【发布时间】:2020-07-14 14:52:46
【问题描述】:
我正在尝试构建一个依赖于外部库 libext 的 C 库 libmy。 libmy 和 libext 都使用 CMake。此外,libext 实际上产生了两个共享对象,libext1.so 和 libext2.so,这两个共享对象都是 libmy 所需要的。
首先,我在${CMAKE_BINARY_DIR}/ext 下安装带有自定义CMake 模块的libext。这个过程是成功的,我最终得到了以下树:
${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)
而构建mytest 的CMakeLists.txt 文件包含:
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)
免责声明:我对场景进行了简化,因为库相当大,并且构建过程包含其他几个组件。但希望这已经足够了。
【问题讨论】:
标签: cmake