【保存版】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) 行は、MyProgramMyLib ライブラリにリンクします。
  • 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 設定を修正することができます。このスクリプトは、CMakepost_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 ...