How do I activate C++ 11 in CMake?
CMake 3.1 introduced the CMAKE_CXX_STANDARD variable that you can use. If you know that you will always have CMake 3.1 or later available, you can just write this in your top-level CMakeLists.txt file, or put it right before any new target is defined:
set (CMAKE_CXX_STANDARD 11)
If you need to support older versions of CMake, here is a macro I came up with that you can use:
macro(use_cxx11)
if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
endif ()
else ()
set (CMAKE_CXX_STANDARD 11)
endif ()
endmacro(use_cxx11)
The macro only supports GCC right now, but it should be straight-forward to expand it to other compilers.
Then you could write use_cxx11()
at the top of any CMakeLists.txt file that defines a target that uses C++11.
CMake issue #15943 for clang users targeting macOS
If you are using CMake and clang to target macOS there is a bug that can cause the CMAKE_CXX_STANDARD
feature to simply not work (not add any compiler flags). Make sure that you do one of the following things:
-
Use cmake_minimum_required to require CMake 3.0 or later, or
-
Set policy CMP0025 to NEW with the following code at the top of your CMakeLists.txt file before the
project
command:# Fix behavior of CMAKE_CXX_STANDARD when targeting macOS. if (POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif ()
The CMake command target_compile_features()
is used to specify the required C++ feature cxx_range_for
. CMake will then induce the C++ standard to be used.
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)
target_compile_features(foobar PRIVATE cxx_range_for)
There is no need to use add_definitions(-std=c++11)
or to modify the CMake variable CMAKE_CXX_FLAGS
, because CMake will make sure the C++ compiler is invoked with the appropriate command line flags.
Maybe your C++ program uses other C++ features than cxx_range_for
. The CMake global property CMAKE_CXX_KNOWN_FEATURES
lists the C++ features you can choose from.
Instead of using target_compile_features()
you can also specify the C++ standard explicitly by setting the CMake properties
CXX_STANDARD
and
CXX_STANDARD_REQUIRED
for your CMake target.
See also my more detailed answer.
I am using
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
But if you want to play with C++11
, g++ 4.6.1
is pretty old.
Try to get a newer g++
version.
The easiest way to set the Cxx standard is:
set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
See the CMake documentation for more details.
As it turns out, SET(CMAKE_CXX_FLAGS "-std=c++0x")
does activate many C++11 features. The reason it did not work was that the statement looked like this:
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
Following this approach, somehow the -std=c++0x
flag was overwritten and it did not work. Setting the flags one by one or using a list method is working.
list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")