Building a Python shared object binding with cmake, which depends upon external libraries

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


Asked by: Ryan799 | Posted: 06-12-2021






Answer 1

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.

Answered by: Catherine228 | Posted: 07-01-2022



Similar questions

python - Building OpenCV libraries from source files

I have installed Python 2.7, but when I try to generate the OpenCV 2.3.1 project Makefiles using CMake 2.8, I get the following message. I am running Windows 7 x86 and using Visual Studio 10. Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE) Could NOT find PythonLibs (missing: PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS) I have followed the guide ...


python - ubuntu libraries not found error when building

I have prepared a setup.py file which requires the opencv libraries contrib,core and highgui. But when I build the setup.py I get an error saying /usr/bin/ld:cannot find -lcontrib /usr/bin/ld:cannot find -lcore /usr/bin/ld:cannot find -lhighgui I added an entry, "include /usr/local/lib" to the ld.so.conf file and ran the command ldconfig from the terminal. Still getting the same error. ...


web crawler - What are the best prebuilt libraries for doing Web Crawling in Python

This question already has answers here:


How to find all built in libraries in Python

I've recently started with Python, and am enjoying the "batteries included" design. I'e already found out I can import time, math, re, urllib, but don't know how to know that something is builtin rather than writing it from scratch. What's included, and where can I get other good quality libraries from?


OCSP libraries for python / java / c?

Going back to my previous question on OCSP, does anybody know of "reliable" OCSP libraries for Python, Java and C? I need "client" OCSP functionality, as I'll be checking the status of Certs against an OCSP responder, so responder functionality is not that important. Thanks


how do i use python libraries in C++?

I want to use the nltk libraries in c++. Is there a glue language/mechanism I can use to do this? Reason: I havent done any serious programming in c++ for a while and want to revise NLP concepts at the same time. Thanks


How can I use Perl libraries from Python?

I have written a bunch of Perl libraries (actually Perl classes) and I want to use some of them in my Python application. Is there a natural way to do this without using SWIG or writing Perl API for Python. I am asking for a similar way of PHP's Perl interface. If there is no such kind of work for Perl in Python. What is the easiest way to use Perl cl...


Python vs. C# Twitter API libraries

Closed. This question does not meet Stack Overflow guid...


d - Calling gdc/dmd shared libraries from Python using ctypes

I've been playing around with the rather excellent ctypes library in Python recently. What i was wondering is, is it possible to create shared D libraries and call them in the same way. I'm assuming i would compile the .so files using the -fPIC with dmd or gdc and call them the same way using the ctypes library. Has anyone tried this ? ...


plot - Python plotting libraries

Closed. This question does not meet Stack Overflow guid...


HTML Agility Pack or HTML Screen Scraping libraries for Java, Ruby, Python?

I found the HTML Agility Pack useful and easy to use for screen scraping web sites. What's the equivalent library for HTML screen scraping in Java, Ruby, Python?


shared libraries - Can two versions of the same library coexist in the same Python install?

The C libraries have a nice form of late binding, where the exact version of the library that was used during linking is recorded, and thus an executable can find the correct file, even when several versions of the same library are installed. Can the same be done in Python? To be more specific, I work on a Python project that uses some 3rd-party libraries, such as paramiko. Paramiko is now version 1.7.4, bu...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top