CMake: CMake 3.20以降で「CMAKE_CXX_COMPILER_ID」を使用する


CMAKE_COMPILER_IS_GNUCXX は CMake 変数の 1 つで、使用されている C++ コンパイラが GNU コンパイラかどうかを判定します。この変数は CMake 3.7 以降で導入されましたが、CMake 3.20 以降では非推奨 となり、代わりに CMAKE_CXX_COMPILER_ID 変数を使用することが推奨されています。

動作

CMAKE_COMPILER_IS_GNUCXX 変数は、以下の条件を満たす場合に TRUE に設定されます。

  • 使用されている C++ コンパイラが Clang であり、-gcc-toolchain オプションが指定されている
  • 使用されている C++ コンパイラが GNU GCC 4.0 以降である

上記以外のコンパイラが使用されている場合は、FALSE に設定されます。

非推奨化の理由

CMAKE_COMPILER_IS_GNUCXX 変数は、コンパイラのバージョンやオプションによって誤った結果を返す可能性があるため、非推奨化されました。代わりに、CMAKE_CXX_COMPILER_ID 変数を使用することで、より正確なコンパイラ識別が可能となります。

代替手段

CMAKE_COMPILER_IS_GNUCXX 変数の代わりに、以下の方法でコンパイラの種類を判定することができます。

  • コンパイラ情報コマンドを使用する: コンパイラ情報コマンドを実行して、コンパイラのバージョンやベンダーなどの情報を確認することができます。
  • CMAKE_CROSSCOMPILING 変数を使用する: この変数は、クロスコンパイルが行われているかどうかを判定します。クロスコンパイルが行われている場合は、コンパイラが GNU コンパイラである可能性が高いです。
  • CMAKE_CXX_COMPILER_ID 変数を使用する: この変数は、使用されている C++ コンパイラの ID を格納します。ID は、コンパイラのバージョンやベンダーによって異なります。

以下の例は、CMAKE_CXX_COMPILER_ID 変数を使用してコンパイラの種類を判定する方法を示しています。

if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  message(STATUS "Using GNU C++ compiler")
else()
  message(STATUS "Using non-GNU C++ compiler")
endif()
  • 複雑な CMake スクリプトを作成する場合は、CMake の専門家に相談することをお勧めします。
  • CMake のバージョンによって、変数やコマンドの動作が異なる場合があります。最新のドキュメントを参照することをお勧めします。


cmake_minimum_required(VERSION 3.7)
project(myproject)

message(STATUS "Using CMake version: ${CMAKE_VERSION}")

if(CMAKE_COMPILER_IS_GNUCXX)
  message(STATUS "Using GNU C++ compiler")
else()
  message(STATUS "Using non-GNU C++ compiler")
endif()

説明

  1. cmake_minimum_required コマンドで、必要な CMake の最小バージョンを指定します。この例では、CMake 3.7 以降が必要となります。
  2. project コマンドで、プロジェクトの名前を指定します。この例では、プロジェクト名は myproject です。
  3. message コマンドで、ステータスメッセージを出力します。この例では、CMake のバージョン情報を出力します。
  4. if ステートメントを使用して、CMAKE_COMPILER_IS_GNUCXX 変数の値を判定します。
  5. if ステートメントの then ブロックでは、使用されている C++ コンパイラが GNU コンパイラである場合のメッセージを出力します。
  6. if ステートメントの else ブロックでは、使用されている C++ コンパイラが GNU コンパイラではない場合のメッセージを出力します。

注意事項

  • CMAKE_COMPILER_IS_GNUCXX 変数は、CMake 3.20 以降では非推奨 となっています。代わりに、CMAKE_CXX_COMPILER_ID 変数を使用することを推奨します。
  • このコードは、CMake 3.7 以降でのみ動作します。

代替コード

以下のコードは、CMAKE_CXX_COMPILER_ID 変数を使用して、コンパイラの種類を判定し、その結果に応じてメッセージを出力するものです。

cmake_minimum_required(VERSION 3.20)
project(myproject)

message(STATUS "Using CMake version: ${CMAKE_VERSION}")

if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  message(STATUS "Using GNU C++ compiler")
else()
  message(STATUS "Using non-GNU C++ compiler")
endif()
  • if ステートメントの条件式が変更されています。CMAKE_CXX_COMPILER_ID 変数が "GNU" 文字列と一致するかどうかを判定します。
  • CMAKE_COMPILER_IS_GNUCXX 変数ではなく、CMAKE_CXX_COMPILER_ID 変数を使用しています。
  • CMake の詳細については、公式ドキュメントを参照することをお勧めします。


CMAKE_CXX_COMPILER_ID 変数を使用する

cmake_minimum_required(VERSION 3.20)
project(myproject)

message(STATUS "Using CMake version: ${CMAKE_VERSION}")

if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  message(STATUS "Using GNU C++ compiler")
else()
  message(STATUS "Using non-GNU C++ compiler")
endif()

上記の例では、CMAKE_CXX_COMPILER_ID 変数が "GNU" 文字列と一致するかどうかを判定します。一致すれば、使用されているコンパイラが GNU コンパイラであると判断されます。

コンパイラ情報コマンドを使用する

cmake_minimum_required(VERSION 3.0)
project(myproject)

message(STATUS "Using CMake version: ${CMAKE_VERSION}")

execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE compiler_version)
message(STATUS "Compiler version: ${compiler_version}")

if(compiler_version MATCHES "GNU")
  message(STATUS "Using GNU C++ compiler")
else()
  message(STATUS "Using non-GNU C++ compiler")
endif()

上記の例では、CMAKE_CXX_COMPILER 変数に格納されているコンパイラを使用して --version コマンドを実行し、その出力を compiler_version 変数に保存します。その後、compiler_version 変数が "GNU" 文字列と一致するかどうかを判定します。

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

一般的には、CMAKE_CXX_COMPILER_ID 変数を使用する方法の方が推奨されます。これは、より簡潔で、コンパイラ情報コマンドを実行するよりも効率的だからです。

しかし、コンパイラ情報コマンドを使用する方法の方が、より詳細なコンパイラ情報を得られるという利点があります。また、CMAKE_CXX_COMPILER_ID 変数が適切に設定されていない古い CMake バージョンを使用している場合にも有効です。

上記以外にも、以下の方法でコンパイラの種類を判定することができます。

  • システムヘッダーファイルの存在を確認する: 特定のコンパイラのみで使用されるヘッダーファイルの存在を確認することで、コンパイラの種類を判定することができます。
  • CMAKE_CROSSCOMPILING 変数を使用する: この変数は、クロスコンパイルが行われているかどうかを判定します。クロスコンパイルが行われている場合は、コンパイラが GNU コンパイラである可能性が高いです。
  • 複雑な CMake スクリプトを作成する場合は、CMake の専門家に相談することをお勧めします。
  • 上記の方法は、CMake 3.20 以降でのみ動作します。