CMAKE RPATH无法正常工作 - 找不到共享对象文件

时间:2015-05-22 13:39:28

标签: cmake makefile

我每次运行程序时都试图摆脱设置LD_LIBRARY_PATH。在库中添加并将我的可执行文件定位到库后,当我运行它时告诉我它无法打开共享库,没有这样的文件或目录。

在我的CMakeLists.txt中,我有:

add_library(heart SHARED ${HEART_FILES})
add_executable(run ${RUN_FILES})
target_link_libraries(run heart)
set(CMAKE_SKIP_BUILD_PATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "~/person/target/usr/local/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

我设置了一个绝对链接到我的库文件夹,以测试这是否会创建一个到我的库的rpath,似乎没有。我检查并确保共享库确实在lib中。 libheart.so是要链接的文件。我还缺少什么?

3 个答案:

答案 0 :(得分:10)

这是因为你从同一个cmake项目中构建 heart run

  

CMAKE_INSTALL_RPATH_USE_LINK_PATH是一个有趣且非常有用的选项。使用RPATH构建目标时,CMake通过使用此目标链接的所有库的目录来确定RPATH。这些库中的一些可以位于相同的构建树中,例如, libbar.so,这些目录也被添加到RPATH中。   如果启用此选项,则除了构建树中的那些目录之外的所有目录都将自动添加到安装RPATH中。然后,RPATH中可能仍然缺少的唯一目录是安装来自同一项目(即libbar.so)的库的目录。如果库的安装目录不是系统缺省库目录之一,则必须通过相应地设置CMAKE_INSTALL_RPATH将此目录自己添加到安装RPATH

你可以试试这个:

SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

此处有更多文档cmake rpath handling

编辑:

只有这应该有效:

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

add_library(heart SHARED ${HEART_FILES})
add_executable(run ${RUN_FILES})
target_link_libraries(run heart)

install(
  TARGETS heart run
  RUNTIME DESTINATION bin
  LIBRARY DESTINATION lib
)

清理构建目录,然后:

cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/home/person/target/usr/local ..
make install

在g ++行链接CXX可执行文件的末尾,您应该看到 -Wl,-rpath,/ home / person / target / usr / local / lib

如果您想要一个完全可重定位的包:

set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")

PS:你是不是找不到 libheart.so

答案 1 :(得分:1)

在CMake文件中,在定义目标之前设置RPATH。 <{1}}必须在调用CMAKE_INSTALL_RPATH之前定义,否则无效。

答案 2 :(得分:1)

我有与原始帖子类似的问题。我创建了链接到外部共享库的可执行文件。这种方法可以在build目录中很好地编译和执行。但是,安装到单独目录的可执行文件在运行时找不到共享库:

error while loading shared libraries: libxxxx.so.1: cannot open shared object file: No such file or directory

要解决,我

1)升级到CMake 3.17

2)使用了克雷格·斯科特(Craig Scott)的推荐: 设置(CMAKE_INSTALL_RPATH $ ORIGIN) 如他的talk

中所述

3)直接设置(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)以解决Kitware documention

中第二个常见问题中的错误

4)将所有这些内容放在之前,按照本文中所述添加目标

5)使用“ $ ORIGIN /../ lib”语法代替了@ explo91提到的Craig Scott提到的$ ORIGIN

总而言之,令我惊讶的是,从上面定义目标定义之前只需要“ $ ORIGIN /../ lib”(我测试了其他不能解决cannot open shared object file运行时问题的组合)。

无论如何,我最终采用的解决方案可能是更好的,细粒度的CMake风格,或者至少对其他人的RPATH旅程有帮助:

set_target_properties(target_defined_above PROPERTIES INSTALL_RPATH "$ORIGIN/../lib")