CMake设置导入共享库的安装相对路径问题排查
我需要链接一个导入的共享库,相关CMake配置如下:
add_library(drivers SHARED IMPORTED) set_target_properties( drivers PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/libdrivers.so )
该库用于pybind11绑定,我尝试设置RPATH,让libdrivers.so能在绑定库的同目录被找到,相关配置:
pybind11_add_module(pybind11_bindings MODULE srcpy/bindings.cpp) set_target_properties(pybind11_bindings PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/myproject OUTPUT_NAME "bindings" SKIP_BUILD_RPATH FALSE BUILD_WITH_INSTALL_RPATH TRUE ) target_link_libraries(pybind11_bindings PRIVATE drivers ) set_target_properties(pybind11_bindings PROPERTIES INSTALL_RPATH "\$ORIGIN") set_target_properties(pybind11_bindings PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
安装配置为:
install(IMPORTED_RUNTIME_ARTIFACTS drivers LIBRARY DESTINATION ${PMYROJECT_INSTALL_PREFIX} COMPONENT bindings ) install( TARGETS pybind11_bindings COMPONENT bindings LIBRARY DESTINATION ${MYPROJECT_INSTALL_PREFIX} ARCHIVE DESTINATION ${MYPROJECT_INSTALL_PREFIX} RUNTIME DESTINATION ${MYPROJECT_INSTALL_PREFIX} )
项目基于setuptools,使用cmake-build-extension通过pip安装。执行pip install .后,site-packages/myproject目录下存在bindings.cpython-38-x86_64-linux-gnu.so和libdrivers.so,但执行ldd bindings.cpython-38-x86_64-linux-gnu.so显示../../lib/libdrivers.so => not found,且objdump -x bindings.cpython-310-x86_64-linux-gnu.so | grep RPATH无输出,动态段仅显示NEEDED ../../lib/libdrivers.so,RPATH未按预期设置,请问哪里配置出错了?
1. 导入库的路径继承问题
当前导入的libdrivers.so被链接时,绑定库直接继承了它的相对路径../../lib/libdrivers.so,这是因为CMake默认会使用导入库的完整路径(或其SONAME中的路径)。要让绑定库仅查找库文件名而非带路径的名称,需给导入库添加IMPORTED_NO_SONAME属性,强制忽略原库的SONAME信息:
add_library(drivers SHARED IMPORTED) set_target_properties( drivers PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/libdrivers.so IMPORTED_NO_SONAME TRUE # 新增该属性 )
2. RPATH配置冲突
你同时启用了BUILD_WITH_INSTALL_RPATH TRUE和INSTALL_RPATH_USE_LINK_PATH TRUE,这两个属性可能相互干扰:
BUILD_WITH_INSTALL_RPATH会让构建阶段直接使用安装时的RPATH设置INSTALL_RPATH_USE_LINK_PATH会把链接时的系统路径追加到RPATH中,可能覆盖你设置的$ORIGIN
建议简化RPATH配置,分开构建和安装阶段的RPATH设置:
set_target_properties(pybind11_bindings PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/myproject OUTPUT_NAME "bindings" SKIP_BUILD_RPATH FALSE BUILD_RPATH "\$ORIGIN" # 构建阶段使用同目录查找 INSTALL_RPATH "\$ORIGIN" # 安装阶段保持同目录查找 INSTALL_RPATH_USE_LINK_PATH FALSE # 禁用自动追加链接路径 )
3. 变量拼写错误
安装配置中的${PMYROJECT_INSTALL_PREFIX}存在拼写错误(多了一个P),应修正为${MYPROJECT_INSTALL_PREFIX},否则会导致libdrivers.so安装路径错误:
install(IMPORTED_RUNTIME_ARTIFACTS drivers LIBRARY DESTINATION ${MYPROJECT_INSTALL_PREFIX} COMPONENT bindings )
4. cmake-build-extension的额外处理
由于使用cmake-build-extension通过pip安装,需确保setup.py中正确配置了cmake_install选项,且没有额外修改RPATH的逻辑。同时,CMake的CMAKE_INSTALL_PREFIX会被pip自动设置为site-packages下的目标目录,无需手动指定(如果已指定需确保路径正确)。
内容的提问来源于stack exchange,提问作者Vince

