CMake 3.17で導入された「CMP0100」ポリシーとヘッダーファイル処理


CMakeポリシー「CMP0100」は、CMake 3.17 以降で導入された、ヘッダーファイル処理に関する互換性設定です。このポリシーは、.hh 拡張子を持つヘッダーファイルをどのように処理するかを制御します。

旧動作と新動作

CMake 3.17 以前では、.hh 拡張子のヘッダーファイルは、自動生成ヘッダーファイルとみなされ、特別な処理を受けませんでした。しかし、CMake 3.17 以降では、これらのファイルも通常のヘッダーファイルとして処理されるようになりました。

CMP0100の設定

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

  • 設定なし: CMakeは警告を発し、旧動作を使用します。(非推奨)
  • cmake_policy(SET CMP0100 OLD): 旧動作を維持します。
  • cmake_policy(SET CMP0100 NEW): 新しい動作を有効にします。

影響を受けるプロジェクト

このポリシーは、.hh 拡張子のヘッダーファイルを明示的にインクルードするプロジェクトに影響を与えます。そのようなプロジェクトでは、以下のいずれかの対応が必要です。

  • ヘッダーファイルの名前を .h に変更する。
  • .hh 拡張子のヘッダーファイルを #include する前に、#pragma once ディレクティブを追加する。
  • cmake_policy(SET CMP0100 NEW) を設定して、新しい動作を許可する。
cmake_minimum_required(VERSION 3.17)

project(myproject)

# 新しい動作を有効にする
cmake_policy(SET CMP0100 NEW)

# myproject.hh をヘッダーファイルとしてインクルード
add_executable(myprogram myprogram.cpp)
target_link_libraries(myprogram myproject)
  • プロジェクトで #include するヘッダーファイルの拡張子を統一することをお勧めします。
  • CMP0100 は、互換性を維持するために導入されたポリシーです。将来的には削除される可能性があります。


cmake_minimum_required(VERSION 3.17)

project(myproject)

# 新しい動作を有効にする
cmake_policy(SET CMP0100 NEW)

# myproject.hh をヘッダーファイルとしてインクルード
add_executable(myprogram myprogram.cpp)
target_link_libraries(myprogram myproject)

説明

この例では、cmake_policy(SET CMP0100 NEW) を使用して新しい動作を有効にし、myproject.hh 拡張子のヘッダーファイルを #include します。CMake 3.17 以降では、このヘッダーファイルは自動生成ヘッダーファイルではなく、通常のヘッダーファイルとして処理されます。

例2: ヘッダーファイルに #pragma once ディレクティブを追加する

cmake_minimum_required(VERSION 3.14)

project(myproject)

# ヘッダーファイルに #pragma once ディレクティブを追加
add_custom_command(COMMAND ${CMAKE_C_COMPILER} -E -P myproject.hh)

# myproject.hh をヘッダーファイルとしてインクルード
add_executable(myprogram myprogram.cpp)
target_link_libraries(myprogram myproject)

説明

この例では、myproject.hh 拡張子のヘッダーファイルに #pragma once ディレクティブを追加するカスタムコマンドを作成します。このディレクティブは、ヘッダーファイルが複数回インクルードされた場合でも、一度だけ処理されるようにします。

例3: ヘッダーファイルの名前を変更する

cmake_minimum_required(VERSION 3.14)

project(myproject)

# ヘッダーファイルの名前を .h に変更
rename_source_file(myproject.hh myproject.h)

# myproject.h をヘッダーファイルとしてインクルード
add_executable(myprogram myprogram.cpp)
target_link_libraries(myprogram myproject)

説明

この例では、rename_source_file コマンドを使用して、myproject.hh 拡張子のヘッダーファイル名を myproject.h に変更します。これにより、CMakeはヘッダーファイルを自動生成ヘッダーファイルとしてではなく、通常のヘッダーファイルとして処理します。

  • 詳細については、CMake ドキュメントを参照してください。
  • 上記の例はあくまで一例であり、プロジェクトの状況に応じて適切な方法を選択する必要があります。


ヘッダーファイルの拡張子を .h に変更する

最も簡単な方法は、.hh 拡張子のヘッダーファイル名を .h に変更することです。これにより、CMakeはファイルを自動生成ヘッダーファイルではなく、通常のヘッダーファイルとして処理します。

# 変更前
myproject.hh

# 変更後
myproject.h

#pragma once ディレクティブを使用する

#pragma once ディレクティブをヘッダーファイルに追加することで、ヘッダーファイルが複数回インクルードされた場合でも一度だけ処理されるようにすることができます。

#pragma once

// ヘッダーファイルの内容

SKIP_AUTOMOC または SKIP_AUTOUIC プロパティを使用する

CMake 3.17 以降では、SKIP_AUTOMOC または SKIP_AUTOUIC プロパティを使用して、特定のソースファイルを AUTOMOC または AUTOUIC 処理から除外することができます。

set_source_properties(myproject.hh SKIP_AUTOMOC)

カスタムヘッダーファイルインクルードパスを設定する

CMake 3.15 以降では、CMAKE_INCLUDE_DIRECTORIES キャッシュ変数を使用して、カスタムヘッダーファイルインクルードパスを設定することができます。これにより、CMakeは .hh 拡張子のファイルを自動的に検索する代わりに、これらのパスを検索します。

set(CMAKE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/include)

サードパーティのビルドシステムを使用する

CMake以外のビルドシステムを使用する場合は、そのシステムのヘッダーファイル処理に関する独自の規則に従うことができます。

最適な方法の選択

最適な方法は、プロジェクトの要件と状況によって異なります。

  • 高度な制御
    サードパーティのビルドシステムを使用する。
  • カスタムヘッダーファイルインクルードパスを指定
    CMAKE_INCLUDE_DIRECTORIES キャッシュ変数を使用する。
  • 特定のファイルの処理を制御
    SKIP_AUTOMOC または SKIP_AUTOUIC プロパティを使用する。
  • マルチインクルード防止
    ヘッダーファイルに #pragma once ディレクティブを追加する。
  • シンプルで移植性の高い方法
    ヘッダーファイルの拡張子を .h に変更する。