LoginSignup
3
1

More than 1 year has passed since last update.

CMake で install の RPATH 設定を相対にやりたいメモ(Linux)

Last updated at Posted at 2022-08-04
build/bin/myapp  # libmyapp.so と絶対パスでリンクしている
build/lib/libmyapp.so

みたいなケースで, install して

dist/bin/myapp
dist/lib/libmyapp.so

のようになると libmyapp.so へのリンクが絶対パスなので
cmake で install すると .so のリンクが not found になる...

Linux を考えます.
また, build 時と install 時でディレクトリの構成は変わらないものとします.

再現 repo

再現テスト用の repo を作りました.

原因

デフォルトでは, ビルド時は RPATH (runtime) が使われ, インストール時は RPATH なしで処理されます.

そのため, install すると RPATH のパスが空になり, binary と .so でディレクトリを分けている場合 .so not found になります.

また, build 時も基本は絶対パスでのリンクになっていますので, build フォルダをコピーして install 相当にして対応というのもできないです.

解決方法(絶対パス) 

構成にもよりますが, 最低限 CMAKE_INSTALL_RPATH を設定すればよいようです.

cmake_minimum_required(VERSION 3.16)
  
  project(MyApp C CXX)
  
  set(LIB_SOURCES mylib.cc)
  
  set(CMAKE_SKIP_BUILD_RPATH FALSE)
  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
  set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
  
  add_library(mylib SHARED ${LIB_SOURCES})
  
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    set_target_properties(mylib PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
  )
  install(TARGETS mylib LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
  
  add_executable(myapp myapp.cc)
  target_link_libraries(myapp PRIVATE mylib)
  
  install(TARGETS myapp RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)

Install 時, ログに

Set runtime path of "/home/syoyo/work/cmake-rpath-experiment/dist/lib/libmylib.so" to "/home/syoyo/work/cmake-rpath-experiment/dist/lib"

のようになってきちんと runtime path 処理されているのを確認しましょう.

ORIGIN で相対パスにする(推奨)

上記だとしかしインストールディレクトリでの絶対パスで処理されるため, さらにインストールディレクトリを移動したりしたときは .so が見つからなくなります.

より汎用には, $ORIGIN を利用して相対にするのが推奨でしょう.

set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib"

(↑のリンクにあるように, CMAKE_INSTALL_RPATH でグローバルではなく target の property で設定するのが推奨ではある)

$ORIGIN 利用だと以下のような感じになりました.

libmylib.so => /home/syoyo/work/cmake-rpath-experiment/dist/bin/./../lib/libmylib.so (0x00007f3a3e266000)

ただ, ビルド構成によっては /path/to/bin/../bin/../lib みたいなややこしいパスになってしまうようですので, 単に ../lib でもいいかもしれません.

set(CMAKE_INSTALL_RPATH "../lib")
libmylib.so => ../lib/libmylib.so
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1