Ubuntu20.04下CMake安装后可执行文件找不到libCOOK.so共享库如何解决?
问题成因
- 构建阶段可正常找到共享库,是因为CMake默认会给构建目录下生成的可执行文件写入指向构建树中共享库位置的RPATH值,动态链接器可以通过这个路径找到依赖,所以ldd检查正常。
- 执行安装命令时,CMake默认会清除安装后可执行文件的RPATH配置。你安装后的共享库存放在独立的
lib目录,既不在系统默认的共享库搜索路径(如/usr/lib、/lib)中,也没有被加入系统动态链接器配置,动态链接器加载可执行文件时无法遍历到lib目录下的libCOOK.so,就会抛出找不到共享对象的错误。 - 注意:Linux下动态链接器不会像Windows那样自动搜索可执行文件同级目录、相邻目录的库文件,必须通过RPATH、系统配置、环境变量三种方式之一告知库的位置。
CMake配置解决方法
推荐使用相对RPATH方案,不依赖绝对路径,安装目录任意移动都不会失效,适配你当前bin/lib平行的目录结构,配置步骤如下:
- 在项目顶层CMakeLists.txt的最开头(定义任何目标之前)加入全局RPATH配置:
# 保留构建目录的RPATH配置,保证构建阶段运行正常 set(CMAKE_SKIP_BUILD_RPATH FALSE) # 构建阶段不使用安装阶段的RPATH,避免构建时路径冲突 set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) # 配置安装后目标的RPATH:$ORIGIN是Linux动态链接器内置变量,代表当前可执行文件所在路径 # $ORIGIN/../lib 即从bin目录向上寻址到安装根目录,再进入同级lib目录找依赖,完全匹配你的目录结构 set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") # 禁止将构建时的链接路径自动追加到安装产物的RPATH中,避免本地构建路径污染安装产物 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
- 确认安装规则的目标路径和RPATH配置匹配,安装规则示例如下:
# 定义共享库目标,目标名需和你代码中保持一致 add_library(COOK SHARED src/libraries/COOK.c) # 定义可执行文件目标 add_executable(my_executable src/exes/my_exe.f90) # 链接共享库到可执行文件 target_link_libraries(my_executable PRIVATE COOK) # 安装规则:共享库装到lib目录,可执行文件装到bin目录 install(TARGETS COOK LIBRARY DESTINATION lib) install(TARGETS my_executable RUNTIME DESTINATION bin)
- 重新构建、安装后验证:进入安装路径的
bin目录,执行ldd ./my_executable.exe,如果libCOOK.so项指向安装目录下../lib/libCOOK.so的对应路径,说明配置生效,直接运行可执行文件就不会再报找不到库的错误。
注意:不要把
CMAKE_INSTALL_RPATH设置为构建目录或本机固定绝对路径,否则安装目录拷贝到其他位置、其他设备时会再次出现找不到库的问题。
内容的提问来源于stack exchange,提问作者bencomo
相关产品推荐
相关产品推荐

