[英]How to link a shared library with CMake with relative path
I want to link a third-party libLibrary.so
and distribute it with my program.我想链接第三方
libLibrary.so
并将其与我的程序一起分发。 If user unzips my archive, he will get this folder structure:如果用户解压缩我的档案,他将获得以下文件夹结构:
game
libLibrary.so
game_executable
game_executable
depends on ./libLibrary.so
. game_executable
取决于./libLibrary.so
。
My project structure:我的项目结构:
game
bin
libLibrary.so
lib
Library.h
src
game_executable.cpp
CMakeLists.txt
My CMakeLists.txt
:我的
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.7)
project(game)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(SOURCE_FILES src/game_executable.cpp)
include_directories(${CMAKE_SOURCE_DIR}/lib)
add_executable(game ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CMAKE_BINARY_DIR}/libLibrary.so)
However, what I get is my game_executable
depends on the .../game/bin/libLibrary.so
, not on the ./libLibrary.so
that is in the folder with game_executable
, making this totally unportable!但是,我得到的是我的
game_executable
取决于.../game/bin/libLibrary.so
,而不是./libLibrary.so
,它位于game_executable
文件夹中,这使得它完全game_executable
移植!
How can I make linking path relative instead of absolute?如何使链接路径相对而不是绝对?
From the documentation :从文档:
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.
默认情况下,如果您不更改任何 RPATH 相关设置,CMake 会将具有完整 RPATH 的可执行文件和共享库链接到构建树中所有使用的库。
This is the behaviour you are seeing.这是您所看到的行为。
However, there are a number of ways to change this to match the behaviour you require.但是,有多种方法可以更改此设置以匹配您需要的行为。
Some examples from the above linked docs:来自上述链接文档的一些示例:
# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
# the RPATH to be used when installing
SET(CMAKE_INSTALL_RPATH "")
# don't add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
Using the above you'll likely want to set CMAKE_INSTALL_RPATH
and then distribute the installed binary.使用上述内容,您可能希望设置
CMAKE_INSTALL_RPATH
,然后分发已安装的二进制文件。
If you want to distribute from the binary in your build tree, it is also possible to bypass CMake's rpath handling and modify the rpath directly using linker flags:如果您想从构建树中的二进制文件分发,也可以绕过 CMake 的 rpath 处理并使用链接器标志直接修改 rpath:
set_target_properties(game PROPERTIES LINK_FLAGS "-Wl,-rpath,./")
Most of the time you want to modify the RPATH
with $ORIGIN
instead of .
大多数时候,你要修改的
RPATH
用$ORIGIN
代替.
, because it refers to the executable's path instead while .
,因为它指的是可执行文件的路径而不是
.
refers to the current directory at runtime (which can be anything else).指运行时的当前目录(可以是其他任何目录)。
I find it simple to edit LINK_FLAGS
instead of INSTALL_RPATH
target property, because CMakes already has a variable named ORIGIN
(seeCMake's documentation ).我发现编辑
LINK_FLAGS
而不是INSTALL_RPATH
目标属性很简单,因为 CMakes 已经有一个名为ORIGIN
的变量(请参阅CMake 的文档)。
So that boils down to the following:所以这归结为以下几点:
# Find shared libraries next to the executable
set_target_properties(target_name PROPERTIES
BUILD_WITH_INSTALL_RPATH FALSE
LINK_FLAGS "-Wl,-rpath,$ORIGIN/")
如果您使用target_link_directories
那么 cmake 会将其作为手动 rpath 添加到链接器命令中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.