How to Enable /Std:C++17 in VS2017 with Cmake

How to enable /std:c++17 in VS2017 with CMake

Turning my comment into an answer

  1. The CMake team is working on it for VS2017 (as for July 2017, for upcoming CMake version 3.10):

    CMake: MSVC standard version switches

    Those flags seem to be rather new switches (as related to the date of this question):

    VS 2017 15.3 preview now supports /std:c++17

    So for Visual Studio you have to "manually" replace or append the compiler switches until CMake officially does support it.

    Here is a code snippet that I've tested for std:c++latest (which is already supported e.g. in my CMake 3.8.0 version):

    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. For CLang and GNU the support was merged into the main source code branch begin of 2017 and is part of CMake version 3.8 and above:

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

Enabling support for C++17 in CMake for Visual Studio

CMake versions higher than 3.10 support MSVC C++ standard switches, but on earlier versions they have no effect.

The only portable approach, to ensuring your program is compiled with the correct C++ standard mode on Visual Studio, is to require at least CMake 3.10, set the target property CXX_STANDARD to your desired value and CXX_STANDARD_REQUIRED to ON.

Example usage:

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

Note: Currently CXX_STANDARD documentation for CMake 3.10 incorrectly states that it has no effect on MSVC. There's an issue tracking this here.

How to enable C++17 compiling in Visual Studio?

There's now a drop down (at least since VS 2017.3.5) where you can specifically select C++17. The available options are (under project > Properties > C/C++ > Language > C++ Language Standard)

  • ISO C++14 Standard. msvc command line option: /std:c++14
  • ISO C++17 Standard. msvc command line option: /std:c++17

Visual Studio 2022 (MSVC C++20 and the /std:c++20 Switch - C++ Team Blog):

  • ISO C++20 Standard. msvc command line option: /std:c++20

Any Visual Studio:

  • The latest draft standard. msvc command line option: /std:c++latest

Compiling C++17 using CLion, CMake and the VS2017 compiler

The CMAKE_CXX_STANDARD variable is used to initialize the CXX_STANDARD property.

From the property documentation:

For compilers that have no notion of a standard level, such as MSVC,
this has no effect.

For Visual Studio 2017 with plain CMake, the canonical way for C++17 (the default is C++14) is:

target_compile_options(optional2 PRIVATE /std:c++latest)

How to enable C++17 code generation in VS2019 CUDA project

Using CUDA 11, the nvcc compiler-driver is capable of supporting usage of certain C++17 language features. Currently, in VS2019, this doesn't appear to be the default behavior.

The following method should work to enable C++17 support when compiling a cuda project in VS2019:

go to Project..Properties..Configuration Properties...CUDA C/C++...Command Line Then you will see a box in the right hand side bottom of the dialog labelled "Additional Options". In that box, type the following:

-std=c++17 -Xcompiler "/std:c++17"

then click "Apply" then rebuild.
Project Properties

(These instructions may change for future versions of CUDA or future versions of Visual Studio.)

Note that this method applies to CUDA projects only (i.e. when nvcc is invoked for compilation), and should be workable whether your code is in a file ending in .cpp or in a file ending in .cu. For non-CUDA projects, this may be helpful.

The std::filesystem features appear to require C++17. The CUDA nvcc compiler-driver is documented here.

How to set compiler options with CMake in Visual Studio 2017

The default settings for the compiler are picked up from standard module files located in the Modules directory of the CMake installation. The actual module file used depends on both the platform and the compiler. E.g., for Visual Studio 2017, CMake will load the default settings from the file Windows-MSVC.cmake and language specific settings from Windows-MSVC-C.cmake or Windows-MSVC-CXX.cmake.

To inspect the default settings, create a file CompilerOptions.cmake in the project directory with the following contents:

# log all *_INIT variables
get_cmake_property(_varNames VARIABLES)
list (REMOVE_DUPLICATES _varNames)
list (SORT _varNames)
foreach (_varName ${_varNames})
if (_varName MATCHES "_INIT$")
message(STATUS "${_varName}=${${_varName}}")
endif()
endforeach()

Then initialize the CMAKE_USER_MAKE_RULES_OVERRIDE variable in your CMakeLists.txt:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
set (CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_CURRENT_LIST_DIR}/CompilerOptions.cmake")
project(foo)
add_executable(foo foo.cpp)

When the project is configured upon opening the directory using Open Folder in Visual Studio 2017, the following information will be shown in the IDE's output window:

 ...
-- CMAKE_CXX_FLAGS_DEBUG_INIT= /MDd /Zi /Ob0 /Od /RTC1
-- CMAKE_CXX_FLAGS_INIT= /DWIN32 /D_WINDOWS /W3 /GR /EHsc
-- CMAKE_CXX_FLAGS_MINSIZEREL_INIT= /MD /O1 /Ob1 /DNDEBUG
-- CMAKE_CXX_FLAGS_RELEASE_INIT= /MD /O2 /Ob2 /DNDEBUG
-- CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT= /MD /Zi /O2 /Ob1 /DNDEBUG
...

So the warning setting /W3 is picked up from the CMake variable CMAKE_CXX_FLAGS_INIT which then applies to all CMake targets generated in the project.

To control the warning level on the CMake project or target level, one can alter the CMAKE_CXX_FLAGS_INIT variable in the CompilerOptions.cmake by adding the following lines to the file:

if (MSVC)
# remove default warning level from CMAKE_CXX_FLAGS_INIT
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT}")
endif()

The warning flags can then be controlled by setting the target compile options in CMakeLists.txt:

...
add_executable(foo foo.cpp)
target_compile_options(foo PRIVATE "/W4")

For most CMake projects it makes sense to control the default compiler options in a rules override file instead of manually tweaking variables like CMAKE_CXX_FLAGS.

When making changes to the CompilerOptions.cmake file, it is necessary to recreate the build folder. When using Visual Studio 2017 in Open Folder mode, choose the command Cache ... -> Delete Cache Folders from the CMake menu and then Cache ... -> Generate from the CMake menu to recreate the build folder.

How to change all projects in a solution file to C++17 MSVC?

Looks like you have to change this for each subproject. Alternatively just run cmake -DCMAKE_CXX_STANDARD=17 -S /path/to/external/project -B bld (for example) and CMake will generate the projects with the desired standard (unless overridden by CMakeLists.txt).



Related Topics



Leave a reply



Submit