labapart / gattlib

Library to access GATT information from BLE (Bluetooth Low Energy) devices
http://labapart.com/
461 stars 161 forks source link

Link error with python3.8 #146

Closed dequis closed 4 years ago

dequis commented 4 years ago
[ 72%] Linking C executable ble_scan
/usr/bin/ld: ../../dbus/libgattlib.so: undefined reference to `PyGILState_Release'
/usr/bin/ld: ../../dbus/libgattlib.so: undefined reference to `PyEval_CallObjectWithKeywords'
/usr/bin/ld: ../../dbus/libgattlib.so: undefined reference to `PyGILState_Ensure'
/usr/bin/ld: ../../dbus/libgattlib.so: undefined reference to `Py_BuildValue'
collect2: error: ld returned 1 exit status
make[2]: *** [examples/ble_scan/CMakeFiles/ble_scan.dir/build.make:85: examples/ble_scan/ble_scan] Error 1
make[1]: *** [CMakeFiles/Makefile2:324: examples/ble_scan/CMakeFiles/ble_scan.dir/all] Error 2
make: *** [Makefile:152: all] Error 2
make -s  5.95s user 0.87s system 99% cpu 6.856 total

Possibly related: https://github.com/thp/pyotherside/issues/102

Apparently python3.8 dropped -lpython3.7m from Libs in its pkg-config, and I guess using pkg-config for python is not terribly common.

Compare: python3.7 pkg-config:

$ cat /usr/lib/pkgconfig/python3.pc
# See: man pkg-config
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: Python
Description: Python library
Requires:
Version: 3.7
Libs.private: -lpthread -ldl  -lutil
Libs: -L${libdir} -lpython3.7m
Cflags: -I${includedir}/python3.7m

And python3.8 pkg-config:

$ cat /usr/lib/pkgconfig/python3.pc
# See: man pkg-config
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: Python
Description: Build a C extension for Python
Requires:
Version: 3.8
Libs.private: -lcrypt -lpthread -ldl  -lutil -lm
Libs:
Cflags: -I${includedir}/python3.8

Nothing in Libs. Using python-config there's a similar lack of -lpython unless you pass --embed

$ python-config --libs
 -lcrypt -lpthread -ldl  -lutil -lm -lm

$ python-config --libs --embed
-lpython3.8 -lcrypt -lpthread -ldl  -lutil -lm -lm

I'm not very familiar with the cmake or the "right" way to do this, i guess something like FindPython3 if using cmake 3.12 otherwise FindPythonLibs? Assuming those handle python3.8's new stuff, which i'm not sure.

A shitty workaround patch that only works for python3.8:

diff --git a/dbus/CMakeLists.txt b/dbus/CMakeLists.txt
index f5096ce..9bae817 100644
--- a/dbus/CMakeLists.txt
+++ b/dbus/CMakeLists.txt
@@ -110,7 +110,7 @@ endif()

 if (PYTHON_FOUND)
    include_directories(${PYTHON_INCLUDE_DIRS})
-   list(APPEND gattlib_LIBS ${PYTHON_LDFLAGS})
+   list(APPEND gattlib_LIBS ${PYTHON_LDFLAGS} -lpython3.8)

    add_definitions(-DWITH_PYTHON)
 endif()
oliviermartin commented 4 years ago

Thanks a lot @dequis for reporting this issue. Effectively find_package (Python COMPONENTS Interpreter Development) does the job.

dequis commented 4 years ago

Thank you!