问题描述
我有一个关于如何在依赖于某些外部库时使用 cmake 安装构建的可执行程序的问题.假设我的可执行文件是 abc
,它依赖于两个外部库:lib1.so
和 lib2.so
.代码结构如下:
-........|----bin (lib1.so lib2.so)|----include(lib1.h lib2.h)|----src(main.cpp)
当使用以下cmake命令安装可执行程序时:
安装(目标 ${Exe_Name}运行时目标 bin 路径图书馆目的地到垃圾箱的路径)
我希望可执行程序与lib1.so
和lib2.so
位于同一目录中.但是,当我在安装文件夹中执行构建的程序时,遇到了如下错误:
加载共享库时出错:lib1 无法打开共享对象文件 No such file or directory
如果我使用 ldd 检查可执行文件,我发现 lib1.so
和 lib2.so not found
.在寻找可能的解决方案后,我发现如果我以这种方式调用可执行文件,那么它就起作用了:
LD_LIBRARY_PATH=././my_program_run
那么我的问题是如何让我的可执行程序在安装时使用 cmake 知道共享库的位置?谢谢.
最好通过最终可执行文件的 RPATH 解决这个问题.RPATH 是可执行文件本身的硬编码搜索路径,并允许使用字符串 $ORIGIN
,它会在运行时扩展到可执行文件的位置.请参阅此参考:http://man7.org/linux/man-pages/man8/ld.so.8.html
CMake
在安装时剥离二进制文件的 rpath,以避免二进制文件拾取散落在开发树周围的库.但正是出于这个原因,它还提供了一种简单的方法来修改安装 rpath.这是简短的回答:
IF(UNIX)SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN/../bin:$ORIGIN")万一()
此特定示例附加到现有的 rpath,并将 .
和 ../bin
添加到搜索路径,所有这些都相对于二进制文件的位置.>
一些开发人员声称调整二进制文件的 RPATH 不是一个好主意.在理想情况下,所有库都将位于系统库目录中.但是如果你把这个推到极致,你最终会得到 Windows(至少是旧的),其中 c:windowssystem32 充满了谁知道来自哪里的垃圾,并且可能会或可能不会与其他软件冲突,等等.使用 rpath 并将所有内容安装在一个地方似乎是一个很好的解决方案.
I have a question related to how to install a built executable program with cmake when it relies on some external libraries. Suppose my executable is abc
, and it relies on two external libraries: lib1.so
and lib2.so
. The structure of the codes are as follows:
-.........
|----bin (lib1.so lib2.so)
|----include(lib1.h lib2.h)
|----src(main.cpp)
When the executable program is installed using the following cmake commands:
INSTALL(TARGETS ${Exe_Name}
RUNTIME DESTINATION Path to bin
LIBRARY DESTINATION Path to bin)
I expect that the executable program will be in the same directory with lib1.so
and lib2.so
. However, when I execute the built program in the installation folder, I met the following error:
error while loading shared libraries: lib1 can not open shared object file No such file or directory
If I use ldd to check the executable, I found lib1.so
and lib2.so not found
. After searching for possible solutions, I found if I call the executable in this way, then it worked:
LD_LIBRARY_PATH=./ ./my_program_run
Then my question is how I can let my executable program knows the locations of the shared libraries with cmake when it is installed? Thanks.
This is best solved this with the RPATH of the final executable. RPATH is a hardcoded search path for the executable itself, and allows the use of the string $ORIGIN
, which expands to the location of the executable at runtime. See this reference: http://man7.org/linux/man-pages/man8/ld.so.8.html
CMake
strips the rpath of a binary at installation time, to avoid the binary picking up libraries littered around your development tree. But it also provides a simple way to modify the installation rpath for exactly this reason. Here's the short answer:
IF(UNIX)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN/../bin:$ORIGIN")
ENDIF()
This particular example appends to the existing rpath, and adds .
and ../bin
to the search path, all relative to the location of the binary.
Some developers claim that adjusting the RPATH of the binary is not a good idea. In the ideal world, all the libraries would live in the system library directories. But if you take this to the extreme, you end up with Windows (at least the older ones), where c:windowssystem32 is full of junk that came from who knows where, and may or may not conflict with other software, etc. Using rpath and installing everything in one place seems like a great solution.
这篇关于为什么在linux(cmake)中加载共享库时安装的程序有错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!