CMakeで共有ライブラリのRPATHを設定するときに見ること
CMakeで共有ライブラリをリンクした実行ファイルを動かすと、ビルドは通っているのに実行時にライブラリが見つからないことがあります。
Linuxなら error while loading shared libraries、macOSなら Library not loaded のようなエラーです。
このときに見るのがRPATHです。
RPATHとは
RPATHは、実行ファイルが共有ライブラリを探すためのパスです。
リンク時にライブラリが見つかっていても、実行時に同じ場所を探すとは限りません。
CMakeでは、ビルド時とinstall後で別のRPATHを設定できます。
| プロパティ | 役割 |
|---|---|
BUILD_RPATH |
build tree内で実行するときのRPATH |
INSTALL_RPATH |
install後に使うRPATH |
https://cmake.org/cmake/help/latest/prop_tgt/BUILD_RPATH.html
https://cmake.org/cmake/help/latest/prop_tgt/INSTALL_RPATH.html
build中に動かす場合
ビルドディレクトリ内で実行ファイルを動かすなら、BUILD_RPATH を設定します。
add_executable(my_app
src/main.cpp
)
target_link_libraries(my_app
PRIVATE
my_shared_lib
)
set_target_properties(my_app PROPERTIES
BUILD_RPATH "${CMAKE_BINARY_DIR}/lib"
)
ただし、CMakeは同じプロジェクト内の共有ライブラリについて、ある程度自動でRPATHを設定します。
まずは何も設定せずに動かし、外部ライブラリや特殊な配置で必要になったら足すくらいでよいです。
install後に動かす場合
install後の配置で共有ライブラリを見つけたい場合は INSTALL_RPATH を使います。
set_target_properties(my_app PROPERTIES
INSTALL_RPATH "$ORIGIN/../lib"
)
Linuxでは $ORIGIN が実行ファイルの場所を表します。
dist/
├── bin/
│ └── my_app
└── lib/
└── libmy_shared_lib.so
この配置なら、bin/my_app から見て ../lib を探せばよいので $ORIGIN/../lib になります。
macOSでは @loader_path を使うことがあります。
set_target_properties(my_app PROPERTIES
INSTALL_RPATH "@loader_path/../lib"
)
install設定と一緒に見る
RPATHはinstall後の配置とセットで考えます。
install() の基本は CMakeで実行ファイルとライブラリをinstallするときの設定 に分けています。
出力先だけを変えたい場合は CMakeで実行ファイルの出力先を分けるときの設定 が近いです。
まとめ
共有ライブラリが実行時に見つからない場合は、RPATHを確認します。
- build tree内で動かすなら
BUILD_RPATH - install後に動かすなら
INSTALL_RPATH - Linuxでは
$ORIGINを使うことがある - macOSでは
@loader_pathを使うことがある - install後の配置とセットで考える
RPATHは最初から細かく触るより、共有ライブラリの配置が決まってから設定する方が分かりやすいです。


