CMake 3.13 以降で必須! ポリシー CMP0007 による空要素処理の変更点


CMake のポリシー CMP0007 は、list コマンドがリスト内の空要素をどのように扱うかを制御します。

旧動作と新動作

  • 新動作 (NEW)
    空要素もカウントされます。例: a;b;;c は長さ4、要素は a, b, 空要素, c となります。
  • 旧動作 (OLD)
    空要素は無視されます。例: a;b;;c は長さ3、要素は a, b, c となります。

影響

このポリシー変更は、list コマンドを使用する古い CMake プロジェクトに影響を与える可能性があります。例えば、空要素を想定していたコードが、新動作では予期しない動作になる可能性があります。

対処方法

以下の方法で、このポリシー変更の影響に対処できます。

  1. CMake のバージョンを確認
    使用している CMake のバージョンが 3.13 より古い場合は、CMP0007 ポリシーが適用されないため、影響を受けません。
  2. ポリシーを設定
    CMake 3.13 以降を使用している場合は、cmake_policy コマンドを使用してポリシーを設定する必要があります。
cmake_policy(SET CMP0007 OLD)

上記のコードは、list コマンドが旧動作を使用するように設定します。

  1. コードを修正
    空要素を明示的に処理するようにコードを修正します。

以下のコードは、list コマンドを使用してリストの要素数を取得します。

list(LENGTH my_list list_length)

旧動作では、list_length は 3 になりますが、新動作では 4 になります。

この問題を修正するには、以下のコードのように、空要素を明示的にカウントする必要があります。

list(REMOVE_DUPLICATES my_list my_list_without_duplicates)
list(LENGTH my_list_without_duplicates list_length)
  • ポリシーは、特定の CMake モジュールまたはプロジェクトのみに適用できます。
  • ポリシーは、CMake の設定ファイル (CMakeLists.txt) で設定できます。
  • ポリシーは、CMake のバージョンによって導入時期が異なります。


list コマンドと空要素の扱い

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

project(myproject)

# 旧動作
list(LENGTH my_list_old 3)
list(APPEND my_list_old ;;)
message("旧動作: リストの長さは ${my_list_old} です。")

# 新動作
cmake_policy(SET CMP0007 NEW)
list(LENGTH my_list_new 3)
list(APPEND my_list_new ;;)
message("新動作: リストの長さは ${my_list_new} です。")

出力

旧動作: リストの長さは 3 です。
新動作: リストの長さは 4 です。

空要素を明示的に処理する

この例では、空要素を明示的に処理して、リストの長さを取得する方法を示します。

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

project(myproject)

list(LENGTH my_list 3)
list(APPEND my_list ;;)

# 空要素を削除
list(REMOVE_DUPLICATES my_list my_list_without_duplicates)

# リストの長さを取得
list(LENGTH my_list_without_duplicates list_length)
message("リストの長さは ${list_length} です。")

出力

リストの長さは 3 です。

この例では、cmake_policy コマンドを使用してポリシーを設定し、list コマンドの動作を変更する方法を示します。

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

project(myproject)

# 新動作を設定
cmake_policy(SET CMP0007 NEW)

# リストを作成
list(LENGTH my_list 3)
list(APPEND my_list ;;)

# リストの長さを取得
list(LENGTH my_list list_length)
message("リストの長さは ${list_length} です。")
リストの長さは 4 です。


CMake ポリシー "CMP0007" は、list コマンドがリスト内の空要素をどのように扱うかを制御します。このポリシーは、CMake 3.13 で導入されました。

代替方法

"CMP0007" には、以下の代替方法があります。

  1. CMake のバージョンを確認
    使用している CMake のバージョンが 3.13 より古い場合は、"CMP0007" ポリシーが適用されないため、代替方法を検討する必要はありません。
  2. ポリシーを設定
    CMake 3.13 以降を使用している場合は、cmake_policy コマンドを使用してポリシーを設定できます。
cmake_policy(SET CMP0007 OLD)
  1. コードを修正
    空要素を明示的に処理するようにコードを修正します。

代替方法の詳細

代替方法長所短所
CMake のバージョンを確認最も簡単CMake 3.13 以降を使用する必要がある
ポリシーを設定特定のプロジェクトまたはCMake モジュールにのみ適用できるコードの変更が必要ない
コードを修正将来の CMake バージョンで動作する最も複雑

推奨事項

どの代替方法を選択するかは、状況によって異なります。

  • 新しいプロジェクトの場合は、CMake 3.13 以降 を使用することをお勧めします。
  • 既存のプロジェクトで、CMake のバージョンを簡単にアップグレードできない場合は、ポリシーを設定 または コードを修正 することをお勧めします。

上記以外にも、以下の代替方法が考えられます。

  • Boost.Qary などのライブラリを使用する
  • カスタム リスト処理関数を作成する