Я пытаюсь создать C библиотеку libmy
, которая зависит от внешней библиотеки libext
. И libmy
, и libext
используют CMake. Кроме того, libext
фактически создает два общих объекта, libext1.so
и libext2.so
, оба из которых необходимы libmy
.
Сначала я устанавливаю libext
с настраиваемым модулем CMake в разделе ${CMAKE_BINARY_DIR}/ext
. Процесс проходит успешно, и я получаю следующее дерево:
${CMAKE_BINARY_DIR}
└── ext
└── lib
├── libext1.so
└── libext2.so
Чтобы протестировать libmy
, я создаю несколько тестовых примеров для цели mytest
, которые связаны с общими объектами libmy.so
, libext1.so
и libext2.so
.
Процесс сборки всех целей завершается успешно. Но когда я пытаюсь запустить mytest
, я получаю знаменитый не могу открыть файл общих объектов: такого файла или каталога нет, но только для libext1.so
, а libext2.so
правильно найден. Однако что очень любопытно, так это то, что и libext1.so
, и libext2.so
расположены по одному и тому же пути, а libext2.so
действительно успешно связан во время выполнения. Вот что выводит LD_DEBUG=libs mytest
:
10703: find library=libext2.so [0]; searching
10703: search path=/usr/local/lib:/home/user/mylib/build/ext/lib:x86_64: (RUNPATH from file src/test/mytest)
10703: trying file=/usr/local/lib/libext2.so
10703: trying file=/home/user/mylib/build/ext/lib/libext2.so
10703:
10703: find library=libext1.so [0]; searching
10703: search cache=/etc/ld.so.cache
10703: trying file=/usr/local/lib/libext1.so
10703: search path=/lib/x86_64-linux-gnu/tls/haswell/x86_64:[...truncated long search path (/home/user/mylib/build/ext/lib is not here)...]:/usr/lib (system search path)
10703: trying file=/lib/x86_64-linux-gnu/tls/haswell/x86_64/libext1.so
...
10703: trying file=/usr/lib/haswell/libext1.so
10703: trying file=/usr/lib/x86_64/libext1.so
10703: trying file=/usr/lib/libext1.so
10703:
src/test/myest: error while loading shared libraries: libext1.so: cannot open shared object file: No such file or directory
Итак, по какой-то причине для поиска libext1.so
используется системный путь поиска (который не включает путь к внешней библиотеке), а для libext2.so
используется RUNPATH (у которого есть правильный путь).
Модуль CMake, в котором я создаю внешнюю библиотеку, в основном делает следующее:
include(ExternalProject)
set(EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/ext)
ExternalProject_Add(extproject
GIT_REPOSITORY https://github.com/ext/ext.git
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION})
include_directories(${EXTERNAL_INSTALL_LOCATION}/include)
link_directories(${EXTERNAL_INSTALL_LOCATION}/lib)
set(EXT_INCLUDE_DIR ${EXTERNAL_INSTALL_LOCATION}/include)
set(EXT1_LIBRARY ext1)
set(EXT2_LIBRARY ext2)
И CMakeLists.txt файл, в котором создается mytest
, содержит:
add_executable(mytest mytest.cpp)
target_include_directories (mytest
PUBLIC
${EXT_INCLUDE_DIR})
target_link_libraries(mytest
my
${EXT1_LIBRARY}
${EXT2_LIBRARY})
add_test(NAME mytest COMMAND mytest)
Заявление об ограничении ответственности : Я дал упрощение сценария, так как библиотека довольно большая, а процесс сборки содержит несколько других компонентов. Но, надеюсь, этого достаточно.