【问题标题】:CMAKE RPATH not working - could not find shared object fileCMAKE RPATH 不工作 - 找不到共享对象文件
【发布时间】:2015-08-04 13:37:02
【问题描述】:

每次我运行我的程序时,我都试图摆脱设置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 是被链接的文件。我还缺少什么?

【问题讨论】:

标签: cmake makefile


【解决方案1】:

这是因为您从同一个 cmake 项目构建 heartrun

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++ 行的末尾 Linking CXX executable run 你应该看到像 -Wl,-rpath,/home/person/target/usr/local/lib

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

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

PS:你确定是 libheart.so 没有找到吗?

【讨论】:

  • 我正在阅读文档并尝试将其设置为 ${CMAKE_INSTALL_PERFIX}/lib" 并且不起作用。如果${CMAKE_INSTALL_PERFIX} 指向 CMakeLists.txt 所在的位置,那么我确定我有正确的文件路径。
  • ${CMAKE_INSTALL_PREFIX} 当你有一个像`INSTALL (TARGETS run DESTINATION bin)这样的CMake命令时使用。您是否有这样的命令,或者您是否尝试从构建树运行您的程序?
  • 我有一个类似install(TARGETS run DESTINATION bin) 的命令,然后是set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib"。它仍然说找不到共享库。我所有的可执行文件都安装在 ../bin 文件夹中,我的目标文件在 ../lib 中。设置变量后,我还将对象安装到我的 lib 文件夹中,如下所示:install(TARGETS heart DESTINATION lib).
  • 请参阅this answer 了解解决方案。 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 之前 add_executable()
【解决方案2】:

在您的 CMake 文件中,在定义目标之前设置 RPATH。 CMAKE_INSTALL_RPATH必须在调用add_executable()之前定义,否则无效。

【讨论】:

    【解决方案3】:

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

    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) set(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")

    【讨论】:

    • 小心,在某些发行版上可能需要“$ORIGIN/../lib64”。甚至 $ORIGIN/../${CMAKE_INSTALL_LIBDIR} 使用 gnuInstallDirs 时
    猜你喜欢
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 2015-10-03
    • 2018-04-08
    • 2019-04-26
    相关资源
    最近更新 更多