Как мне активировать C++ 11 в CMake?
Когда я пытаюсь запустить созданный CMake make файл для компиляции моей программы, я получаю сообщение об ошибке, что
диапазон, основанный на циклах, не поддерживается в режиме 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.
Ответы
Ответ 1
Как оказалось, SET(CMAKE_CXX_FLAGS "-std=c++0x")
активирует многие возможности С++ 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")
Ответ 2
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, который определяет цель, которая использует С++ 11.
CMake выпуск № 15943 для пользователей clang, ориентированных на macOS
Если вы используете CMake и clang для нацеливания на macOS, существует ошибка bug, которая может привести к тому, что функция 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 ()
Ответ 3
Команда CMake target_compile_features()
используется для указания требуемой функции С++ cxx_range_for
. Затем CMake побуждает использовать стандарт С++.
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 убедится, что компилятор С++ вызывается с помощью соответствующей команды флаги линии.
Возможно, ваша программа на С++ использует другие функции С++, чем cxx_range_for
. Глобальное свойство CMake CMAKE_CXX_KNOWN_FEATURES
перечисляет возможности С++, которые вы можете выбрать.
Вместо использования target_compile_features()
вы также можете явно указать стандарт С++, установив свойства CMake
CXX_STANDARD
а также
CXX_STANDARD_REQUIRED
для вашей цели CMake.
См. также мой более подробный ответ.
Ответ 4
Я использую
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++
.
Ответ 5
Самый простой способ установить стандарт Cxx:
set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
Смотрите документацию CMake для более подробной информации.
Ответ 6
Самый простой способ:
add_compile_options(-std=c++11)
Ответ 7
Это еще один способ включить поддержку С++ 11,
ADD_DEFINITIONS(
-std=c++11 # Or -std=c++0x
# Other flags
)
Я встречал экземпляры, где работает только этот метод, а другие методы терпят неудачу. Может быть, это имеет какое-то отношение к последней версии CMake.
Ответ 8
Для CMake 3.8 и новее вы можете использовать
target_compile_features(target PUBLIC cxx_std_11)
Ответ 9
На современном CMake (> = 3.1) лучший способ установить глобальные требования:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
Это переводится как "Я хочу С++ 11 для всех целей, это не обязательно, я не хочу использовать какие-либо расширения GNU или Microsoft".
Начиная с С++ 17, это ИМХО лучший способ.
Источник: Включение С++ 11 и более поздних версий в CMake
Ответ 10
Что для меня работает, так это установить следующую строку в вашем CMakeLists.txt:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Установка этой команды активирует функции С++ 11 для компилятора и после выполнения команды cmake ..
вы можете использовать range based for loops
в своем коде и скомпилировать ее без каких-либо ошибок.
Ответ 11
Я думаю, что этих двух строк достаточно.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Ответ 12
Если вы хотите всегда активировать последний стандарт 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)
в связанном ответе.)
Ответ 13
OS X и Homebrew LLVM:
Не забудьте вызвать cmake_minimum_required (ВЕРСИЯ 3.3) и project() после него!
Или CMake будет вставлять project()
неявно перед строкой 1, вызывая проблемы с обнаружением версии Clang и, возможно, другими видами проблем. Вот связанная с этим проблема.