Как активировать C++ 11 в CMake?

когда я пытаюсь запустить созданный 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"), что также не работа.

Я не понимаю, как я могу активировать функции C++ 11 с помощью CMake.

12 ответов


CMake 3.1 представил CMAKE_CXX_STANDARD переменная, которую вы можете использовать. Если вы знаете, что у вас всегда будет CMake 3.1, вы можете просто написать это в своих CMakeLists верхнего уровня.txt-файл или поместите его прямо перед определением любой новой цели:

set (CMAKE_CXX_STANDARD 11)

Если вам нужно поддерживать более старые версии CMake, вот макрос, который я придумал, который вы можете использовать:

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)

макрос поддерживает только GCC прямо сейчас, но он должен быть прямым расширить его на другие компиляторы.

затем вы могли бы написать use_cxx11() в верхней части любых CMakeLists.txt-файл, определяющий цель, использующую C++11.

проблема CMake #15943 для пользователей clang, нацеленных на macOS

если вы используете CMake и clang для целевой MacOS есть ошибка это может вызвать CMAKE_CXX_STANDARD функция просто не работает (не добавлять флаги компилятора). Убедитесь, что вы делаете одну из следующих вещей:

  • использовать cmake_minimum_required требовать CMake 3.0 или более поздней версии, или
  • установите политику CMP0025 в NEW со следующим кодом в верхней части ваших CMakeLists.txt файл перед project команда:

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

команда CMake target_compile_features() используется для указания требуемой функции C++cxx_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) или изменить переменную CMake CMAKE_CXX_FLAGS, потому что CMake удостоверится, что компилятор C++ вызывается с соответствующими флагами командной строки.

возможно, ваша программа на C++ использует другой C++ особенности, чем cxx_range_for. В случае с CMake глобальной собственность CMAKE_CXX_KNOWN_FEATURES перечисляет функции C++, которые вы можете выбрать.

вместо target_compile_features() вы также можете явно указать стандарт C++, установив свойства CMake CXX_STANDARD и CXX_STANDARD_REQUIRED для вашей цели CMake.

см. также мой более подробный ответ.


Я использую

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++11, g++ 4.6.1 довольно старый. Попробуйте получить более новый g++ версия.


самый простой способ установить стандарт Cxx:

 set_property(TARGET tgt PROPERTY CXX_STANDARD 11)

посмотреть документация CMake для получения более подробной информации.


как выясняется, SET(CMAKE_CXX_FLAGS "-std=c++0x") активирует многие функции C++11. Причина, по которой это не сработало, заключалась в том, что утверждение выглядело так:

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

следуя этому подходу, как-то -std=c++0x флаг был перезаписан, и он не работал. Установка флагов по одному или использование метода list работает.

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++11 для компилятора и после выполнения cmake .. команда, вы должны иметь возможность использовать range based for loops в коде и скомпилировать его без ошибок.


для CMake 3.8 и новее, вы можете использовать

target_compile_features(target PUBLIC cxx_std_11)

Я думаю, что этих двух строк достаточно.

set(CMAKE_CXX_STANDARD 11)

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

на современном CMake (>=3.1) лучший способ установить глобальное требование:

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

это переводится как "я хочу C++11 для всех целей, это необязательно, я не хочу использовать любой дистрибутив GNU или МС расширения." Начиная с c++17, это все еще IMHO лучший способ.

источник: https://crascit.com/2015/03/28/enabling-cxx11-in-cmake/


OS X и Homebrew LLVM связанные:

Не забудьте вызвать cmake_minimum_required (версия 3.3) и project () после него!

или CMake вставит project() неявно перед строкой 1, вызывая проблемы с обнаружением версии Clang и, возможно, другие проблемы. Вот вопрос.