如何在CMake中激活C ++ 11?

当我尝试运行CMake生成的makefile来编译我的程序时,出现错误

C ++ 98模式不支持基于范围的循环。

我尝试添加add_definitions(-std=c++0x)到我的CMakeLists.txt ,但它没有帮助。 我也试过这个:

 if(CMAKE_COMPILER_IS_GNUCXX) add_definitions(-std=gnu++0x) endif() 

当我做g++ --version ,我得到:

g ++(Ubuntu / Linaro 4.6.1-9ubuntu3)4.6.1

我也试过SET(CMAKE_CXX_FLAGS "-std=c++0x") ,这也不起作用。

我不明白如何使用CMake激活C ++ 11function。

CMake 3.1引入了可以使用的CMAKE_CXX_STANDARDvariables。 如果您知道您将始终拥有CMake 3.1,那么您可以将其写入顶级CMakeLists.txt文件中,或者在定义任何新目标之前将其写入正确的位置:

 set (CMAKE_CXX_STANDARD 11) 

如果你需要支持CMake的老版本,下面是我提出的一个macros,你可以使用:

 macro(use_cxx11) if (CMAKE_VERSION VERSION_LESS "3.1") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}") endif () else () set (CMAKE_CXX_STANDARD 11) endif () endmacro(use_cxx11) 

macros只支持GCC,但是应该直接将其扩展到其他编译器。

然后你可以在任何定义了一个使用C ++ 11的目标的CMakeLists.txt文件的顶部写上use_cxx11()

CMake issue#15943针对macOS的clang用户

如果您使用CMake和铿锵的目标MacOS有一个错误 ,可能会导致CMAKE_CXX_STANDARDfunction简单地不工作(不添加任何编译器标志)。 确保你做了以下一件事情:

  • 使用cmake_minimum_required来要求CMake 3.0或更高版本,或者
  • project命令之前,在您的CMakeLists.txt文件的顶部使用以下代码将策略CMP0025设置为NEW:

     # Fix behavior of CMAKE_CXX_STANDARD when targeting macOS. if (POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif () 

CMake命令target_compile_features()用于指定所需的C ++functioncxx_range_for 。 然后CMake将会使用C ++标准。

 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) 

不需要使用add_definitions(-std=c++11)或者修改CMakevariablesCMAKE_CXX_FLAGS ,因为CMake会确保C ++编译器调用适当的命令行标志。

也许你的C ++程序使用其他C ++特性而不是cxx_range_for 。 CMake全局属性CMAKE_CXX_KNOWN_FEATURES列出了您可以select的C ++function。

除了使用target_compile_features()还可以通过为CMake目标设置CMake属性CXX_STANDARDCXX_STANDARD_REQUIRED来明确指定C ++标准。

另见我更详细的答案 。

我在用

 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() 

但是,如果你想玩C++11g++ 4.6.1是相当古老的。 尝试获得更新的g++版本。

设置cxx标准最简单的方法是

  set_property(TARGET tgt PROPERTY CXX_STANDARD 11) 

有关更多详细信息,请参阅cmake文档 。

事实certificate, SET(CMAKE_CXX_FLAGS "-std=c++0x")确实激活了许多C ++ 11function。 它没有工作的原因是这个声明是这样的:

 set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs") 

按照这种方法,不知何故, -std=c++0x标志被覆盖,并且不起作用。 逐个设置标志或使用列表方法正在工作。

 list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs") 

最简单的方法是:

add_compile_options(-std=c++11)

这是支持C ++ 11的另一种方式,

 ADD_DEFINITIONS( -std=c++11 # Or -std=c++0x # Other flags ) 

我遇到了只有这个方法有效并且其他方法失败的情况。 也许它与最新版本的CMake有关。

什么对我有用是在你的CMakeLists.txt中设置下面的行:

 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 

设置这个命令将激活编译器的C ++ 11function,并且在执行cmake ..命令之后,您应该能够在代码中使用range based for loops ,并无任何错误地进行编译。

OSX和自制的LLVM相关:

不要忘了在它后面调用cmake_minimum_required(VERSION 3.3)和project()!

或者cmake会在第1行之前隐式插入project(),从而导致叮当检测版本以及其他types的麻烦。 这是相关的问题