We have a c file called dbookpy.c, which will provide a Python binding some C functions.
Next we decided to build a proper .so with cmake, but it seems we are doing something wrong with regards to linking the external library 'libdbook' in the binding:
The CMakeLists.txt is as follows:
PROJECT(dbookpy)
FIND_PACKAGE(PythonInterp)
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES("/usr/local/include")
LINK_DIRECTORIES(/usr/local/lib)
OPTION(BUILD_SHARED_LIBS "turn OFF for .a libs" ON)
ADD_LIBRARY(dbookpy dbookpy)
SET_TARGET_PROPERTIES(dbookpy PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES dbook)
SET_TARGET_PROPERTIES(dbookpy PROPERTIES LINKER_LANGUAGE C)
#SET_TARGET_PROPERTIES(dbookpy PROPERTIES LINK_INTERFACE_LIBRARIES dbook)
#SET_TARGET_PROPERTIES(dbookpy PROPERTIES ENABLE_EXPORTS ON)
#TARGET_LINK_LIBRARIES(dbookpy LINK_INTERFACE_LIBRARIES dbook)
SET_TARGET_PROPERTIES(dbookpy
PROPERTIES
SOVERSION 0.1
VERSION 0.1
)
Then we build:
x31% mkdir build
x31% cd build
x31% cmake ..
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Check size of void*
-- Check size of void* - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Configuring done
-- Generating done
-- Build files have been written to: /home/edd/dbook2/dbookpy/build
x31% make
Scanning dependencies of target dbookpy
[100%] Building C object CMakeFiles/dbookpy.dir/dbookpy.o
Linking C shared library libdbookpy.so
[100%] Built target dbookpy
So far so good. Test in Python:
x31% python
Python 2.5.4 (r254:67916, Apr 24 2009, 15:28:40)
[GCC 3.3.5 (propolice)] on openbsd4
Type "help", "copyright", "credits" or "license" for more information.
>>> import libdbookpy
python:./libdbookpy.so: undefined symbol 'dbook_isbn_13_to_10'
python:./libdbookpy.so: undefined symbol 'dbook_isbn_10_to_13'
python:./libdbookpy.so: undefined symbol 'dbook_sanitize'
python:./libdbookpy.so: undefined symbol 'dbook_check_isbn'
python:./libdbookpy.so: undefined symbol 'dbook_get_isbn_details'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: Cannot load specified object
Hmmm. Linker error. Looks like it is not linking libdbook:
x31% ldd libdbookpy.so
libdbookpy.so:
Start End Type Open Ref GrpRef Name
05ae8000 25aec000 dlib 1 0 0 /home/edd/dbook2/dbookpy/build/libdbookpy.so.0.1
No it is not. A proper linkage to libdbook looks like this:
x31% ldd /usr/local/bin/dbook-test
/usr/local/bin/dbook-test:
Start End Type Open Ref GrpRef Name
1c000000 3c004000 exe 1 0 0 /usr/local/bin/dbook-test
08567000 28571000 rlib 0 2 0 /usr/lib/libm.so.5.0
09ef7000 29efb000 rlib 0 1 0 /usr/local/lib/libdbook.so.0.1
053a0000 253d8000 rlib 0 1 0 /usr/lib/libc.so.50.1
0c2bc000 0c2bc000 rtld 0 1 0 /usr/libexec/ld.so
Does anyone have any ideas why this is not working?
Many thanks.
Edd
You need to link dbookpy against dbook:
target_link_libraries(dbookpy dbook)
Adding that just after the line ADD_LIBRARY(dbookpy dbookpy)
should do it.
I see you are using IMPORTED - the help for IMPORTED_LINK_INTERFACE_LIBRARIES
reads:
Lists libraries whose interface is included when an IMPORTED library target is
linked to another target. The libraries will be included on the link line for
the target. Unlike the LINK_INTERFACE_LIBRARIES property, this property
applies to all imported target types, including STATIC libraries. This
property is ignored for non-imported targets.
So that means that "dbook", which is in /usr/local/lib, should be an imported library:
add_library(dbook SHARED IMPORTED)
Is that really what you wanted? I mean, imported libraries are ones that are built outside CMake but are included as part of your source tree. The dbook library seems to be installed or at least expected to be installed. I don't think you need imports here - it seems to be a regular linkage problem. But this may just be a side effect of creating a minimal example to post here.
By the sounds of it, in order to get the linked libraries and link directories sorted out, I would probably use find_library()
, which will look in sensible default places like /usr/local/lib, and then append that to the link libraries.
find_library(DBOOK_LIBRARY dbook REQUIRED)
target_link_libraries(dbookpy ${DBOOK_LIBRARY})
Anyway, seems like you have it sorted now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With