7

我们有一个名为 dbookpy.c 的 ac 文件,它将提供一个 Python 绑定一些 C 函数。

接下来我们决定用 cmake 构建一个合适的 .so,但似乎我们在绑定中链接外部库“libdbook”方面做错了:

CMakeLists.txt 如下:

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
)

然后我们构建:

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

到现在为止还挺好。在 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

嗯。链接器错误。看起来它没有链接 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

不它不是。与 libdbook 的正确链接如下所示:

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

有谁知道为什么这不起作用?

非常感谢。

埃德

4

1 回答 1

4

您需要将 dbookpy 与 dbook 链接起来:

target_link_libraries(dbookpy dbook)

在该行之后添加它ADD_LIBRARY(dbookpy dbookpy)应该这样做。

我看到您正在使用 IMPORTED -IMPORTED_LINK_INTERFACE_LIBRARIES阅读帮助:

 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.

这意味着 /usr/local/lib 中的“dbook”应该是一个导入的库:

 add_library(dbook SHARED IMPORTED)

这真的是你想要的吗?我的意思是,导入的库是在 CMake 之外构建但包含在源代码树中的库。dbook 库似乎已安装或至少预计已安装。我认为您在这里不需要导入 - 这似乎是一个常规的链接问题。但这可能只是创建一个在此处发布的最小示例的副作用。

听上去,为了整理链接库和链接目录,我可能会使用find_library(),它会在 /usr/local/lib 等合理的默认位置查找,然后将其附加到链接库中。

find_library(DBOOK_LIBRARY dbook REQUIRED)
target_link_libraries(dbookpy ${DBOOK_LIBRARY})    

无论如何,看起来你现在已经整理好了。

于 2009-06-15T06:44:20.667 回答