2009-06-14 3 views
5

У нас есть c-файл с именем dbookpy.c, который предоставит Python, связывающий некоторые C-функции.Создание связывания общего объекта Python с cmake, который зависит от внешних библиотек

Далее мы решили построить правильный .so с CMake, но мне кажется, что мы делаем что-то неправильно в отношении увязки «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

Вы должны связать 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. 

Так это означает, что "dbook", который находится в/USR/местные/Библиотека должна быть импортирована библиотека:

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

Hi rq, см. Ниже ответ. Спасибо –

1

Благодарим за помощь.

Вы правы, что IMPORTED, вероятно, не требуется. Добавление LINK_LIBRARIES (dbookpy dbook) действительно добавляет -ldbook в gcc-исполнение, так что это здорово.

Однако 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

ответ должен добавить LINK_DIRECTORIES перед ADD_LIBRARY :) –

+0

Стоит отметить, что target_link_libraries ожидает имя проекта и имя lib, а не путь к lib (который предположил пример, который я использовал). Другими словами, часть, которая появится рядом с -l, т.е. db (для Berkeley DB), который является libdb и отображается как -ldb. – Asher