1. ホーム
  2. c++

[解決済み] CMake でコンパイラの C++11 サポートを検出する方法

2023-06-16 21:29:39

質問

コンパイラが C++11 をサポートしているかどうかを CMake が自動的に検出する方法はありますか?

CMake の実行中に、コンパイラが C++11 をサポートしていないためコードがコンパイルされないことをユーザーに知らせることができれば良いと思います。 現在、私は C++11 フラグを設定しています。しかし、コンパイラーがそれをサポートしていない場合、ユーザーは CMake 実行中にエラーではなく、コンパイル エラーを受け取ります。

完璧なのは、次のように動作するものです。 find_package() . しかし、私は必要な機能を提供するモジュールまたは関数を見つけられませんでした。

追加で、コンパイラがフラグを必要とするかどうかを検出する機能があるとよいでしょう。 std=c++0x とか std=c++11 .

何か利用できるものがあるのでしょうか、それとも自分で開発する必要があるのでしょうか。

以下は私がこれまでに使用したコードですが、これは GNU'c GCC コンパイラでのみ動作します。より一般的なソリューションがあるならば、それは素晴らしいことです。

if(CMAKE_COMPILER_IS_GNUCXX)
   execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
   if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
        message(STATUS "C++11 activated.")
        add_definitions("-std=gnu++11")
   elseif(GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
        message(WARNING "C++0x activated. If you get any errors update to a compiler which fully supports C++11")
        add_definitions("-std=gnu++0x")
   else ()
        message(FATAL_ERROR "C++11 needed. Therefore a gcc compiler with a version higher than 4.3 is needed.")   
   endif()
else(CMAKE_COMPILER_IS_GNUCXX)
   add_definitions("-std=c++0x") 
endif(CMAKE_COMPILER_IS_GNUCXX)

どのように解決するのですか?

CMake バージョン 3.1.0 以降では、どの C++ 機能がサポートされているかを検出することができます。 C++ コンパイラーがサポートしている

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
message("Your C++ compiler supports these C++ features:")
foreach(i ${CMAKE_CXX_COMPILE_FEATURES})
  message("${i}")
endforeach()

しかし、通常はCMakeの変数である cmake_cxx_compile_features をCMakeスクリプトで使用する必要はありません。その代わりに、どのC++規格の下でC++ファイルをコンパイルすべきかをCMakeに指示する方法が2つあります。 C++標準を明示的に指定するか、必要なC++機能を指定し、CMakeにC++標準を誘導させるかです。CMake は、C++ コンパイラーが正しいコマンドライン フラグ(例:-std=c++11)で呼び出されることを確認します。

1. C++ 標準を明示的に指定する

CMake のプロパティを設定することにより、C++ 標準を明示的に指定することができます。 CXX_STANDARD そして cxx_standard_required をCMakeターゲットに追加してください。

$ cat /tmp/src/CMakeLists.txt
project(foobar CXX)
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
add_executable(prog main.cc)
set_property(TARGET prog PROPERTY CXX_STANDARD 11)
set_property(TARGET prog PROPERTY CXX_STANDARD_REQUIRED ON)
$ cat /tmp/src/main.cc
int main() {
  return 0;
}
$ mkdir /tmp/build
$ cd /tmp/build
$ cmake /tmp/src
-- The CXX compiler identification is GNU 4.8.2
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build
$ make VERBOSE=1 | grep main.cc | grep -- "-c"
/usr/bin/c++    -std=gnu++11 -o CMakeFiles/prog.dir/main.cc.o -c /tmp/src/main.cc
$

2. 必要な C++ 機能を指定し、CMake に C++ 標準を誘導させる

CMakeコマンドを使用することができます。 ターゲット_コンパイル_フィーチャー で、CMake ターゲットで使用される C++ 機能を指定します。CMakeはこのリストから、使用するC++標準を決定します。CMakeのグローバルプロパティである cmake_cxx_known_features は、選択可能な C++ 機能をリストアップします。

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
message("Your CMake version supports these C++ features:")
get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
foreach(i ${known_features})
  message("${i}")
endforeach()

例えば、このC++プログラムでは、ファイル名が main.cc は、C++11の機能を利用しています。 cxx_strong_enums。 , cxx_constexpr , cxx_auto_type

#include <cstdlib>

int main(int argc, char *argv[]) {
  enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
  constexpr float a = 3.1415f;
  auto b = a;
  return EXIT_SUCCESS;
}

このCMakeLists.txtファイルは、これをビルドします。

cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)                                                                                                                                                                                                                                                     
set(needed_features
    cxx_strong_enums
    cxx_constexpr
    cxx_auto_type)
target_compile_features(foobar PRIVATE ${needed_features})