Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to link a shared library with CMake with relative path

Tags:

c++

cmake

I want to link a third-party libLibrary.so and distribute it with my program. If user unzips my archive, he will get this folder structure:

game
  libLibrary.so
  game_executable

game_executable depends on ./libLibrary.so.

My project structure:

game
  bin
    libLibrary.so
  lib
    Library.h
  src
    game_executable.cpp
  CMakeLists.txt

My 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!

How can I make linking path relative instead of absolute?

like image 566
The Saber Cat Avatar asked Apr 10 '17 18:04

The Saber Cat


People also ask

How do I create a relative path in CMake?

Our CMakeLists. txt needs to add a subdirectory using relative path such as: add_subdirectory(${CMAKE_SOURCE_DIR}/../../Foundation/BlahLib ...) CMake requires that the binary directory be specified as the second argument in the add_subdirectory command whenever such relative paths are used.

Can rpath be relative?

The RPATH entries for directories contained within the build tree can be made relative to enable relocatable builds and to help achieve reproducible builds by omitting the build directory from the build environment.

How do I add a library to CMake project?

To add a library in CMake, use the add_library() command and specify which source files should make up the library. Rather than placing all of the source files in one directory, we can organize our project with one or more subdirectories.


1 Answers

Most of the time you want to set the RPATH to $ORIGIN instead of ., 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 (see CMake's documentation).

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/")
like image 190
CharlesB Avatar answered Oct 21 '22 12:10

CharlesB