c++11 - ¿Cómo activar C++ 11 en CMake?
(12)
CMake 3.1 introdujo la variable CMAKE_CXX_STANDARD que puede utilizar. Si sabe que siempre tendrá CMake 3.1 disponible, puede escribir esto en su archivo CMakeLists.txt de nivel superior, o ubicarlo justo antes de definir cualquier nuevo objetivo:
set (CMAKE_CXX_STANDARD 11)
Si necesita admitir versiones anteriores de CMake, aquí hay una macro que se me ocurrió y que puede usar:
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)
La macro solo admite GCC en este momento, pero debería ser sencillo expandirla a otros compiladores.
Luego, puede escribir use_cxx11()
en la parte superior de cualquier archivo CMakeLists.txt que defina un objetivo que use C ++ 11.
Edición CMake # 15943 para usuarios de Clang dirigidos a macOS
Si está utilizando CMake y clang para apuntar a MacOS, hay un bug que puede hacer que la función CMAKE_CXX_STANDARD
simplemente no funcione (no agregue ninguna marca de compilación). Asegúrese de hacer una de las siguientes cosas:
- Utilice cmake_minimum_required para requerir CMake 3.0 o posterior, o
Establezca la política CMP0025 en NUEVO con el siguiente código en la parte superior de su archivo CMakeLists.txt antes del comando del
project
:# Fix behavior of CMAKE_CXX_STANDARD when targeting macOS. if (POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif ()
Cuando intento ejecutar el makefile generado por CMake para compilar mi programa, aparece el error que
el rango basado en bucles no se admite en el modo C ++ 98.
Intenté agregar add_definitions(-std=c++0x)
a mi CMakeLists.txt
, pero no ayudó. Intenté esto también:
if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions(-std=gnu++0x)
endif()
Cuando hago g++ --version
, obtengo:
g ++ (Ubuntu / Linaro 4.6.1-9ubuntu3) 4.6.1
También probé SET(CMAKE_CXX_FLAGS "-std=c++0x")
, que tampoco funciona.
No entiendo cómo puedo activar las características de C ++ 11 usando CMake.
Creo que solo estas dos líneas son suficientes.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
El comando CMake target_compile_features()
se usa para especificar la función de C ++ requerida cxx_range_for
. CMake entonces inducirá el estándar C ++ que se utilizará.
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)
No es necesario usar add_definitions(-std=c++11)
o modificar la variable CMake CMAKE_CXX_FLAGS
, porque CMake se asegurará de que el compilador de C ++ se invoque con los indicadores de línea de comando apropiados.
Tal vez su programa de C ++ use otras características de C ++ que cxx_range_for
. La propiedad global CMake CMAKE_CXX_KNOWN_FEATURES
enumera las características de C ++ que puede elegir.
En lugar de usar target_compile_features()
, también puede especificar el estándar de C ++ explícitamente estableciendo las propiedades de CMake CXX_STANDARD
y CXX_STANDARD_REQUIRED
para su destino de CMake.
Véase también mi respuesta más detallada .
En el moderno CMake (> = 3.1), la mejor manera de establecer un requisito global es:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
Se traduce como "Quiero C ++ 11 para todos los objetivos, no es opcional, no quiero usar ninguna extensión de GNU o MS". A partir de c ++ 17, esto sigue siendo, en mi opinión, la mejor manera.
Fuente: https://crascit.com/2015/03/28/enabling-cxx11-in-cmake/
Esta es otra forma de habilitar el soporte de C ++ 11,
ADD_DEFINITIONS(
-std=c++11 # Or -std=c++0x
# Other flags
)
He encontrado instancias donde solo este método funciona y otros métodos fallan. Tal vez tenga algo que ver con la última versión de CMake.
La forma más fácil de establecer el estándar Cxx es:
set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
Vea la documentación de CMake para más detalles.
La forma más fácil:
add_compile_options(-std=c++11)
Lo que me funciona es establecer la siguiente línea en tu CMakeLists.txt:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Al establecer este comando, se activan las funciones de C ++ 11 para el compilador y, después de ejecutar el comando cmake ..
, debería poder usar el range based for loops
en su código y compilarlo sin ningún error.
Para CMake 3.8 y más nuevos puedes usar
target_compile_features(target PUBLIC cxx_std_11)
Relacionados con OS X y Homebrew LLVM:
¡No olvides llamar a cmake_minimum_required (VERSION 3.3) y project () después de eso!
O CMake insertará project()
implícitamente antes de la línea 1, lo que causará problemas con la detección de la versión Clang y posiblemente otros tipos de problemas. Aquí hay un tema relacionado .
Resulta que SET(CMAKE_CXX_FLAGS "-std=c++0x")
activa muchas funciones de C ++ 11. La razón por la que no funcionó fue que la declaración se veía así:
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
Siguiendo este enfoque, de alguna manera se -std=c++0x
la -std=c++0x
y no funcionó. La configuración de los indicadores uno por uno o el uso de un método de lista está funcionando.
list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
estoy usando
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()
Pero si quieres jugar con C++11
, g++ 4.6.1
es bastante antiguo. Trate de obtener una nueva versión de g++
.