cmake compiler-flags

Cambiando CMAKE_CXX_FLAGS en proyecto



compiler-flags (9)

Tengo el siguiente contenido en mi CMakeLists.txt:

project( Matfile ) SET ( CMAKE_CXX_FLAGS "-std=c++0x" ) set ( SOURCES "foo.cpp" "bar.cpp" ) add_library( Matfile ${SOURCES} )

Como se puede imaginar, lo que quiero hacer es compilar mis fuentes de C ++ usando la bandera -std = c ++ 0x (estoy usando gcc y necesito las características de C ++ 11). Desafortunadamente, esto no funciona, en el sentido de que, cuando uso cmake para generar los archivos make, la variable CMAKE_CXX_FLAGS está completamente vacía.

¿Cómo puedo establecer esta variable en el archivo de proyecto?

Parece ser una pregunta muy estúpida, pero acabo de pasar no menos de dos horas tratando de resolver esto.


¿Ayuda usar la bandera FORCE ?

SET ( CMAKE_CXX_FLAGS "-std=c++0x" CACHE STRING "compile flags" FORCE)


En el caso específico de requerir un estándar particular para el compilador, cmake 3.1 resuelve el problema al proporcionar una forma de solicitar una versión estándar o un conjunto de características del compilador. Consulte esta respuesta y la documentación oficial .


Esta es la solución que uso actualmente:

if(CMAKE_COMPILER_IS_GNUCXX) add_definitions(-std=c++0x) add_definitions(-std=gnu++11) endif()

O bien, si tiene una versión anterior de cmake y quiere verla aparecer en cmake-gui:

set_property(CACHE CMAKE_CXX_FLAGS PROPERTY VALUE "-std=c++0x")


He encontrado un método mejor que funciona en las versiones anteriores de cmake, por ejemplo, Ubuntu 14 tiene 2.8.12 y las expresiones de destino son funciones 3.3.

Aquí se explica cómo establecería algunos indicadores específicos de C ++:

STRING(REGEX REPLACE "<FLAGS>" "<FLAGS> -std=gnu++11 -fpermissive -fexceptions " CMAKE_CXX_COMPILE_OBJECT ${CMAKE_CXX_COMPILE_OBJECT})


La forma correcta de establecer el estándar C ++ en CMake 3.1 y posterior es:

set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED on)

Es posible especificar el estándar para un objetivo individual también:

set_property(TARGET mylib PROPERTY CXX_STANDARD 11)

Desde CMake 3.8 hay una nueva opción para el comando target_compile_features que permite establecer el estándar requerido para un objetivo:

target_compile_features(mylib PUBLIC cxx_std_11)

La ventaja sería que propaga el requisito a los objetivos dependientes. Si compila una biblioteca con la cxx_std_11 requerida cxx_std_11 , cualquier binario que se vincule con ella tendrá automáticamente este conjunto de requisitos.


La solución más sencilla debería ser el uso de add_compile_options() si está utilizando la versión 2.8.12 o posterior. Para versiones anteriores, puede "abusar" de add_definitions() . Si bien solo está pensado para add -D flags, también funciona con cualquier otro indicador de compilación. Sin embargo, creo que no está destinado a ser utilizado de esa manera y podría romperse en una versión futura.

add_compile_options(-std=c++0x) # CMake 2.8.12 or newer

o

add_definitions(-std=c++0x) # CMake 2.8.11 or older

Comenzando con CMake 3.3 también puede hacer que este indicador solo se aplique a un idioma específico (por ejemplo, solo C o C ++) usando la sintaxis de expresiones de generador extraño:

add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-std=c++14> $<$<COMPILE_LANGUAGE:C>:-std=c99>)

Sin embargo, esto no funcionará con el generador de Visual Studio , así que asegúrese de usarlo solo para los generadores de Make / Ninja o use target_compile_options() para configurarlo en un alcance por objetivo.


Para expandir un poco en ADD_COMPILE_OPTIONS () con respuesta de expresión del generador por ar31, puede encontrarse con un problema cuando quiera agregar varios indicadores separados por espacios, ya que cmake tiene un desagradable error en las expresiones del generador .

La solución que utilicé fue un ciclo FOREACH, aquí hay un ejemplo del proyecto en el que estoy trabajando:

IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # common flags SET(MY_C_AND_CXX_FLAGS -mtune=generic -pipe -fPIC -Wformat -Wformat-security -fomit-frame-pointer -fstack-protector-strong --param ssp-buffer-size=4 -fexceptions -D_FORTIFY_SOURCE=2 -feliminate-unused-debug-types) SET(MY_C_FLAGS ${MY_C_FLAGS} ${MY_C_AND_CXX_FLAGS}) SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} ${MY_C_AND_CXX_FLAGS}) IF(MINGW) SET(MY_C_FLAGS ${MY_C_FLAGS} -static-libgcc) SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -static-libgcc -static-libstdc++) ENDIF(MINGW) IF(CMAKE_BUILD_TYPE STREQUAL "Debug") SET(MY_C_FLAGS ${MY_C_FLAGS} -g2 -Wall) SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -g2 -Wall) ELSE() SET(MY_C_FLAGS ${MY_C_FLAGS} -O2 -Wno-error) SET(MY_CXX_FLAGS ${MY_CXX_FLAGS} -O2 -Wno-error) ENDIF() FOREACH(C_COMPILE_FLAG ${MY_C_FLAGS}) ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:C>:${C_COMPILE_FLAG}>) ENDFOREACH() FOREACH(CXX_COMPILE_FLAG ${MY_CXX_FLAGS}) ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CXX>:${CXX_COMPILE_FLAG}>) ENDFOREACH() # for the gcc -fstack-protector* flags we need libssp # clang does not have this IF(CMAKE_COMPILER_IS_GNUCXX) SET(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lssp") SET(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} -lssp") ENDIF() ENDIF() # Assembler flags IF(ASM_ENABLED) FOREACH(ASM_FLAG -I${CMAKE_SOURCE_DIR}/src/filters/hq/asm/ -O1 -w-orphan-labels) ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:ASM_NASM>:${ASM_FLAG}>) ENDFOREACH() ENDIF(ASM_ENABLED)


Quizás esto funcionaría mejor:

set_source_files_properties(${SOURCES} PROPERTIES COMPILE_FLAGS "-std=c++0x")