Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get CMake to pass either std=c++14/c++1y or c++17/c++1z based on GCC version?

People also ask

Does CMake use GCC or G ++?

Usually under Linux, one uses CMake to generate a GNU make file which then uses gcc or g++ to compile the source file and to create the executable.

How do I specify C++ version of CMake?

The CMake global property CMAKE_CXX_KNOWN_FEATURES lists the C++ features you can choose from. Instead of using target_compile_features() you can also specify the C++ standard explicitly by setting the CMake properties CXX_STANDARD and CXX_STANDARD_REQUIRED for your CMake target.

Is CMake a GCC?

CMake generates files for other build systems. These can be Makefiles, Ninja files or projects files for IDEs like Visual Studio or Eclipse. The build files contain calls to compilers like GCC, Clang, or cl.exe. If you have several compilers installed, you can choose one.

Is CMake used for C?

In the C/C++ ecosystem, the best tool for project configuration is CMake. CMake allows you to specify the build of a project, in files named CMakeLists. txt, with a simple syntax (much simpler than writing Makefiles).


When wanting to specify a particular C++ version, the recommended way to do this with CMake 3.1 and later is to use the CXX_STANDARD, CXX_STANDARD_REQUIRED and CXX_EXTENSIONS target properties, or their variable equivalents to specify target defaults. Full details can be found here, but the short version goes something like this:

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 should then select the appropriate compiler flag for the requested C++ standard based on what the compiler supports, or error out if it doesn't support the requested standard.

It should also be noted that CMake may upgrade the target to use a later language standard than the one specified by its CXX_STANDARD target property. The use of compile feature requirements (as mentioned in @FlorianWolters answer) can raise the language standard requirement. In fact, CMake will always pick the stronger language requirement specified by either the CXX_STANDARD target property or the compile feature requirements set on the target. Note also that the CMake documentation as of 3.10.1 does not accurately reflect the way CXX_EXTENSIONS interacts with compile features, as CXX_EXTENSIONS only takes effect if CXX_STANDARD is also specified for most common compilers (since they are specified together with the one compiler flag).


Modern CMake code should use the target_compile_features command to request a specific C++ standard. This can be specified as build requirement only (PRIVATE), usage requirement only (INTERFACE) or build and usage requirement (PUBLIC).

Example:

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)

Refer to the section Requiring Language Standards in the official CMake documentation for cmake-compile-features to learn more.


Check if the compiler supports the flags? Perhaps something like

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()