CMake: add_custom_command()のソースファイル指定方法を一新!CMP0050ポリシーの全容


CMakeポリシー CMP0050 は、add_custom_command() 関数におけるソースファイルの指定方法に関するものです。このポリシーは CMake 3.29.4 で導入され、古い動作と新しい動作を切り替えることができます。

古い動作

古い動作では、add_custom_command() 関数でソースファイルのパスを直接指定することができました。これは以下の例のように記述されます。

add_custom_command(
  my_command
  OUTPUT my_output
  COMMAND ${CMAKE_COMMAND} -E copy <source_file> my_output
)

新しい動作

新しい動作では、add_custom_command() 関数でソースファイルのパスを直接指定することはできなくなりました。代わりに、ソースファイルは SOURCES キーワードを使用して指定する必要があります。これは以下の例のように記述されます。

add_custom_command(
  my_command
  OUTPUT my_output
  COMMAND ${CMAKE_COMMAND} -E copy source_file my_output
  SOURCES source_file
)

ポリシーの適用方法

CMakeポリシー CMP0050 を適用するには、以下のいずれかの方法を使用する必要があります。

  • プロジェクトレベルで cmake_minimum_required_version コマンドを使用して、ポリシーが導入された CMake のバージョンを指定する。
  • CMakeLists.txt ファイルで CMAKE_POLICY_DEFAULT_CMP0050 変数を設定する。
  • ポリシーを適用すると、古い動作を使用している箇所でエラーが発生する可能性があります。
  • 古い動作を使用している場合は、add_custom_command() 関数のソースファイル指定方法を変更する必要があります。


# CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

project(my_project)

add_custom_command(
  my_command
  OUTPUT my_output
  COMMAND ${CMAKE_COMMAND} -E copy <source_file> my_output
)

新しい動作

# CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

project(my_project)

cmake_policy(SET CMP0050 NEW)

add_custom_command(
  my_command
  OUTPUT my_output
  COMMAND ${CMAKE_COMMAND} -E copy source_file my_output
  SOURCES source_file
)

説明

上記のコードは、add_custom_command() 関数におけるソースファイルの指定方法を古い動作と新しい動作で比較したものです。

古い動作

古い動作では、<source_file> プレースホルダにソースファイルのパスを直接指定します。

新しい動作

新しい動作では、SOURCES キーワードを使用してソースファイルを指定します。ソースファイルは複数指定することもできます。

ポリシー設定

新しい動作を使用するには、CMakeLists.txt ファイルで cmake_policy(SET CMP0050 NEW) コマンドを使用してポリシーを設定する必要があります。

  • ポリシーを適用すると、古い動作を使用している箇所でエラーが発生する可能性があります。
  • 古い動作を使用している場合は、ソースファイルの指定方法を変更する必要があります。


代替方法

CMP0050 ポリシーの代替方法は、以下の2つが考えられます。

  1. set_property() 関数を使用する

set_property() 関数を使用して、add_custom_command() 関数にソースファイルを関連付けることができます。これは以下の例のように記述されます。

add_custom_command(
  my_command
  OUTPUT my_output
  COMMAND ${CMAKE_COMMAND} -E copy source_file my_output
)

set_property(TARGET my_target APPEND PROPERTY SOURCES source_file)

この方法では、add_custom_command() 関数でソースファイルを直接指定する必要はありません。

  1. add_custom_target() 関数を使用する

add_custom_target() 関数を使用して、ソースファイルを伴うカスタムターゲットを作成することができます。これは以下の例のように記述されます。

add_custom_target(
  my_target
  ALL
  COMMAND ${CMAKE_COMMAND} -E copy source_file my_output
)

この方法では、add_custom_command() 関数を使用する必要はありません。

どちらの代替方法を選択するべきか

どちらの代替方法を選択するかは、プロジェクトの状況によって異なります。

  • add_custom_target() 関数を使用する場合は、コードをより簡潔に記述することができます。
  • set_property() 関数を使用する場合は、add_custom_command() 関数とソースファイルを明確に関連付けることができます。

上記以外にも、CMakeにはソースファイルを指定する様々な方法があります。詳細は CMake ドキュメントを参照してください。