如何在CMake中启用C++ 17

MiP*_*MiP 38 c++ cmake visual-studio c++17

我正在使用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")
Run Code Online (Sandbox Code Playgroud)

我希望CMake在生成VS解决方案文件时添加"/ std:c ++ lastest"或等价物,但是没有找到c ++ 17标志,导致编译器错误:

C1189 #error: class template optional is only available with C++17.
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 31

CMake 3.9文档:

对于没有标准级别概念的编译器,例如MSVC,这没有任何效果.

简而言之,CMake尚未更新以适应VC++ 2017中添加的标准标志.

您必须检测是否使用了VC++ 2017(或更高版本)并自行添加相应的标志.


在CMake 3.10(及更高版本)中,这已针对较新版本的VC++进行了修复.请参阅3.10文档.

  • 较新的CMake 3.10(及更高版本)文档说它适用于Visual Studio 2015更新3或更新版本.仅支持2015 Update 3之前的Visual Studio版本.上面的链接实际上是最新文档,反映了这一点. (2认同)
  • 一个(可能)迂腐的评论:为了让 MSVC 表现得像一个符合标准的编译器,你还必须使用 `/Zc:__cplusplus` 标志,否则 `__cplusplus` 宏没有设置为正确的值。一个肯定迂腐的评论是,我认为这是 cmake 中的一个错误:当我要求 C++11、C+14、C++17 时,我希望 cmake 设置使编译器符合要求的 *all* 标志,并且包括 `__cplusplus` 宏的值。 (2认同)

lon*_*ver 12

在现代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..
            )
Run Code Online (Sandbox Code Playgroud)

  • 似乎每个 cmake 功能都会立即过时,并且互联网上充满了过时的问题和答案。 (9认同)
  • "现代"CMake究竟意味着什么? (3认同)

The*_*ist 8

您可以将其保留set(CMAKE_CXX_STANDARD 17)给其他编译器,例如Clang和GCC.但是对于Visual Studio来说,它毫无用处.

如果CMake仍不支持此功能,您可以执行以下操作:

if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
endif(MSVC)
Run Code Online (Sandbox Code Playgroud)

  • [最近的VS更改](https://docs.microsoft.com/zh-cn/cpp/what-s-new-for-visual-cpp-in-visual-studio)允许使用`/ std:c设置标准++ 14`,`/ std:c ++ 17`和`/ std:c ++ latest`标志。 (2认同)
  • 就我而言,情况恰恰相反。我正在使用 CMake 3.19.1、VS2019 和 gcc 7.5.0。`set(CMAKE_CXX_STANDARD 17)` 对于 VS2019 来说已经足够了,但是 gcc 需要 `target_compile_features(${TARGET_NAME} PRIVATE cxx_std_17)`。即使显式的 `add_compile_options("-std=gnu++17")` 也是不够的。 (2认同)

tes*_*060 7

使用时 vs2019

set(CMAKE_CXX_STANDARD 17)
Run Code Online (Sandbox Code Playgroud)


nbo*_*out 6

现代CMake为此提出了一个接口target_compile_features。文档在这里:要求语言标准

像这样使用它:

target_compile_features(${TARGET_NAME} PRIVATE cxx_std_17)

  • 在 CMake 中,“PUBLIC”(对于每个人)=“INTERFACE”(对于其他人)+“PRIVATE”(对于我) (4认同)
  • 所以为了清楚起见我改变了它。请随意恢复。 (2认同)
  • 我希望随着新语言功能的出现,接受的答案会自动更改......这是正确的答案。上面的这些都非常过时了。 (2认同)

Dan*_*li3 5

CMake 标志中的 Bash 命令行:

-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DCMAKE_CXX_EXTENSIONS=OFF \
Run Code Online (Sandbox Code Playgroud)