2017-07-07 40 views
14

我正尝试使用CMake将/std:c++17编译器标志添加到VS2017。我使用的是“现代”的跨平台的方式至今:如何使用CMake在VS2017中启用/ std:C++ 17

set(CMAKE_CXX_STANDARD 14) 
set(CMAKE_CXX_STANDARD_REQUIRED ON) 
set(CMAKE_CXX_EXTENSIONS OFF) # -std=c++11 instead of -std=gnu++11 
set(MY_CXX_COMPILE_FEATURES cxx_generic_lambdas cxx_range_for cxx_strong_enums) 

add_library(mylib INTERFACE) 
target_compile_features(mylib INTERFACE ${MY_CXX_COMPILE_FEATURES}) 

这增加了在VS2017 /std:c++14(这可能是默认的呢?)。 但是,我无法将其切换到C++ 17(即添加了/std:c++17)。如果我只是手动添加它,我得到的不是那么好的警告,因为这两个标志存在:

1>cl : Command line warning D9025: overriding '/std:c++14' with '/std:c++17'

我试过set(CMAKE_CXX_STANDARD 17),但它没有任何效果,实际上的CMake文档中提到CMAKE_CXX_STANDARD对VS无影响。至于为C++ 17添加C++ 17功能到target_compile_features,看起来好像还没有(甚至在CMake-3.9.0-rc5中),即使有,我特别只使用std::optional来自C++ 17,并且没有target_compile_features标志用于库功能,如std::optional

所以我的问题是,什么是最好(或最不丑)的方式来做到这一点与CMake?在某种程度上,它也适用于gcc和clang?我很高兴使用最新的CMake版本(3.8或3.9)。我更喜欢它是“很好”,而不是通过CXX_COMPILE_FLAGS手动循环,并删除字符串“/ std:C++ 14”或一些像这样的黑客。

编辑:它也可以是VS /std:c++latest开关 - 无论是可能的用途这两种工作。)

+0

见https://gitlab.kitware.com/cmake/cmake/issues/16482,这是工作正在进行中。 – Florian

+0

更新:'CMAKE_CXX_STANDARD 17'现在可以在最新的CMake中使用,并将在CMake-3.10中着陆。 – Ela782

回答

15

谈到我的意见为答案

  1. CMake的团队正在为VS2017做准备(至2017年7月,即将推出的CMake版本3.10):

    CMake: MSVC standard version switches

    这些标志似乎是相当新的交换机(如涉及到这个问题的日期):

    VS 2017年15.3预览现在支持/ STD:C++ 17

    所以对于Visual Studio必须“手动”替换或附加编译器开关,直到CMake正式支持它。

    下面的代码片段,我已经为std:c++latest测试(这已经是我的CMake 3.8.0版本支持如):支持被合并到主

    if (MSVC_VERSION GREATER_EQUAL "1900") 
        include(CheckCXXCompilerFlag) 
        CHECK_CXX_COMPILER_FLAG("/std:c++latest" _cpp_latest_flag_supported) 
        if (_cpp_latest_flag_supported) 
         add_compile_options("/std:c++latest") 
        endif() 
    endif() 
    
  2. 对于铛和GNU的2017的源代码分支开始,并且是CMake的版本3.8和以上的部分:

    CMake: Features: Add support for C++ 17 language standard

+0

嗯!太糟糕了,没有登陆CMake,但问题是7个月大:-(标志并不是真的太新,VS2015已经拥有了它们)无论如何,鉴于我使用的是高于“现代”和基于目标的方法,手动替换/添加MSVC标志的最佳方法是什么? – Ela782

+0

我认为这将是一个头痛的问题。我不能'get_target_property(my_compile_flags mylib COMPILE_FLAGS)',因为它是一个INTERFACE目标(仅限标题库)... – Ela782

+0

我已经问了一个新的问题:https://stackoverflow.com/questions/44977868/cmake-replace-compile-flags-of-an-interface-target – Ela782

3

CMake的版本更高THA 3。适用于MSVC版本高于19.0.24215的10 support MSVC C++ standard switches。如果任一版本要求不符合,则它们不起作用。

唯一的移植性的方法,确保您的程序与正确的C++标准模式下的Visual Studio编译的,是要求至少CMake的3.10,目标属性CXX_STANDARD设置为你想要的值,并CXX_STANDARD_REQUIREDON

用法示例:

set_property(TARGET my_target PROPERTY CXX_STANDARD 17) 
set_property(TARGET my_target PROPERTY CXX_STANDARD_REQUIRED ON)