¿Cómo activar C++11 en CMake?




(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 .

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.


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/


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 ()
    

La forma más fácil:

add_compile_options(-std=c++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 .


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.


Para CMake 3.8 y más nuevos puedes usar

target_compile_features(target PUBLIC cxx_std_11)

Creo que solo estas dos líneas son suficientes.

set(CMAKE_CXX_STANDARD 11)

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

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++ .


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 palabra clave final en C ++ cuando se agrega a una función, evita que sea anulada por una clase base. Además, cuando se agrega a una clase evita la herencia de cualquier tipo. Considere el siguiente ejemplo que muestra el uso del especificador final. Este programa falla en la compilación.

#include <iostream>
using namespace std;

class Base
{
  public:
  virtual void myfun() final
  {
    cout << "myfun() in Base";
  }
};
class Derived : public Base
{
  void myfun()
  {
    cout << "myfun() in Derived\n";
  }
};

int main()
{
  Derived d;
  Base &b = d;
  b.myfun();
  return 0;
}

También:

#include <iostream>
class Base final
{
};

class Derived : public Base
{
};

int main()
{
  Derived d;
  return 0;
}






c++11 cmake