CMake 3.14の新機能「CMP0087」:インストールにおける生成式の扱い方


CMakeポリシー「CMP0087」は、install(CODE)install(SCRIPT) コマンドにおける生成器式の扱い方を制御します。このポリシーはCMake 3.14で導入されました。

旧動作と新動作

  • 新動作 (CMake 3.14 以降): install(CODE)install(SCRIPT) コマンドは、生成式を評価し、生成された値に基づいてコードまたはスクリプトをインストールします。
  • 旧動作 (CMake 3.13 以前): install(CODE)install(SCRIPT) コマンドは、生成式を評価せずに、指定されたコードまたはスクリプトをそのままインストールします。

影響を受ける箇所

このポリシーは、以下の状況に影響を与えます。

  • 生成式を使用してインストールするファイル名や内容を指定する場合
  • 生成式を使用してインストール先のパスを指定する場合

設定方法

このポリシーは、以下の方法で設定できます。

  • cmake_policy コマンドを使用する:
cmake_policy(SET CMP0087 NEW)
  • CMakeLists.txtファイルに直接記述する:
POLICY(CMP0087 NEW)

注意事項

  • include() で導入されたファイルではなく、add_subdirectory() で導入されたサブディレクトリからこれらのコマンドを呼び出す場合に影響を受けます。
  • ディレクトリスコープ末尾で設定された値が有効になります。install(CODE) または install(SCRIPT) コマンドを呼び出す場所とは異なる場合があります。
  • ポリシーの「旧動作」は非推奨であり、将来のCMakeバージョンで削除される可能性があります。
  • このポリシーのデフォルト動作は「旧動作」です。

以下の例は、install(CODE) コマンドで生成式を使用してインストール先のパスを指定する方法を示しています。

cmake_policy(SET CMP0087 NEW)

set(INSTALL_DIR ${CMAKE_BINARY_DIR}/install)

install(CODE DESTINATION ${INSTALL_DIR}
  CODE "message(\"Hello, world!\")")

この例では、install(CODE) コマンドは CMAKE_BINARY_DIR 変数を評価し、その値を DESTINATION 引数に渡します。結果として、コードは install ディレクトリにインストールされます。



cmake_policy(SET CMP0087 NEW)

set(INSTALL_BASE_DIR "/usr/local")
set(USER_DIR "${CMAKE_CURRENT_USER}")

install(CODE DESTINATION ${INSTALL_BASE_DIR}/${USER_DIR}
  CODE "message(\"Hello, ${USER_DIR}!\")")

この例では、以下の処理が行われます。

  1. cmake_policy コマンドを使用して、CMP0087 ポリシーを「新動作」に設定します。
  2. INSTALL_BASE_DIR 変数に、デフォルトのインストール先ディレクトリを設定します。
  3. USER_DIR 変数に、現在のユーザー名を設定します。
  4. install(CODE) コマンドを使用して、コードをインストールします。
    • DESTINATION 引数には、INSTALL_BASE_DIRUSER_DIR 変数を連結したパスを指定します。
    • コードは、現在のユーザー名を出力するメッセージを表示します。

例2: 生成式を使用してインストールするファイル名と内容を指定する

この例では、install(SCRIPT) コマンドで生成式を使用してインストールするファイル名と内容を指定する方法を示します。

cmake_policy(SET CMP0087 NEW)

set(CONFIG_FILE "${CMAKE_BINARY_DIR}/config.txt")
set(CONFIG_CONTENT "MY_VAR=${CMAKE_CURRENT_BINARY_DIR}")

install(SCRIPT DESTINATION ${CONFIG_FILE}
  CODE "file(WRITE \"${CONFIG_FILE}\" \"${CONFIG_CONTENT}\")")
  1. cmake_policy コマンドを使用して、CMP0087 ポリシーを「新動作」に設定します。
  2. CONFIG_FILE 変数に、設定ファイルのパスを設定します。
  3. CONFIG_CONTENT 変数に、設定ファイルの内容を設定します。
    • MY_VAR 変数には、現在のバイナリディレクトリのパスを設定します。
  4. install(SCRIPT) コマンドを使用して、スクリプトをインストールします。
    • DESTINATION 引数には、CONFIG_FILE 変数の値を指定します。
    • スクリプトは、CONFIG_FILE ファイルに CONFIG_CONTENT 変数の値を書き込みます。
  • 具体的な状況に合わせて、さまざまな方法でこのポリシーを活用することができます。
  • これらの例は、CMP0087 ポリシーの使用方法を示すほんの一例です。


代替方法

「CMP0087」ポリシーを使用せずに、生成式を使用してファイルをインストールするには、以下の代替方法を使用できます。

CMAKE_POST_PROCESS_TARGETS プロパティを使用する

この方法は、ターゲットのビルド後に実行されるカスタムコマンドを定義できます。

set(CMAKE_POST_PROCESS_TARGETS MyTarget COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/script.sh" "${INSTALL_DIR}")
  1. MyTarget ターゲットの CMAKE_POST_PROCESS_TARGETS プロパティに、カスタムコマンドを設定します。
  2. カスタムコマンドは、script.sh スクリプトを INSTALL_DIR ディレクトリにコピーします。

add_custom_command コマンドを使用する

この方法は、任意のタイミングで実行されるカスタムコマンドを定義できます。

add_custom_command(INSTALL_SCRIPT
  COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_BINARY_DIR}/script.sh" "${INSTALL_DIR}")
  1. INSTALL_SCRIPT という名前のカスタムコマンドを定義します。
  2. カスタムコマンドは、script.sh スクリプトを INSTALL_DIR ディレクトリにコピーします。

configure_file コマンドを使用する

この方法は、テンプレートファイルを生成し、インストールする前にそのファイルを処理できます。

configure_file("${CMAKE_CURRENT_BINARY_DIR}/config.txt.in" "${INSTALL_DIR}/config.txt" COPYONLY)
  1. config.txt.in テンプレートファイルを config.txt ファイルにコピーします。
  2. ファイルはコピーのみされ、処理されません。
  • 具体的な状況に合わせて、最適な方法を選択する必要があります。
  • 上記の代替方法は、CMP0087 ポリシーと同等の機能を提供するとは限りません。