Как активировать 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")
это еще один способ включить поддержку 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
в коде и скомпилировать его без ошибок.
Я думаю, что этих двух строк достаточно.
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 и, возможно, другие проблемы. Вот вопрос.