Why is CMake designed so that it removes runtime path when installing(为什么 CMake 设计为在安装时删除运行时路径)
问题描述
我自己构建了我的共享库(例如我使用了一个计算斐波那契数的库),并希望在我的另一个由 CMake
I built my shared library(I use a lib calculating the fibonacci number for example) myself and want to use it in my another c++ project built by CMake
假设共享库和头文件位于 /path/to/my/lib
,共享库 libfib.so
位于 /path/to/my/lib/lib
和标题 fib.h
在 /path/to/my/lib/include
和我自己的项目位于 >/path/to/my/project
Let's say the shared library and headers located in /path/to/my/lib
, the shared library libfib.so
is in /path/to/my/lib/lib
and the header fib.h
is in /path/to/my/lib/include
and my own project located in /path/to/my/project
这是我原来的CMakeLists.txt
:
cmake_minimum_required(VERSION 3.2)
project(learn-lib)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
set(FIB_INCLUDE "${FIB_PREFIX}/include")
set(FIB_LIB "${FIB_PREFIX}/lib")
set(EXE mybin)
include_directories(${FIB_INCLUDE})
link_directories(${FIB_LIB})
add_executable(${EXE} main.cpp)
target_link_libraries(${EXE} fib)
install(TARGETS ${EXE} RUNTIME DESTINATION bin)
我使用这个脚本来构建和安装我的项目:
And I use this script to build and install my project:
mkdir -p build_dir
cd build_dir
cmake -DFIB_PREFIX=/path/to/my/lib
-DCMAKE_INSTALL_PREFIX=/path/to/my/project
..
make
make install
cd ..
现在,在运行安装脚本后,我得到了两个可执行文件,一个在 build_dir
中,一个在安装位置 path/to/my/project/bin
中,当在 build_dir
中运行程序,一切正常,但是在运行已安装的程序时,我得到:
Now, after running the install script, I got two executables, one in build_dir
, one in the install location path/to/my/project/bin
, when running the program in build_dir
, everything is fine, but when running the installed program, I get:
./bin/mybin:加载共享库时出错:libfib.so:无法打开共享对象文件:没有这样的文件或目录
./bin/mybin: error while loading shared libraries: libfib.so: cannot open shared object file: No such file or directory
在 google 和 stackoverflow 上进行一些搜索后,我知道 CMake
似乎删除了构建时与可执行文件相关联的运行时搜索路径.我现在知道两种解决方法:
After some searching on google and stackoverflow, I knew it seems that CMake
removed the runtime search path that is tied to the executable when building. I now know two ways to get it around:
- 将
libfib.so
所在的库路径添加到环境变量LD_LIBRARY_PATH
- 将
set_target_properties(${EXE} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
添加到我的CMakeLists.txt
- Add the library path where
libfib.so
locates to the environment variableLD_LIBRARY_PATH
- Add
set_target_properties(${EXE} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
into myCMakeLists.txt
所以,我的问题是:
- 为什么
CMake
是这样设计的?安装时,为什么要从可执行文件中删除运行时路径,而不是将构建的可执行文件复制到安装目标或保留已安装程序的链接路径的任何内容? - 哪种方法是消除此问题的最佳做法(或是否有最佳做法)?设置环境或将
set_target_properties(...)
添加到CMakeLists.txt
中?
- Why is
CMake
designed so? When installing, why would it remove runtime path from executables instead of just copying the built executables to the install destination or whatever keeping the link path for the installed program? - Which way is the best practice(or is there a best practice) to eliminate this problem? To set the environment or to add
set_target_properties(...)
intoCMakeLists.txt
?
推荐答案
您可能需要查看 CMake 的 RPATH 处理设置
这句话似乎与您的困境特别相关:
This quote in particular seems relevant to your predicament:
默认情况下,如果您不更改任何 RPATH 相关设置,CMake 会将具有完整 RPATH 的可执行文件和共享库链接到构建树中所有使用的库.安装时,会清除这些目标的 RPATH,以便安装时使用空的 RPATH.
By default if you don't change any RPATH related settings, CMake will link the executables and shared libraries with full RPATH to all used libraries in the build tree. When installing, it will clear the RPATH of these targets so they are installed with an empty RPATH.
您可以使用 CMAKE_INSTALL_RPATH
变量设置为已安装二进制文件设置的 RPATH,例如:
You can set the RPATH that is set for installed binaries using the CMAKE_INSTALL_RPATH
variable, for example:
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
并且您还可以在安装过程中禁用 RPATH 剥离:
and you can also disable the RPATH stripping during installation:
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
这篇关于为什么 CMake 设计为在安装时删除运行时路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 CMake 设计为在安装时删除运行时路径
基础教程推荐
- 从 std::cin 读取密码 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01