web-dev-qa-db-ja.com

GCCバージョンに基づいてstd = c ++ 14 / c ++ 1yまたはc ++ 17 / c ++ 1zを渡すようにCMakeを取得する方法は?

GCC 4.xは、C++ 14コードの--std=c++14スイッチを受け入れません-代わりに--std=c++1yを取ります。それ以降のバージョンは--std=c++1zを使用しますが、(おそらく)まだ設定されていない--std=c++17を使用しません(2016年にこれを記述)。 C++ 11にも同様の問題がある可能性があります。

CMakeには、GCCバージョンに応じて正しいスイッチを渡すための機能(おそらくモジュール)がありますか?

39
einpoklum

特定のC++バージョンを指定する場合、CMake 3.1以降でこれを行うための推奨される方法は、CXX_STANDARDCXX_STANDARD_REQUIRED、およびCXX_EXTENSIONSターゲットプロパティ、またはそれらの同等の変数を使用して指定することですターゲットのデフォルト。詳細は here にありますが、短いバージョンは次のようになります。

cmake_minimum_required(VERSION 3.1)
project(Example)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# ... Define targets, etc. as usual

CMakeは、コンパイラがサポートするものに基づいて、要求されたC++標準に適切なコンパイラフラグを選択するか、要求された標準をサポートしていない場合はエラーになります。

また、CMakeはCXX_STANDARDターゲットプロパティで指定された言語標準よりも新しい言語標準を使用するようにターゲットをアップグレードする場合があることに注意してください。 コンパイル機能要件 (@FlorianWoltersの回答で述べたように)を使用すると、言語の標準要件を上げることができます。実際、CMakeは、CXX_STANDARDターゲットプロパティまたはターゲットに設定されたコンパイル機能要件のいずれかで指定された、より強力な言語要件を常に選択します。 CXX_EXTENSIONSがほとんどの一般的なコンパイラに対して指定されている場合にのみCXX_EXTENSIONSが有効になるため、3.10.1のCMakeドキュメントはCXX_STANDARDがコンパイル機能と対話する方法を正確に反映していないことにも注意してください1つのコンパイラフラグと一緒に指定されているため)。

68
Craig Scott

最新のCMakeコードは target_compile_features コマンドを使用して特定のC++標準を要求する必要があります。これは、ビルド要件のみ(PRIVATE)、使用要件のみ(INTERFACE)、またはビルドと使用要件(PUBLIC)として指定できます。

例:

cmake_minimum_required(VERSION 3.9.4)

project(cpp-snippets)
add_executable(cpp-snippets "main.cpp")
target_compile_features(cpp-snippets PRIVATE cxx_std_17)

詳細については、 cmake-compile-features の公式CMakeドキュメントのセクションRequireing Language Standardsを参照してください。

22
Florian Wolters

コンパイラがフラグをサポートしているかどうかを確認しますか?おそらく次のようなもの

include(CheckCXXCompilerFlag)

# Check for standard to use
check_cxx_compiler_flag(-std=c++17 HAVE_FLAG_STD_CXX17)
if(HAVE_FLAG_STD_CXX17)
    # Have -std=c++17, use it
else()
    check_cxx_compiler_flag(-std=c++1z HAVE_FLAG_STD_CXX1Z)
    if(HAVE_FLAG_STD_CXX1Z)
        # Have -std=c++1z, use it
    else()
        # And so on and on...
    endif()
endif()