2009-06-14 49 views
5

我们有一个名为dbookpy.c的c文件,它将提供一个Python绑定一些C函数。使用cmake构建Python共享对象绑定,这取决于外部库

下一步,我们决定建立与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 

有没有人有任何想法,为什么这是行不通的?

非常感谢。

埃德

回答

3

你需要对dbook链接dbookpy:

target_link_libraries(dbookpy dbook) 

添加,只是行ADD_LIBRARY(dbookpy dbookpy)之后应该这样做。

我看你是采用进口 - 为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. 

这样就意味着 “dbook”,这是在/ usr/local/lib目录,应该是一个导入库:

add_library(dbook SHARED IMPORTED) 

这真的是你想要的吗?我的意思是,导入的库是在CMake之外构建的,但作为源代码树的一部分。 dbook库似乎已安装或至少预计会安装。我不认为你在这里需要进口 - 这似乎是一个常规的联系问题。但这可能只是创建一个最小范例在这里发布的副作用。

通过它的声音,为了获得链接库和链接目录,我可能会使用find_library(),它会查看合理的默认位置,如/ usr/local/lib,然后将其附加到链接库。

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

无论如何,好像你已经排序了。

+0

嗨rq, 请参阅下面的答案。 谢谢 – 2009-06-15 18:34:11

1

感谢您的帮助。

你说的很可能不需要IMPORTED。添加LINK_LIBRARIES(dbookpy dbook)确实为gcc执行添加了-ldbook,所以这非常棒。

然而cmake的似乎忽略LINK_DIRECTORIES,所以从来没有发现-ldbook:

/usr/bin/gcc -fPIC -shared -o libdbookpy.so.0.1 "CMakeFiles/dbookpy.dir/dbookpy.o" -ldbook 
/usr/bin/ld: cannot find -ldbook 

这里是CMakeList,因为它主张:

PROJECT(dbookpy) 
SET(CMAKE_VERBOSE_MAKEFILE ON) 

OPTION(BUILD_SHARED_LIBS "turn OFF for .a libs" ON) 
ADD_LIBRARY(dbookpy dbookpy) 
SET_TARGET_PROPERTIES(dbookpy PROPERTIES LINKER_LANGUAGE C) 


FIND_PACKAGE(PythonInterp) 
FIND_PACKAGE(PythonLibs) 

INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) 
INCLUDE_DIRECTORIES(/usr/local/include) 
target_link_libraries(dbookpy dbook) 
LINK_DIRECTORIES("/usr/local/lib") 

SET_TARGET_PROPERTIES(dbookpy 
PROPERTIES 
     SOVERSION 0.1 
     VERSION 0.1 
) 

INSTALL(TARGETS dbookpy 
     LIBRARY DESTINATION lib 
) 

任何想法?

+1

答案是在ADD_LIBRARY之前添加LINK_DIRECTORIES :) – 2009-06-15 18:40:13