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