CMAKE RPATH 不起作用 - 找不到共享对象文件

问题描述 投票:0回答:4

每次运行程序时,我都试图摆脱设置

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
4个回答
22
投票

这是因为您从同一个 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处理

编辑:

只有这个才可以:

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吗?


6
投票

在 CMake 文件中,在定义目标之前设置 RPATH。

CMAKE_INSTALL_RPATH
必须在调用
add_executable()
之前定义,否则无效。


4
投票

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

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) 正如他的演讲

中所解释的

3) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 正如 Kitware 文档

中第二个常见问题中直接提到的那样解决此错误

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


0
投票

简单的解决方案

set(RPATH "/lib/custom")
set_target_properties(${PROJECT_NAME}
        PROPERTIES
        LINK_FLAGS "-Wl,-rpath,${RPATH}"
)
© www.soinside.com 2019 - 2024. All rights reserved.