How to enable C++17 in CMake
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.
How to get CMake to pass either std=c++14/c++1y or c++17/c++1z based on GCC version?
When wanting to specify a particular C++ version, the recommended way to do this with CMake 3.1 and later is to use the CXX_STANDARD
, CXX_STANDARD_REQUIRED
and CXX_EXTENSIONS
target properties, or their variable equivalents to specify target defaults. Full details can be found here, but the short version goes something like this:
cmake_minimum_required(VERSION 3.1)
project(Example)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# ... Define targets, etc. as usual
CMake should then select the appropriate compiler flag for the requested C++ standard based on what the compiler supports, or error out if it doesn't support the requested standard.
It should also be noted that CMake may upgrade the target to use a later language standard than the one specified by its CXX_STANDARD
target property. The use of compile feature requirements (as mentioned in @FlorianWolters answer) can raise the language standard requirement. In fact, CMake will always pick the stronger language requirement specified by either the CXX_STANDARD
target property or the compile feature requirements set on the target. Note also that earlier versions of the CMake documentation did not accurately reflect the way CXX_EXTENSIONS
interacts with compile features. With CMake 3.21 or earlier, CXX_EXTENSIONS
would only take effect if CXX_STANDARD
was also specified, for most common compilers (since they are specified together with the one compiler flag). From CMake 3.22 onward, CXX_EXTENSIONS
is honoured whether CXX_STANDARD
is set or not.
How to enable /std:c++17 in VS2017 with CMake
Turning my comment into an answer
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()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 `/std:c++latest` in cmake?
Until CMake 3.20.3, if you ask for C++20, using set(CMAKE_CXX_STANDARD 20)
, you'll get -std:c++latest
. Proof:
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.12.25835)
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
endif()
(from Modules/Compiler/MSVC-CXX.cmake in the cmake sources)
UPDATE: Since CMake 3.20.4, set(CMAKE_CXX_STANDARD 20)
gets you -std:c++20
, so you need set(CMAKE_CXX_STANDARD 23)
to get -std:c++latest
-- assuming that your MSVC compiler version is 16.11 Preview 1 or later (see cmake commit 3aaf1d91bf353).
QtCreator Cmake C++17 Features
If you're compiling Cmake projects in Qt creator, just be sure there is a line like this in your CMakeLists.txt:
set(CMAKE_CXX_STANDARD 17)
To use gcc-7.2.0, be sure it is listed in the Compilers tab of the Build & Run section in Tools/Option. Then, in Kits tab, select the kit you configured your project with, and select gcc-7.2.0 as the the kit's compiler.
If you're using qmake, instead, add this line to your pro
file:
QMAKE_CXXFLAGS += -std=c++17
CMake cannot set CUDA standard c++17
As is turns out, CMake was not using the correct nvcc
binary.
In my case, I've had two versions of nvcc on the system:
nvcc v10.1.243
in/usr/bin
andnvcc v11.2.152
in/usr/local/cuda-11.2/bin
In my CMake configuration,
CUDA_NVCC_EXECUTABLE
was set to/usr/local/cuda-11.2/bin
, butCMAKE_CUDA_COMPILER
was set to the older version in/usr/bin
.
After setting CMAKE_CUDA_COMPILER
to the correct path, CMake was able to detect nvcc 11.2.152
and could apply the C++17 standard.
Related Topics
How to Iterate Over a Std::Tuple in C++ 11
Difference Between A* Pa = New A; and A* Pa = New A();
Literal Initialization for Const References
C++: How to Get Fprintf Results as a Std::String W/O Sprintf
Confusion About Pointers and References in C++
Is a Linked-List Implementation Without Using Pointers Possible or Not
Loading a File into a Vector<Char>
How to Ensure Constexpr Function Never Called at Runtime
Was Not Declared in This Scope' Error
Of Memory Management, Heap Corruption, and C++
How to Take Screenshot in Opengl
What Is Better: Reserve Vector Capacity, Preallocate to Size or Push Back in Loop
How to Access Variables Defined and Declared in One Function in Another Function
Comparing 3 Modern C++ Ways to Convert Integral Values to Strings
Should Objects Delete Themselves in C++