CMakeのバージョンアップに伴う変更点:ポリシーCMP0070で相対パス処理を最新化


CMakeポリシーCMP0070は、CMake 3.15で導入された比較的新しいポリシーです。このポリシーは、相対パスを処理する方法に関する古い未定義の動作との互換性を提供するために使用されます。

旧動作

CMake 3.9以前では、相対パスに関する明確な動作が定義されていませんでした。しかし、古いCMakeバージョンは、誤ってプロセスワーキングディレクトリを基準とした相対パスを処理していました。

CMP0070 の影響

CMP0070ポリシーが設定されていない場合、CMakeは警告を発し、古い動作を使用します。古い動作は本質的に非推奨であり、将来のバージョンのCMakeで削除される可能性があります。

CMP0070 の設定方法

このポリシーを有効にするには、CMakeLists.txtファイルで次の行を追加します。

cmake_policy(SET CMP0070 NEW)

この行を追加すると、CMakeは相対パスを処理する方法に関する新しい動作を使用します。新しい動作では、相対パスはCMakeLists.txtファイルが存在するディレクトリを基準に処理されます。

CMP0070 を使用する利点

CMP0070を使用する利点は次のとおりです。

  • バグの可能性を減らすことができます。
  • 将来のバージョンのCMakeとの互換性を確保できます。
  • コードの移植性を向上させることができます。

CMP0070 を使用する際の注意点

CMP0070を使用する際には、次の点に注意する必要があります。

  • プロジェクトで相対パスを使用している場合は、新しい動作が意図した動作であることを確認してください。
  • 古いCMakeバージョンのプロジェクトと互換性を保つ必要がある場合は、このポリシーを使用しないことを検討してください。


cmake_minimum_required(VERSION 3.9)

project(myproject)

file(GENERATE OUTPUT "output.txt" CONTENT "Hello, world!")

このコードを実行すると、output.txtファイルが現在のワーキングディレクトリに作成されます。

新しい動作の例

cmake_minimum_required(VERSION 3.15)

cmake_policy(SET CMP0070 NEW)

project(myproject)

file(GENERATE OUTPUT "output.txt" CONTENT "Hello, world!")

このコードを実行すると、output.txtファイルがCMakeLists.txtファイルが存在するディレクトリに作成されます。

説明

古い動作では、file(GENERATE)コマンドのOUTPUT引数に指定された相対パスは、現在のワーキングディレクトリを基準に処理されます。一方、新しい動作では、相対パスはCMakeLists.txtファイルが存在するディレクトリを基準に処理されます。

その後、file(GENERATE)コマンドを使用して"output.txt"という名前のファイルを生成します。このコマンドのCONTENT引数には、ファイルに書き込むテキスト"Hello, world!"が指定されています。

古い動作では、このコードを実行すると、output.txtファイルが現在のワーキングディレクトリに作成されます。一方、新しい動作では、output.txtファイルがCMakeLists.txtファイルが存在するディレクトリに作成されます。



代替方法 1: 絶対パスを使用する

最も簡単な代替方法は、絶対パスを使用することです。絶対パスは、システム上のファイルまたはディレクトリの完全な場所を指定します。相対パスとは異なり、絶対パスは現在のワーキングディレクトリに依存しません。

file(GENERATE OUTPUT "/path/to/output.txt" CONTENT "Hello, world!")

上記の例では、file(GENERATE)コマンドのOUTPUT引数に絶対パス/path/to/output.txtが指定されています。このコードを実行すると、output.txtファイルが指定された場所に作成されます。

代替方法 2: CMakeのCMAKE_CURRENT_LIST_DIRマクロを使用する

CMakeには、CMAKE_CURRENT_LIST_DIRというマクロが用意されています。このマクロは、CMakeLists.txtファイルが存在するディレクトリのパスを返します。

file(GENERATE OUTPUT "${CMAKE_CURRENT_LIST_DIR}/output.txt" CONTENT "Hello, world!")

上記の例では、file(GENERATE)コマンドのOUTPUT引数に${CMAKE_CURRENT_LIST_DIR}/output.txtという式が指定されています。この式は、CMakeLists.txtファイルが存在するディレクトリのパスにoutput.txtという文字列を追加します。

代替方法 3: CMakeのCMAKE_SOURCE_DIRマクロを使用する

CMakeには、CMAKE_SOURCE_DIRというマクロも用意されています。このマクロは、ソースディレクトリのパスを返します。ソースディレクトリは、CMakeプロジェクトのルートディレクトリです。

file(GENERATE OUTPUT "${CMAKE_SOURCE_DIR}/output.txt" CONTENT "Hello, world!")

上記の例では、file(GENERATE)コマンドのOUTPUT引数に${CMAKE_SOURCE_DIR}/output.txtという式が指定されています。この式は、ソースディレクトリのパスにoutput.txtという文字列を追加します。