简体   繁体   English

如何使用相对路径将共享库与 CMake 链接

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM