2009-06-14 10 views
5

Mamy plik c o nazwie dbookpy.c, który zapewni powiązanie Pythona z niektórymi funkcjami C.Budowanie powiązania obiektu udostępnionego w Pythonie z cmake, który zależy od bibliotek zewnętrznych.

Następny zdecydowaliśmy się zbudować właściwą .so z cmake, ale wydaje się, że robią coś złego w odniesieniu do łączenia „libdbook” zewnętrznej biblioteki w wiązaniu:

CMakeLists.txt przedstawia się następująco:

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 
) 

Następnie budujemy:

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 

tej pory tak dobrze. Test w języku 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. Błąd łącznika. Wygląda na to, że nie jest to link do biblioteki 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 

Nie, nie jest. Właściwy link do libdbook wygląda następująco:

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 

Czy ktoś ma jakieś pomysły, dlaczego to nie działa?

Wielkie dzięki.

Edd

Odpowiedz

3

Trzeba połączyć dbookpy przeciwko dbook:

target_link_libraries(dbookpy dbook) 

Dodając, że tuż po linii ADD_LIBRARY(dbookpy dbookpy) powinno wystarczyć.

widzę jesteś korzystając PRZYWOŻONY - pomoc dla IMPORTED_LINK_INTERFACE_LIBRARIES brzmi:

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. 

Więc to znaczy, że "dbook", który znajduje się w katalogu/usr/local/lib, powinny być importowane biblioteka:

add_library(dbook SHARED IMPORTED) 

Czy tego właśnie chcesz? Mam na myśli, że biblioteki importowane to te, które są zbudowane poza CMake, ale są włączone jako część twojego drzewa źródłowego. Biblioteka podręczna wydaje się być zainstalowana lub przynajmniej oczekuje się, że zostanie zainstalowana. Nie sądzę, że potrzebujesz tu importu - wydaje się, że jest to normalny problem z linkami. Ale może to być efekt uboczny tworzenia minimalnego przykładu do publikowania tutaj.

Odgłosami, w celu uporządkowania połączonych bibliotek i katalogów linków, prawdopodobnie użyłbym find_library(), który będzie wyglądał w rozsądnych domyślnych miejscach, takich jak/usr/local/lib, a następnie dołącza to do biblioteki linków.

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

W każdym razie wydaje się, że masz teraz posortowane.

+0

Hi rq, zobacz poniżej odpowiedź. Dzięki –

1

Dzięki za pomoc.

Masz rację, twierdząc, że IMPORTED prawdopodobnie nie jest potrzebny. Dodanie LINK_LIBRARIES (dbookpy dbook) rzeczywiście dodaje -ldbook do wykonywania gcc, więc to świetnie.

cmake jednak wydaje się ignorować LINK_DIRECTORIES, a więc nigdy nie znajdzie -ldbook:

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

Oto CMakeList jak stoi:

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 
) 

pomysłów?

+1

odpowiedzią jest dodanie LINK_DIRECTORIES przed ADD_LIBRARY :) –

+0

Warto zauważyć, że target_link_libraries oczekuje nazwy projektu i nazwy biblioteki, a nie ścieżki do biblioteki (co sugerował przykład, którego użyłem). Innymi słowy, część, która pojawiłaby się obok -l, tj. db (dla Berkeley DB), który jest libdb i wyświetla się jako -ldb. – Asher