我使用VS 15.3,它支持集成的CMake 3.8。如何在不为每个特定编译器编写标志的情况下定位C ++ 17?我目前的全球设置不起作用:
# https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# expected behaviour
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++lastest")
我希望CMake添加" / std:c ++最新"或等效生成VS解决方案文件,但未找到c ++ 17标志,导致编译器错误:
C1189 #error: class template optional is only available with C++17.
答案 0 :(得分:22)
对于没有标准级别概念的编译器,例如MSVC,这没有任何效果。
简而言之,CMake尚未更新以适应VC ++ 2017中添加的标准标志。
您必须检测是否使用了VC ++ 2017(或更高版本)并立即自行添加相应的标记。
在CMake 3.10(及更高版本)中,已针对较新版本的VC ++修复此问题。请参阅the 3.10 documentation。
答案 1 :(得分:10)
在现代CMake中,我发现最好在目标级别而不是全局变量级别分配CXX标准,并使用内置属性(在此处看到:https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html)来保持编译器不可知。
例如:
set_target_properties(FooTarget PROPERTIES
CXX_STANDARD 17
CXX_EXTENSIONS OFF
etc..
)
答案 2 :(得分:9)
您可以将set(CMAKE_CXX_STANDARD 17)
保留给其他编译器,例如Clang和GCC。但是对于Visual Studio来说,它是没用的。
如果CMake仍不支持此功能,您可以执行以下操作:
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
endif(MSVC)
答案 3 :(得分:2)
现代CMake为此target_compile_features
提出了一个接口。
文档在这里:Requiring Language Standards
像这样使用它:
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
答案 4 :(得分:2)
使用vs2019
set(CMAKE_CXX_STANDARD 17)
答案 5 :(得分:0)
您还可以使用target_compile_options
为Visual Studio 2019设置/std:c++latest
标志
if (MSVC_VERSION GREATER_EQUAL "1900")
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("/std:c++latest" _cpp_latest_flag_supported)
if (_cpp_latest_flag_supported)
target_compile_options(${TARGET_NAME} PRIVATE "/std:c++latest")
endif()
endif()
用实际的目标名称替换${TARGET_NAME}
。
答案 6 :(得分:0)
根据我的测试,下面的代码会让VS2019选择/std:c++latest,否则其他平台会设置C++版本为C++17。我已经用 emscripten、raspian 和 windows 对此进行了测试。
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest")
else(MSVC)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
endif(MSVC)