プログラミング初心者でも安心!CMakeポリシー CMP0044 でコンパイラを理解


CMakeポリシー CMP0044 は、CMake 3.30.0-rc3 以降で導入されたポリシーであり、コンパイラIDの比較方法を制御します。このポリシーは、大文字小文字を区別するか区別しないかを決定します。

旧動作

このポリシーが導入される以前は、CMakeは <LANG>_COMPILER_ID 変数に格納された値と比較する際に、常に大文字小文字を区別しない比較を行っていました。

新動作

CMP0044 ポリシーが有効な場合、CMakeは <LANG>_COMPILER_ID 変数に格納された値と比較する際に、大文字小文字を区別するようになります。

影響を受ける場面

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

  • コンパイラ固有のフラグを設定する
  • 特定のコンパイラがインストールされているかどうかを確認する
  • ターゲットプロパティ COMPILE_LANGUAGE の値に基づいてコンパイラを選択する

ポリシーの設定方法

このポリシーは、CMakeLists.txt ファイル内で以下のいずれかの方法で設定できます。

CMakeLists.txt ファイル内での設定

cmake_minimum_required(VERSION 3.30)

cmake_policy(CMP0044 NEW)

プロジェクトレベルでの設定

set(CMAKE_POLICY_CMP0044 NEW)

注意事項

  • このポリシーは、CMake 3.30.0-rc3 以降でのみ使用できます。
  • このポリシーを OLD に設定すると、旧動作に戻ります。

以下の例は、CMP0044 ポリシーを使用して、GCC コンパイラがインストールされているかどうかを確認する方法を示しています。

cmake_minimum_required(VERSION 3.30)

cmake_policy(CMP0044 NEW)

if(CMAKE_COMPILER_IS_GNUC)
  message(STATUS "GCC compiler is installed")
else()
  message(STATUS "GCC compiler is not installed")
endif()


例1: GCC コンパイラがインストールされているかどうかを確認する

cmake_minimum_required(VERSION 3.30)

cmake_policy(CMP0044 NEW)

if(CMAKE_COMPILER_IS_GNUC)
  message(STATUS "GCC compiler is installed")
else()
  message(STATUS "GCC compiler is not installed")
endif()

例2: 特定のコンパイラバージョンを使用しているかどうかを確認する

cmake_minimum_required(VERSION 3.30)

cmake_policy(CMP0044 NEW)

if(CMAKE_COMPILER_VERSION VERSION_GREATER 8.0)
  message(STATUS "Using GCC compiler version 8.0 or higher")
else()
  message(STATUS "Using GCC compiler version lower than 8.0")
endif()

例3: コンパイラ固有のフラグを設定する

cmake_minimum_required(VERSION 3.30)

cmake_policy(CMP0044 NEW)

if(CMAKE_COMPILER_IS_GNUC)
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
endif()

説明

  • CMAKE_C_FLAGSCMAKE_CXX_FLAGS 変数は、C/C++ コンパイラ用のフラグを定義します。
  • CMAKE_COMPILER_VERSION 変数は、現在のコンパイラのバージョンを格納します。
  • CMAKE_COMPILER_IS_GNUC マクロは、現在のコンパイラが GCC であるかどうかを確認します。
  • cmake_policy コマンドは、CMake ポリシーを設定します。
  • cmake_minimum_required コマンドは、CMake の最小バージョンを指定します。
  • 上記のコードは、CMakeポリシー CMP0044 を有効にして、コンパイラの識別と設定を行います。
  • CMakeポリシー CMP0044 は、CMake 3.30.0-rc3 以降でのみ使用できます。


文字列比較を使用する

CMP0044 の代わりに、<LANG>_COMPILER_ID 変数に格納された値と比較する際に、文字列比較を使用することができます。

if(STRING_EQUAL <LANG>_COMPILER_ID "GCC")
  # GCC コンパイラを使用している
else()
  # GCC コンパイラを使用していない
endif()

ターゲットプロパティを使用する

CMP0044 の代わりに、ターゲットプロパティを使用してコンパイラを識別することができます。

target_properties(my_target COMPILE_LANGUAGE CXX)

if(CMAKE_CXX_COMPILER_ID MATCHES "GCC")
  # GCC コンパイラを使用している
else()
  # GCC コンパイラを使用していない
endif()

外部スクリプトを使用する

CMP0044 の代わりに、外部スクリプトを使用してコンパイラを識別することができます。

execute_script(
  SOURCE check_compiler.sh
  OUTPUT_VARIABLE compiler_id
)

if(compiler_id STREQUAL "GCC")
  # GCC コンパイラを使用している
else()
  # GCC コンパイラを使用していない
endif()

それぞれの方法の利点と欠点

  • 外部スクリプト
    柔軟性がありますが、設定とメンテナンスがより複雑になります。
  • ターゲットプロパティ
    より安全で信頼性の高い方法ですが、CMakeLists.txt ファイルが複雑になる可能性があります。
  • 文字列比較
    シンプルで分かりやすいですが、大文字小文字の区別を考慮しないため、誤った結果になる可能性があります。

最適な方法の選択

最適な方法は、プロジェクトの要件と開発者の好みによって異なります。

  • 柔軟性が求められる場合は、外部スクリプトを使用します。
  • より安全で信頼性の高い方法が必要な場合は、ターゲットプロパティを使用します。
  • シンプルで分かりやすい方法が必要な場合は、文字列比較を使用します。
  • CMake のバージョンによって、使用可能なポリシーと機能が異なる場合があります。
  • プロジェクトで複数のコンパイラを使用する場合は、条件分岐を使用して各コンパイラに対応する必要があります。

CMakeポリシー CMP0044 は便利な機能ですが、状況によっては代替方法の方が適切な場合があります。それぞれの方法の利点と欠点を理解し、プロジェクトの要件に合った方法を選択することが重要です。