Linux下CMake链接外部共享库运行报错的原因及解决方法
Linux下CMake链接外部共享库后运行时报错的原因与解决方法
报错信息
./test/calculator_test: error while loading shared libraries: ../../../third_party/add/lib/add.so: cannot open shared object file: No such file or directory
项目目录结构
├── CMakeLists.txt ├── build ├── src ├── test │ ├── CMakeLists.txt │ └── calculator │ ├── CMakeLists.txt │ └── calculator_test.cpp └── third_party ├── add │ ├── include │ │ └── add.h │ └── lib │ └── add.so └── googletest ...
关联的CMake代码(test/calculator/CMakeLists.txt)
add_library(lib-add SHARED IMPORTED) set_target_properties(lib-add PROPERTIES IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/third_party/add/lib/add.so" INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/third_party/add/include" ) add_executable(calculator_test calculator_test.cpp) target_link_libraries(calculator_test PRIVATE lib-add lib-sub) set_target_properties(calculator_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test" COMMAND calculator_test )
报错原因
编译构建阶段CMake能通过IMPORTED_LOCATION找到共享库完成链接,但运行时Linux动态链接器(ld.so)无法定位到add.so的位置:
- 动态链接器默认仅从系统标准库路径(如
/usr/lib)、LD_LIBRARY_PATH环境变量指定的路径中查找共享库 - 当前可执行文件生成在
build/test目录,运行时它尝试使用相对路径../../../third_party/add/lib/add.so查找库,但该路径依赖于当前工作目录,且未被动态链接器识别为可靠查找路径 - 未通过CMake设置可执行文件的
RPATH属性,导致可执行文件无法记住共享库的固定位置
解决方法
方法一:CMake层面设置RPATH(推荐,永久解决)
修改test/calculator/CMakeLists.txt中calculator_test的目标属性,添加RPATH配置,让可执行文件在运行时自动定位到共享库目录:
set_target_properties(calculator_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test" # 让可执行文件继承链接时的库路径,自动设置RPATH INSTALL_RPATH_USE_LINK_PATH TRUE # 或者直接显式指定RPATH为共享库所在的绝对路径 # RPATH "${PROJECT_SOURCE_DIR}/third_party/add/lib" )
INSTALL_RPATH_USE_LINK_PATH TRUE会让CMake自动将链接时用到的库路径添加到可执行文件的RPATH中,无需手动指定路径,兼容性更好。
方法二:临时设置LD_LIBRARY_PATH环境变量
如果只是临时测试,可在运行前将共享库所在目录添加到环境变量:
# 进入build目录后执行 export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PWD}/../third_party/add/lib" ./test/calculator_test
注意:该方法仅当前终端会话有效,每次运行都需要重新设置。
方法三:将共享库复制到系统库目录(不推荐)
将add.so复制到系统标准库目录(如/usr/local/lib),然后更新动态链接器缓存:
sudo cp ../third_party/add/lib/add.so /usr/local/lib sudo ldconfig
此方法会污染系统环境,不建议用于项目依赖的第三方库,仅适用于全局通用的库。
内容的提问来源于stack exchange,提问作者Roseveknif
相关产品推荐
相关产品推荐

