I\'m using VS 15.3, which supports integrated CMake 3.8. How can I target C++17 without writing flags for each specific compilers? My current global settings don\'t work:
You can keep that set(CMAKE_CXX_STANDARD 17)
for other compilers, like Clang and GCC. But for Visual Studio, it's useless.
If CMake still doesn't support this, you can do the following:
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
endif(MSVC)
Your approach is the correct one, but it will not work for MSVC on versions of CMake prior to 3.10.
From the CMake 3.9 documentation:
For compilers that have no notion of a standard level, such as MSVC, this has no effect.
In short, CMake haven't been updated to accommodate for the standard flags added to VC++ 2017.
You have to detect if VC++ 2017 (or later) is used and add the corresponding flags yourself for now.
In CMake 3.10 (and later) this have been fixed for newer version of VC++. See the 3.10 documentation.
In modern CMake, I've found it best to assign CXX standards at the target level instead of global variable level and use the built in properties (seen here: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html) to keep it compiler agnostic.
For Example:
set_target_properties(FooTarget PROPERTIES
CXX_STANDARD 17
CXX_EXTENSIONS OFF
etc..
)
when using vs2019
set(CMAKE_CXX_STANDARD 17)
You can also use target_compile_options
to set /std:c++latest
flag for Visual Studio 2019
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()
Replace ${TARGET_NAME}
with the actual target name.
Modern CMake propose an interface for this purpose target_compile_features
.
Documentation is here: Requiring Language Standards
Use it like this:
target_compile_features(${TARGET_NAME} PRIVATE cxx_std_17)