如何让CMake基于GCC版本传递std = c ++ 14 / c ++ 1y或c ++ 17 / c ++ 1z?

时间:2017-03-16 13:00:31

标签: c++ cmake c++14 gcc4

GCC 4.x不接受C ++ 14代码的--std=c++14开关 - 它需要--std=c++1y。以后的版本需要--std=c++1z但是(可能)还没有--std=c++17尚未设置(2016年写这个)。也许C ++ 11也有类似的问题。

CMake是否有一些设施(可能作为模块)根据GCC版本传递正确的开关?

3 个答案:

答案 0 :(得分:66)

当想要指定特定的C ++版本时,使用CMake 3.1及更高版本执行此操作的推荐方法是使用CXX_STANDARDCXX_STANDARD_REQUIREDCXX_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目标属性指定的语言更晚的语言标准。使用compile feature requirements(如@FlorianWolters答案中所述)可以提高语言标准要求。事实上,CMake将始终选择由CXX_STANDARD目标属性或目标上设置的编译功能要求指定的更强大的语言要求。另请注意,自3.10.1起的CMake文档未准确反映CXX_EXTENSIONS与编译功能交互的方式,因为CXX_EXTENSIONS仅在大多数常见编译器中指定CXX_STANDARD时才生效(因为它们与一个编译器标志一起指定。)

答案 1 :(得分:18)

现代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文档中的要求语言标准部分以了解详情。

答案 2 :(得分:9)

检查编译器是否支持这些标志?也许像是

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