CMake链接导入共享库时如何让可执行文件仅嵌入库文件名
问题根因
你使用UNKNOWN类型的导入目标时,CMake无法判断目标类型是共享库,也无法读取库的SONAME信息,因此会直接将IMPORTED_LOCATION中配置的路径写入可执行文件的DT_NEEDED字段,导致运行时动态链接器无法通过rpath找到对应库。
解决方案
修改导入目标的配置,明确指定目标为共享库类型,同时显式设置库的SONAME即可,修改后的配置代码如下:
add_library(libstring SHARED IMPORTED) set_target_properties(libstring PROPERTIES IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/external/libstring.so" IMPORTED_SONAME "libstring.so" ) add_executable(my_exe "${CMAKE_CURRENT_BINARY_DIR}/my_exe.cpp") target_link_libraries(my_exe PRIVATE libstring)
修改说明
- 将导入目标的类型从
UNKNOWN改为SHARED,明确告知CMake该导入目标是共享库,按照共享库的链接逻辑处理 - 新增
IMPORTED_SONAME属性,值设置为库的文件名libstring.so,CMake链接时会直接将该值写入可执行文件的DT_NEEDED字段,不会再使用路径 - 由于你已经将库所在目录添加到了rpath中,动态链接器运行时会自动通过SONAME在rpath路径下查找对应的库文件,无需修改其他配置
- 即使导入库路径在构建二进制树之外,只要显式设置了
IMPORTED_SONAME属性,CMake也会优先使用配置的SONAME写入可执行文件,不会嵌入绝对路径。
如果确实需要保留UNKNOWN类型的导入目标,只需要在原有配置基础上新增IMPORTED_SONAME属性也可以达到相同效果。
内容的提问来源于stack exchange,提问作者Sogartar
相关产品推荐
相关产品推荐

