如何让install(RUNTIME_DEPENDENCIES)无需指定DIRECTORIES找到共享库?
CMake install(RUNTIME_DEPENDENCIES) 依赖搜索问题解答
1. install(RUNTIME_DEPENDENCIES) 默认搜索路径
CMake的install(RUNTIME_DEPENDENCIES)默认会从以下路径查找依赖:
- 操作系统的标准系统库路径(如Linux的
/usr/lib、/lib,macOS的/usr/lib等) - 目标可执行文件自身的
RPATH和RUNPATH配置 - 链接阶段记录的依赖库路径(但静态库不会传递这类路径信息,这是你遇到问题的核心原因)
- 安装阶段生效的环境变量(Linux下的
LD_LIBRARY_PATH、macOS下的DYLD_LIBRARY_PATH) - CMake内置变量
CMAKE_SYSTEM_LIBRARY_PATH指定的路径
2. 无需显式指定DIRECTORIES的配置方案
因为静态库不会存储依赖库的路径信息,所以需要通过目标的INTERFACE属性把依赖路径传递给最终的可执行文件,让CMake能自动追踪到这些依赖。以下是两种可行方案:
方案一:用IMPORTED目标管理外部依赖
将外部依赖dep1.so和dep2.so定义为CMake的IMPORTED目标,通过INTERFACE属性传递路径:
# A/B/CMakeLists.txt # 定义dep1为导入的共享库 add_library(dep1 SHARED IMPORTED) set_target_properties(dep1 PROPERTIES IMPORTED_LOCATION "/path/to/dep1.so" IMPORTED_NO_SONAME TRUE # 如果dep1.so没有设置SONAME则添加此选项 ) add_library(B STATIC b.cpp) target_link_libraries(B PRIVATE dep1) # 将dep1的路径传递给所有依赖B的目标 target_link_directories(B INTERFACE "/path/to/dep1")
# A/C/CMakeLists.txt add_library(dep2 SHARED IMPORTED) set_target_properties(dep2 PROPERTIES IMPORTED_LOCATION "/path/to/dep2.so" IMPORTED_NO_SONAME TRUE ) add_library(C STATIC c.cpp) target_link_libraries(C PRIVATE dep2) target_link_directories(C INTERFACE "/path/to/dep2")
当MyExecutable链接B和C时,会自动继承这些INTERFACE链接目录,install(RUNTIME_DEPENDENCIES)就能通过这些目录找到对应的依赖库。
方案二:通过INTERFACE属性传递安装路径
直接在静态库的INTERFACE属性中设置依赖路径,让可执行文件继承:
# A/B/CMakeLists.txt add_library(B STATIC b.cpp) target_link_libraries(B PRIVATE /path/to/dep1.so) # 传递运行时路径给依赖B的目标 set_target_properties(B PROPERTIES INTERFACE_INSTALL_RPATH "/path/to/dep1" ) # 同时确保构建阶段的路径可用(可选) target_link_options(B INTERFACE "-Wl,-rpath,/path/to/dep1")
# A/C/CMakeLists.txt add_library(C STATIC c.cpp) target_link_libraries(C PRIVATE /path/to/dep2.so) set_target_properties(C PROPERTIES INTERFACE_INSTALL_RPATH "/path/to/dep2" ) target_link_options(C INTERFACE "-Wl,-rpath,/path/to/dep2")
这种方式会让MyExecutable继承B和C的INTERFACE_INSTALL_RPATH,install(RUNTIME_DEPENDENCIES)会从这些路径中搜索依赖库。
内容的提问来源于stack exchange,提问作者Ershat
相关产品推荐
相关产品推荐

