我正在建立一个与一些测试和示例程序捆绑在一起的库。该项目能够兑现cmake属性BUILD_SHARED_LIBS,.so如果打开,则构建一个,.a如果关闭,则构建一个文件。该库依赖于其他一些动态库,这些动态库应该使用环境变量来找到LIBLOC(它们的约定,不是我的)。
构建动态版本的库时,可以设置安装rpath以便正确找到库。例如:
add_library(lib ${SRC})
set_target_properties(lib INSTALL_RPATH $LIBLOC)
install(TARGETS lib LIBRARY DESTINATION lib)
Run Code Online (Sandbox Code Playgroud)
然后在每个测试/示例程序的CMakeLists.txt中:
add_executable(test ${SRC})
target_link_libraries(test lib)
set_target_properties(test INSTALL_RPATH $ORIGIN/../lib)
install(TARGETS test RUNTIME bin)
Run Code Online (Sandbox Code Playgroud)
当BUILD_SHARED_LIBS是时,测试程序是幸福的:
$ lddtree bin/test
test => bin/test (interpreter => /lib64/ld-linux-x86-64.so.2)
liblib.so => /path/to/install/liblib.so
libdep.so => /path/to/dependency/libdep.so
Run Code Online (Sandbox Code Playgroud)
我们可以找到一切,因为在测试中rpath的是$ORIGIN/../lib,它的发现liblib.so,然后将rpath的liblib.so就是$LIBLOC,这是在我的环境设置/path/to/dependency。
我本来希望在安装静态库时,cmake INSTALL_RPATH将从我的库中读取该属性并将其放入测试程序中,以便测试中的rpath为$ORIGIN/../lib;$LIBLOC。而是$LIBLOC不会以任何rpath结尾。
我目前的解决方案是不满意:我调节我INSTALL_RPATH对BUILD_SHARED_LIBS每个示例或测试程序,如
if (BUILD_SHARED_LIBS)
set_target_properties(test INSTALL_RPATH "$ORIGIN/../lib")
else ()
set_target_properties(test INSTALL_RPATH "$LIBLOC")
endif ()
Run Code Online (Sandbox Code Playgroud)
现在,我有几个目标,所有这些目标都必须了解其依赖性的依赖性。再加上一堆臭的if语句。!
在cmake中,有一种更好的方法将安装rpath“向上”传递给静态编译我的库时生成的第一个ELF文件吗?
该变量可以在外部CMAKE_INSTALL_RPATH设置,并将应用于所有明确定义的目标(即可执行文件和共享库)。RPATH
对于您编写或供应商的库,您应该将它们安装到一致的结构中,以便CMAKE_INSTALL_RPATH可以在所有目标上设置$LIBLOC或$ORIGIN/../lib统一设置。对于真正的依赖项,期望用户在系统范围内安装它们、设置LD_LIBRARY_PATH或使用find_dependencyCMake 包配置中的宏来查找正确的库是合理的。
如果将以下代码片段放置在创建任何目标之前,可能会对您有所帮助:
if (NOT DEFINED CMAKE_INSTALL_RPATH)
# or perhaps it's meant to be $env{LIBLOC}?
set(CMAKE_INSTALL_RPATH "$<IF:$<BOOL:${BUILD_SHARED_LIBS}>,$ORIGIN/../lib,$LIBLOC>")
endif ()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
380 次 |
| 最近记录: |