2009-06-14 16 views
5

Tenemos un archivo c llamado dbookpy.c, que proporcionará un Python vinculando algunas funciones de C.Construir un enlace de objeto compartido de Python con cmake, que depende de librerías externas

A continuación se decidió construir un .so adecuada con cmake, pero parece que estamos haciendo algo mal en lo que respecta a la vinculación 'libdbook' la biblioteca externa en la unión:

El CMakeLists.txt es el siguiente:

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 
) 

Entonces construimos:

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 

Hasta aquí todo bien. Prueba en 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. Error del enlazador Parece que no está enlazando 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, no lo es. Un enlace adecuado a libdbook se ve así:

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 

¿Alguien tiene alguna idea de por qué esto no está funcionando?

Muchas gracias.

Edd

Respuesta

3

es necesario enlazar dbookpy contra DBOOK:

target_link_libraries(dbookpy dbook) 

Agregando que después de la línea ADD_LIBRARY(dbookpy dbookpy) debe hacerlo.

veo que está utilizando importados - la ayuda para IMPORTED_LINK_INTERFACE_LIBRARIES lee:

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. 

Por lo que significa que "DBOOK", que se encuentra en// local/lib usr, debe ser una biblioteca de importación:

add_library(dbook SHARED IMPORTED) 

¿Eso es realmente lo que quería? Quiero decir, las bibliotecas importadas son las que se construyen fuera de CMake, pero se incluyen como parte de su árbol fuente. La biblioteca dbook parece estar instalada o, al menos, se espera que esté instalada. No creo que necesite importar aquí, parece ser un problema de vinculación regular. Pero esto puede ser solo un efecto secundario de crear un ejemplo mínimo para publicar aquí.

Por su sonido, para ordenar las bibliotecas y los directorios de enlaces enlazados, probablemente usaría find_library(), que buscará en lugares predeterminados razonables como/usr/local/lib, y luego anexarlos al bibliotecas de enlaces.

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

De todos modos, parece que lo tienes ordenado ahora.

+0

Hola rq, vea la respuesta a continuación. Gracias, –

1

Gracias por su ayuda.

Tiene razón al decir que IMPORTED probablemente no sea necesario. Agregar LINK_LIBRARIES (dbookpy dbook) de hecho agrega -ldbook a la ejecución de gcc, así que eso es genial.

Sin embargo cmake parece ignorar LINK_DIRECTORIES, y así nunca encuentra -ldbook:

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

Aquí es el CMakeList tal y como está:

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 
) 

¿Alguna idea?

+1

la respuesta es agregar LINK_DIRECTORIES antes ADD_LIBRARY :) –

+0

Vale la pena señalar que target_link_libraries espera el nombre del proyecto y el nombre de la lib, no la ruta a la lib (que un ejemplo que estaba usando había sugerido). En otras palabras, la parte que se mostraría junto a -l, es decir. db (para Berkeley DB) que es libdb y aparece como -ldb. – Asher

Cuestiones relacionadas