我有一个问题与如何使用cmake安装构建的可执行程序有关,当它依赖于某些外部库时。假设我的可执行文件是abc
,它依赖于两个外部库:lib1.so
和lib2.so
。代码的结构如下:
-.........
|----bin (lib1.so lib2.so)
|----include(lib1.h lib2.h)
|----src(main.cpp)
使用以下cmake命令安装可执行程序时:
INSTALL(TARGETS ${Exe_Name}
RUNTIME DESTINATION Path to bin
LIBRARY DESTINATION Path to bin)
我希望可执行程序与lib1.so
和lib2.so
位于同一目录中。但是,当我在安装文件夹中执行构建的程序时,我遇到以下错误:
error while loading shared libraries: lib1 can not open shared object file No such file or directory
如果我使用ldd检查可执行文件,我找到了lib1.so
和lib2.so not found
。在搜索可能的解决方案后,我发现如果以这种方式调用可执行文件,那么它可以工作:
LD_LIBRARY_PATH=./ ./my_program_run
然后我的问题是如何让我的可执行程序在安装时用cmake知道共享库的位置?谢谢。
答案 0 :(得分:2)
如果要将应用程序干净地安装到标准的Linux发行版中,那么您应该将支持的共享库安装到标准位置(/ usr / lib),或者应该将库位置添加到ld.so配置中,通过创建一个/etc/ld.so.conf.d/myprogram.conf
文件,其中包含库所在目录的名称。
如果安装是临时的或更临时的,那么设置LD_LIBRARY_PATH的脚本是合适的。
答案 1 :(得分:2)
最好用最终可执行文件的RPATH解决这个问题。 RPATH是可执行文件本身的硬编码搜索路径,允许使用字符串$ORIGIN
,它在运行时扩展到可执行文件的位置。请参阅此参考:http://man7.org/linux/man-pages/man8/ld.so.8.html
CMake
在安装时剥离二进制文件的rpath,以避免二进制文件在您的开发树周围乱丢。但它也提供了一种简单的方法来修改安装路径,正是出于这个原因。这是简短的回答:
IF(UNIX)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:\$ORIGIN/../bin:\$ORIGIN")
ENDIF()
此特定示例附加到现有rpath,并将.
和../bin
添加到搜索路径,所有这些都相对于二进制文件的位置。
一些开发人员声称调整二进制文件的RPATH并不是一个好主意。在理想的世界中,所有库都将存在于系统库目录中。但是如果你把这种情况发挥到极致,你最终会得到Windows(至少是旧的),其中c:\ windows \ system32充满了垃圾,这些垃圾来自谁知道在哪里,可能与其他软件冲突,也可能不与其他软件发生冲突,使用rpath并将所有内容安装在一个地方似乎是一个很好的解决方案。
答案 2 :(得分:0)
在预定义的位置搜索库,其中包括使用ld.so.conf和LD_LIBRARY_PATH配置的标准库路径。您也可以尝试使用-rpath编译您的应用程序,但某些开发人员不建议这样做。我建议你创建一个包装脚本,它将设置LD_LIBRARY_PATH并像这样运行真正的应用程序:
“theapp”脚本:
#!/bin/sh
dir="`dirname \"$0\"`"
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}"$dir"
exec "$dir/theapp.real" # your real application
应用程序,脚本和库应位于同一位置(在bin /)下。