问题
GCC 4.x doesn't accept the --std=c++14
switch for C++14 code - it takes --std=c++1y
instead. Later versions take --std=c++1z
but (probably) not --std=c++17
which has not been set yet (writing this in 2016). Perhaps there are similar issues with C++11.
Does CMake have some facility (perhaps as a module) to pass the correct switch according to the GCC version?
回答1:
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).
回答2:
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.
回答3:
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()
来源:https://stackoverflow.com/questions/42834844/how-to-get-cmake-to-pass-either-std-c14-c1y-or-c17-c1z-based-on-gcc-vers