【初心者向け】CMakeでC++コンパイラフラグを検証する:CheckOBJCXXCompilerFlagモジュールの使い方


使い方

check_objcxx_compiler_flag(
  <flag>
  <resultVar>
  [<message>]
)
  • <message>: 検証に失敗した場合に表示するメッセージ (オプション)
  • <resultVar>: 検証結果を格納する変数
  • <flag>: 検証したいコンパイラフラグ
check_objcxx_compiler_flag(
  -std=c++11
  CXX11_SUPPORTED
  "C++11 フラグがサポートされていないようです。"
)

if(CXX11_SUPPORTED)
  message(STATUS "C++11 フラグがサポートされています。")
else()
  message(WARNING "C++11 フラグがサポートされていないため、C++11 標準ライブラリを使用できません。")
endif()
  • 検証結果は、CMake キャッシュに保存されます。そのため、一度検証したフラグは、次回の CMake 実行時に再検証されることなく、キャッシュから結果が読み込まれます。キャッシュを無効化するには、cmake --no-cache オプションを使用して CMake を実行する必要があります。
  • このモジュールは、C++ コンパイラだけでなく、Objective-C コンパイラにも使用できます。
  • CheckOBJCXXCompilerFlag モジュールは、CMake 3.29.3 以降で使用できます。


cmake_minimum_required(VERSION 3.29.3)

project(myproject)

check_objcxx_compiler_flag(
  -std=c++11
  CXX11_SUPPORTED
  "C++11 フラグがサポートされていないようです。"
)

if(CXX11_SUPPORTED)
  message(STATUS "C++11 フラグがサポートされています。")
else()
  message(WARNING "C++11 フラグがサポートされていないため、C++11 標準ライブラリを使用できません。")
endif()

例 2: 複数のフラグを同時に検証する

cmake_minimum_required(VERSION 3.29.3)

project(myproject)

check_objcxx_compiler_flag(
  -std=c++11
  CXX11_SUPPORTED
  "C++11 フラグがサポートされていないようです。"
)

check_objcxx_compiler_flag(
  -Wall
  WARNINGS_ENABLED
  "警告フラグ -Wall がサポートされていないようです。"
)

if(CXX11_SUPPORTED AND WARNINGS_ENABLED)
  message(STATUS "C++11 フラグと警告フラグ -Wall がサポートされています。")
else()
  message(WARNING "C++11 フラグまたは警告フラグ -Wall がサポートされていないため、プロジェクトの設定を変更する必要があるかもしれません。")
endif()

例 3: 検証結果に基づいて条件分岐を行う

cmake_minimum_required(VERSION 3.29.3)

project(myproject)

check_objcxx_compiler_flag(
  -std=c++14
  CXX14_SUPPORTED
  "C++14 フラグがサポートされていないようです。"
)

if(CXX14_SUPPORTED)
  add_feature(MYPROJECT CXX14)
  set(CMAKE_CXX_STANDARD 14)
else()
  message(WARNING "C++14 フラグがサポートされていないため、プロジェクトの設定を変更する必要があるかもしれません。")
endif()
cmake_minimum_required(VERSION 3.29.3)

project(myproject)

check_objcxx_compiler_flag(
  -Wno-unused-variable
  UNUSED_VAR_WARNING_DISABLED
  "未使用変数警告フラグ -Wno-unused-variable がサポートされていないようです。"
)

if(UNUSED_VAR_WARNING_DISABLED)
  message(STATUS "未使用変数警告フラグ -Wno-unused-variable が無効化されています。")
else()
  message(WARNING "未使用変数警告フラグ -Wno-unused-variable がサポートされていないため、プロジェクトの設定を変更する必要があるかもしれません。")
endif()


CMake 内蔵の変数を使用する

  • CMake には、コンパイラに関する情報を含むいくつかの内蔵変数が用意されています。これらの変数を使用して、フラグがサポートされているかどうかを判断することができます。


cmake_minimum_required(VERSION 3.20)

project(myproject)

if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  set(CXX_COMPILER_GNU TRUE)
endif()

if(CXX_COMPILER_GNU)
  message(STATUS "GNU コンパイラが使用されています。")
else()
  message(STATUS "GNU コンパイラが使用されていません。")
endif()

カスタム CMake モジュールを作成する

  • 独自のロジックを使用してフラグがサポートされているかどうかを判断したい場合は、カスタム CMake モジュールを作成することができます。


cmake_minimum_required(VERSION 3.20)

project(myproject)

function(check_objcxx_compiler_flag_custom FLAG RESULT_VAR MESSAGE)
  set(CMAKE_TRY_COMPILE_ARGS ${FLAG})
  set(CMAKE_TRY_COMPILE_LINK_OBJECTS "")
  set(CMAKE_TRY_COMPILE_TARGET compile_test)

  try_compile(COMPILE_RESULT)

  if(COMPILE_RESULT)
    set(${RESULT_VAR} TRUE)
  else()
    set(${RESULT_VAR} FALSE)
    message(STATUS "${MESSAGE}")
  endif()
endfunction()

check_objcxx_compiler_flag_custom(
  -std=c++11
  CXX11_SUPPORTED
  "C++11 フラグがサポートされていないようです。"
)

if(CXX11_SUPPORTED)
  message(STATUS "C++11 フラグがサポートされています。")
else()
  message(WARNING "C++11 フラグがサポートされていないため、プロジェクトの設定を変更する必要があるかもしれません。")
endif()

外部ツールを使用する

  • コンパイラフラグのサポート状況を検証するための外部ツールを使用することもできます。


# clang++ が -std=c++11 フラグを受け入れるかどうかを確認する
clang++ -std=c++11 -c test.cpp 2>&1 | grep -q "error"
方法利点欠点
CheckOBJCXXCompilerFlag モジュールシンプルで使いやすいCMake 3.29.3 以降でのみ使用可能
CMake 内蔵変数シンプルで軽量すべてのコンパイラでサポートされているわけではない
カスタム CMake モジュール柔軟性が高い開発と保守の手間がかかる
外部ツール汎用性が高い設定が複雑になる可能性がある