【保存版】CMake: ツールチェーンRPATHとさよなら! CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATHでクリーンなインストールを実現
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
は、CMake 3.16 以降で導入された変数です。この変数は、インストール時にツールチェーン定義の RPATH エントリを削除するかどうかを制御します。
RPATH とは
RPATH (Run-Time Path) は、実行時にライブラリを検索するためのディレクトリパスを指定するものです。これは、プログラムが実行時に必要な共有ライブラリを見つけるのに役立ちます。
ツールチェーン定義の RPATH
ツールチェーン定義の RPATH は、ビルドシステムまたはツールチェーンによって設定される RPATH エントリです。これらのエントリは、特定のプラットフォームやライブラリセットに必要な共有ライブラリを見つけるために使用されます。
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
の役割
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数は、インストール時にツールチェーン定義の RPATH エントリを削除するかどうかを制御します。この変数が TRUE
に設定されている場合、CMake はインストール時にツールチェーン定義の RPATH エントリを削除します。これは、インストールされたプログラムが RPATH エントリに依存せず、必要な共有ライブラリをシステムの標準的な場所で見つけることを保証するのに役立ちます。
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
の設定
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数は、CMake のコマンドラインオプションまたは CMakeLists.txt ファイル内の変数設定を使用して設定できます。
コマンドラインオプション
cmake -DCMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH=TRUE ...
CMakeLists.txt ファイル
set(CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH TRUE)
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
の使用例
以下の例は、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を使用して、ツールチェーン定義の RPATH エントリを削除する方法を示しています。
cmake_minimum_required(VERSION 3.16)
project(MyProject)
set(CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH TRUE)
add_executable(MyProgram myprogram.cpp)
target_install(MyProgram DESTINATION bin)
この例では、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数が TRUE
に設定されているため、MyProgram
プログラムがインストールされるときに、ツールチェーン定義の RPATH エントリが削除されます。
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
の利点
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を使用する利点は次のとおりです。
- システムのクリーンアップ: ツールチェーン定義の RPATH エントリは、不要なエントリでシステムを散らかす可能性があります。これらのエントリを削除することで、システムをクリーンで整理することができます。
- セキュリティを向上させる: ツールチェーン定義の RPATH エントリは、悪意のあるコードを挿入するために使用される可能性があります。これらのエントリを削除することで、プログラムを悪意のある攻撃から保護するのに役立ちます。
- プログラムの移植性を向上させる: プログラムが RPATH エントリに依存しないため、さまざまなシステムで簡単に移植できます。
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
の注意点
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を使用する際には、以下の点に注意する必要があります。
- ツールチェーンの要件: 一部のツールチェーンは、RPATH エントリが設定されていることを想定しています。このようなツールチェーンを使用している場合は、
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を設定する前に、ツールチェーンのドキュメントを確認する必要があります。 - プログラムが RPATH エントリに依存している場合: プログラムが RPATH エントリに依存している場合は、
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を設定すると、プログラムが実行時に必要な共有ライブラリを見つけることができなくなる可能性があります。
例 1: コマンドラインオプション
cmake -DCMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH=TRUE \
-DCMAKE_BUILD_TYPE=Release \
-G "Unix Makefiles" \
/path/to/source/directory
この例では、cmake
コマンドを使用して、MyProject
プロジェクトをビルドします。
/path/to/source/directory
オプションは、ソースディレクトリを指定します。-G "Unix Makefiles"
オプションは、Unix Makefiles ジェネレータを使用するように指定します。-DCMAKE_BUILD_TYPE=Release
オプションは、ビルドタイプをRelease
に設定します。-DCMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH=TRUE
オプションは、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数をTRUE
に設定します。
例 2: CMakeLists.txt ファイル
cmake_minimum_required(VERSION 3.16)
project(MyProject)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_INSTALL_PREFIX /usr/local)
set(CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH TRUE)
add_executable(MyProgram myprogram.cpp)
target_link_libraries(MyProgram MyLib)
target_install(MyProgram DESTINATION bin)
install(TARGETS MyLib DESTINATION lib)
この例では、CMakeLists.txt
ファイルを使用して、MyProject
プロジェクトをビルドします。
install(TARGETS MyLib DESTINATION lib)
行は、MyLib
を/usr/local/lib
ディレクトリにインストールします。target_install(MyProgram DESTINATION bin)
行は、MyProgram
を/usr/local/bin
ディレクトリにインストールします。target_link_libraries(MyProgram MyLib)
行は、MyProgram
をMyLib
ライブラリにリンクします。add_executable(MyProgram myprogram.cpp)
行は、MyProgram
という名前の実行可能ファイルを追加します。set(CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH TRUE)
行は、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数をTRUE
に設定します。set(CMAKE_INSTALL_PREFIX /usr/local)
行は、インストールプレフィックスを/usr/local
に設定します。set(CMAKE_BUILD_TYPE Release)
行は、ビルドタイプをRelease
に設定します。project(MyProject)
行は、プロジェクトの名前をMyProject
に設定します。cmake_minimum_required(VERSION 3.16)
行は、CMake の最小バージョンを 3.16 に設定します。
- ツールチェーンの要件: 一部のツールチェーンは、RPATH エントリが設定されていることを想定しています。このようなツールチェーンを使用している場合は、
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を設定する前に、ツールチェーンのドキュメントを確認する必要があります。 - プログラムが RPATH エントリに依存している場合: プログラムが RPATH エントリに依存している場合は、
CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を設定すると、プログラムが実行時に必要な共有ライブラリを見つけることができなくなる可能性があります。
これらの問題を回避するために、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数の代替方法をいくつか検討することができます。
インストール後の RPATH 設定の修正
この方法は、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数を使用せずに、インストール後に RPATH 設定を修正することを意味します。
- カスタムスクリプトを使用する: カスタムスクリプトを使用して、インストール後に RPATH 設定を修正することができます。このスクリプトは、
CMake
のpost_install
ターゲットを使用して実行できます。 - ldconfig ツールを使用する:
ldconfig
ツールは、システムの共有ライブラリキャッシュを更新するために使用できます。このツールを使用して、インストールされたプログラムに必要な共有ライブラリが見つかるように RPATH 設定を修正することができます。
例:ldconfig
ツールを使用する
cmake -DCMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH=FALSE ...
make install
ldconfig
ldconfig
コマンドは、システムの共有ライブラリキャッシュを更新します。make install
コマンドは、プロジェクトをインストールします。-DCMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH=FALSE
オプションは、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数をFALSE
に設定します。
この例では、CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
変数が FALSE
に設定されているため、MyProgram
プログラムと MyLib
ライブラリがインストールされるときに、ツールチェーン定義の RPATH エントリは削除されません。ただし、ldconfig
コマンドを使用して、インストール後に RPATH 設定が修正されます。
インストールディレクトリを調整する
この方法は、RPATH エントリを必要としない場所にプログラムをインストールすることを意味します。
- システム共有ライブラリではなく静的ライブラリを使用する: システム共有ライブラリではなく、静的ライブラリを使用してプログラムをビルドします。これにより、プログラムが RPATH エントリに依存する必要がなくなります。
- 標準のインストールプレフィックスを使用しない: 標準のインストールプレフィックス (
/usr/local
など) を使用せずに、カスタムのインストールディレクトリを使用します。これにより、プログラムが RPATH エントリに依存する可能性を低減できます。
例:カスタムインストールディレクトリを使用する
cmake -DCMAKE_INSTALL_PREFIX=/opt/MyProject ...
make install
make install
コマンドは、プロジェクトをインストールします。-DCMAKE_INSTALL_PREFIX=/opt/MyProject
オプションは、インストールプレフィックスを/opt/MyProject
に設定します。
この例では、MyProgram
プログラムと MyLib
ライブラリは /opt/MyProject
ディレクトリにインストールされます。このディレクトリは標準のインストールプレフィックスではないため、プログラムは RPATH エントリに依存する可能性が低くなります。
この方法は、RPATH エントリを生成しないツールチェーンを使用することを意味します。
- ツールチェーン設定を調整する: ツールチェーン設定を調整して、RPATH エントリの生成を無効にすることができます。
- 別のコンパイラを使用する: RPATH エントリを生成しない別のコンパイラを使用します。
CC=clang CXX=clang++ cmake ...