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

Когда я пытаюсь запустить сгенерированный CMake make-файл для компиляции моей программы, я получаю сообщение об ошибке

range based for loops are not supported in C++ 98 mode.

Я пытался добавить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.

 kyku02 июн. 2012 г., 10:49
add_definitions (-std = c ++ 11) у меня работает с CMake 2.8.8
 Ela78209 дек. 2016 г., 21:21
@tuple_cat Вы также можете сделать это на основе цели. Но знайте, чтоCXX_STANDARD делаетnot работать на MSVC, так что в основном вы должны вернуться кtarget_compile_features если вы хотите что-то, что работает кроссплатформенно.
 ComicSansMS01 июн. 2012 г., 16:11
SET(CMAKE_CXX_FLAGS "-std=c++0x") у меня работает нормально, так что, возможно, проблема где-то еще в файле CMakeLists. Убедитесь, что вы случайно не перезаписали содержимое CMAKE_CXX_FLAGS позже.
 TheBicentennialMan03 июн. 2012 г., 12:31
@ComicSansMS: Вы совершенно правы! Я переписал это, что было моей собственной ошибкой. Я исправил это, и теперь он работает нормально! C ++ 11 очень классный материал! Я хотел зациклить вектор структур, что потребовало бы итератора и ненужного шума кодирования, если бы у меня не было диапазона, основанного на циклах. Я думаю, что я мог бы использовать BOOST_FOREACH, хотя, ну да ладно ...
 emlai13 июн. 2015 г., 04:26
Для CMake & # x2265; 3.1,set(CMAKE_CXX_STANDARD 11) (до определения цели) это лучший способ.

Ответы на вопрос(13)

Самый простой способ:

add_compile_options(-std=c++11)

 10 мар. 2016 г., 13:36
Доступно только с cmake 3.0
 10 июн. 2016 г., 18:10
Это вызывает предупреждение и ошибки при компиляции файлов C в том же проекте.

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

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

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

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

 07 янв. 2015 г., 14:38
Я бы сказал, что это самый точный ответ
 20 мар. 2015 г., 04:37
@ UliK & # xF6; hler, это на самом деле все еще недоступно, иmay possibly обратиться заsome compilers в 3.2. Не используйте этот метод в краткосрочной перспективе; это совсем не портативно.
 15 сент. 2014 г., 00:16
Кажется, сегодняшняя редакция вводит в заблуждение. CMake 3.0.0 не содержит target_compile_features. Поправь меня, если я ошибаюсь. Я думаю, что команда присутствует только в ночных сборках CMake.
 14 мар. 2015 г., 19:32
Я думаю, что так и должно быть. Другие ответы просто вручную добавляют флаги и поэтому вводят несовместимости. Однако это, кажется, доступно только в CMake 3.1+
 31 дек. 2015 г., 04:29
Любая идея, как это сделать в CMake 2.6?

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

 set_property(TARGET tgt PROPERTY CXX_STANDARD 11)

Увидетьдокументация CMake Больше подробностей.

 18 мая 2015 г., 23:47
Да, это определенно выглядит как один из лучших способов сделать это в современном CMake (3.1+)
 19 нояб. 2015 г., 16:48
Это работает в CMake 2.8?
 18 окт. 2018 г., 23:53
Это также решение, которое вам нужно, если вы хотите установить разные стандарты C ++ для разных целей, потому чтоset Команда, предложенная @emlai, является глобальной и влияет на все последующие цели.
 13 июн. 2015 г., 04:14
Или ты можешь простоset(CMAKE_CXX_STANDARD 11) определить свойство по умолчанию для всех целей, созданных после этого.

Что работает для меня, это установить следующую строку в вашем CMakeLists.txt:

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

Установка этой команды активирует функции C ++ 11 для компилятора и после выполненияcmake .. команда, вы должны быть в состоянии использоватьrange based for loops в вашем коде и скомпилируйте его без ошибок.

 29 авг. 2017 г., 17:14
@Antonioset (CMAKE_CXX_EXTENSIONS OFF)
 31 мая 2017 г., 12:08
В конце концов, это лучший ответ, если вы хотите именно-std=c++11, какset (CMAKE_CXX_STANDARD 11) будет использовать флаг-std=gnu++11, что может быть нежелательно.

я использую

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++ версия.

 30 янв. 2015 г., 15:20
Отлично, это дополнение для старых CMake и g ++ 4.6 (и перспективных). Я также проголосовал заCXX_STANDARDответы, но это был единственный ответ, полезный в моей ситуации.
 22 янв. 2015 г., 01:28
Скопировал и вставил это, и это сработало отлично. Я на Cygwin использую CMAKE 2.8.9. Я знаю о большинстве подходов, которые я здесь читаю, потому что я следую за списком рассылки CMAKE и портировал WebKit на различные компиляторы. То, что мы сделали для портов WebKit, это установили CMake 2.8.12. Однако, поскольку я знаю, что CMAKE Cygwin устарел, я хотел что-то, что применимо к этой версии. (Не портирую WebKit на Cygwin, извините)
 01 апр. 2015 г., 08:00
@JanSegre модуль впервые появился в 2.4,cmake.org/…
 19 окт. 2014 г., 22:18
Для меня это единственный правильный и хороший ответ на этот вопрос, с текущим (развернутым) cmake на самых последних версиях Linux & apos; используя g ++.
 31 мар. 2015 г., 20:12
Это именно то, что я искал, однако неясно, какая минимальная версия cmake необходима для использования этого модуля. cmake --help-module не очень помогает в этом.

Если вы хотите всегда активировать новейший стандарт C ++, вот мое расширениеОтвет Дэвида Грейсонав свете недавних (CMake 3.8, CMake 3.11) добавлений значений 17 и 20 для CMAKE_CXX_STANDARD):

IF (CMAKE_VERSION VERSION_LESS "3.8")
    SET(CMAKE_CXX_STANDARD 14)
ELSEIF (CMAKE_VERSION VERSION_LESS "3.11")
    SET(CMAKE_CXX_STANDARD 17)
ELSE() # CMake 3.11 or higher:
    SET(CMAKE_CXX_STANDARD 20)
ENDIF()
# Typically, you'll also want to turn off compiler-specific extensions:
SET(CMAKE_CXX_EXTENSIONS OFF)

(используйте этот код вместоset (CMAKE_CXX_STANDARD 11) в связанном ответе).

На современном CMake (& gt; = 3.1) лучший способ установить глобальные требования:

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

Это переводится как «Я хочу C ++ 11 для всех целей, это не является обязательным, я не хочу использовать какие-либо расширения GNU или MS». Начиная с c ++ 17, это ИМХО лучший способ.

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

 29 янв. 2019 г., 12:41
Этот способ не идеален для новейших версий C ++, если у вас нет последней версии CMake. Например. Вы не можете включить C ++ 2a до CMake 3.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 issue #15943 for clang users targeting macOS

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

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 ()
 20 янв. 2016 г., 13:49
Это должен быть принятый ответ. Он не требует индивидуального касания свойств каждой цели и работает кроссплатформенно.
 03 авг. 2017 г., 00:00
man gcc говорит -std = ... не --std = ... (одна черта, а не две).
 01 нояб. 2017 г., 16:34
@Unapiedra: это ошибка CMake, но вы можете обойти ее, см.gitlab.kitware.com/cmake/cmake/issues/15943
 23 мая 2016 г., 20:40
Согласен, это должен быть принятый ответ начиная с CMake 3.1+. Это, похоже, не работает для меня на Mac, хотя. Вы можете заставить его дать вам --std = c ++ 11 с --stdlib = libc ++, по умолчанию на Mac. Вместо этого CMAKE_CXX_STANDARD всегда включает расширения gnu, если они поддерживаются, и результат, по-видимому, не соответствует --stdlib = libc ++. Вместо этого вам нужно переключиться на gnu 'sststlib = libstdc ++. Mac - это особый случай. Для Linux выбор gnu ++ 11 с libstdc ++ является нормой. Конечно, это легко исправить с помощью if (APPLE) add_compile_options () для привязки к флагам.
 31 мая 2017 г., 12:11
Одна из проблем этого подхода заключается в том, чтоgnu++11 применяется, даже когда эти переменные определеныset(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang) set(CMAKE_ANDROID_STL_TYPE c++_static), Для меня единственным жизнеспособным способом был классическийset (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")

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

Не забудьте вызвать cmake_minimum_required (ВЕРСИЯ 3.3) и project () после него!

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

 03 июн. 2016 г., 21:52
Вопрос, в частности, не связан с OSX или LVVM. Кроме того, нет причин требовать CMake v3.x для разработки на C ++ 11. Что касается обнаружения версии clang - это не то, о чем спрашивал OP.
Решение Вопроса

Как выясняется,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( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
 15 февр. 2013 г., 15:08
Однажды я сделал небольшой сценарий для этого (хотя и не полный):github.com/Morwenn/POLDER/blob/master/cmake/set_cxx_norm.cmake
 14 авг. 2018 г., 12:13
CXX_STANDARD свойство лучше, поскольку оно не зависит от компилятора.
 29 мая 2013 г., 16:26
-1. Если вы укажете какой-либо CMAKE_CXX_FLAGS из командной строки, второй метод создаст точку с запятой в команде построения (и дважды повторит исходный CMAKE_CXX_FLAGS).
 24 нояб. 2014 г., 21:52
вместо того, чтобы вручную добавлять флаг -g, вы должны установить переменную CMAKE_BUILD_TYPE для отладки:voices.canonical.com/jussi.pakkanen/2013/03/26/…
 21 сент. 2012 г., 18:42
Я всегда просто использую: SET (CMAKE_CXX_FLAGS & quot; $ {CMAKE_CXX_FLAGS} -std = c ++ 11 & quot;) # для gcc & gt; = 4.7 или c ++ 0x для 4.6

Это еще один способ включить поддержку C ++ 11,

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

Я встречал случаи, когда только этот метод работает, а другие методы не работают. Возможно, это как-то связано с последней версией CMake.

 07 нояб. 2014 г., 01:26
add_definitions Предполагается, что он используется только для добавления ОПРЕДЕЛЕНИЙ, т.е. И, как сказал @Emmanuel, во многих случаях это не работает.
 13 нояб. 2013 г., 17:45
Это будет работать только если вы используете ТОЛЬКО C ++ компилятор. Если вы также используете компилятор CC, он потерпит неудачу.
 31 мар. 2015 г., 20:15
Я использовал это раньше, но у меня были проблемы, когда я включил файл C, потому чтоadd_definitions не был сделан для установки флагов.

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

target_compile_features(target PUBLIC cxx_std_11)
 12 июн. 2018 г., 05:16
Какова функцияPUBLIC Вот?
 12 июн. 2018 г., 09:05
@RotsiserMhoPUBLIC означает, что другие цели, которые зависят от вашей цели, также будут использовать C ++ 11. Например, если ваша цель - библиотека, то все цели, которые ссылаются на вашу библиотеку с помощьюtarget_link_libraries будет скомпилирован с поддержкой C ++ 11.
 19 мая 2018 г., 19:36
так рекомендуется в последней версии CMake

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

set(CMAKE_CXX_STANDARD 11)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
 06 авг. 2018 г., 12:45
Это имеет смысл, когда все цели в проекте используют один и тот же стандарт C ++ (например, все скомпилированные библиотеки и исполняемые файлы используют C ++ 11). В противном случае, Cmaketarget_compile_features Функция, применяемая для каждой отдельной цели, как показано в других ответах, является более рекомендуемым подходом.

Ваш ответ на вопрос