2013-02-26 6 views
26

Ich habe den folgenden Inhalt in meinem CMakeLists.txt:Ändern CMAKE_CXX_FLAGS in Projekt

project(Matfile) 

SET (CMAKE_CXX_FLAGS "-std=c++0x") 

set (SOURCES 
     "foo.cpp" 
     "bar.cpp" 
    ) 

add_library(
     Matfile 
     ${SOURCES} 
) 

Wie Sie sich vorstellen können, was ich tun möchte, ist meine C++ Quellen mit der Fahne zu kompilieren -std = C++ 0x (Ich benutze gcc und ich brauche die C++ 11 Funktionen). Leider funktioniert das nicht in dem Sinne, dass, wenn ich cmake verwende, um die Makefiles zu erzeugen, die Variable CMAKE_CXX_FLAGS vollständig ungültig ist.

Wie kann ich diese Variable in der Projektdatei einstellen?

Es scheint eine sehr dumme Frage zu sein, aber ich habe gerade nicht weniger als zwei Stunden ausgegeben, um das herauszufinden.

+0

Die ' set 'command für die Flags sieht gut aus (obwohl für gcc v4.7 ab, sollte das Flag' -std = C++ 11' sein, denke ich). Was meinst du mit "völlig leer"? Was ist die Ausgabe, wenn Sie 'make VERBOSE = 1' ausführen? – Fraser

+2

Möglicherweise sind die CMAKE_CXX_FLAGS im Makefile korrekt eingestellt, aber in der 'CMakeCache.txt' Datei leer. Es ist daher nicht ausreichend, den CMakeCache einzuchecken, es sei denn, man zwingt es, in den Cache zurückgeschrieben zu werden (benutzen 'set (var Wert CACHE STRING" "FORCE") – Alex

Antwort

37

Die einfachste Lösung add_compile_options() verwenden sollten, wenn Sie Version 2.8.12 oder höher verwenden. Für ältere Versionen können Sie add_definitions() "missbrauchen". Obwohl es nur für das Hinzufügen von -D-Flags gedacht ist, funktioniert es auch mit jedem anderen Compiler-Flag. Ich denke jedoch, dass es nicht so verwendet werden soll und eine zukünftige Version einbrechen könnte.

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

oder

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

Beginnend mit CMake 3.3 Sie können auch dieses Flag nur auf eine bestimmte Sprache (zB nur C oder C++) mit dem seltsamen Generator Ausdrücke Syntax gelten machen:

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

Dies wird jedoch not work with the Visual studio generator, also stellen Sie sicher, dass Sie nur für Make/Ninja Generatoren verwenden oder verwenden Sie target_compile_options(), um es auf einen Zielbereich festzulegen.

+2

Gut, aber in diesem Fall hat es ein Problem, diese Argumente werden auch zu C_COMPILER hinzugefügt, nicht nur für CXX und C unterstützen einige Argumente, die für CXX sind, insbesondere '-std = C++ 0x'. In diesem Fall ist eine bessere Lösung 'set (CMAKE_CXX_FLAGS ...)'. – vlk

+0

CMake 3.3 und neuer hat hierfür eine Lösung, die jetzt Generatorausdrücke verwendet. – ar31

5

Vielleicht würde besser funktionieren:

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

Danke, diese Arbeit. Aber im Falle eines größeren Projekts mit mehr Ausgaben , wie einige Bibliotheken und ein paar ausführbare Dateien, vorausgesetzt, dass alle von ihnen mit den gleichen Flags kompiliert werden, sollte ich diese Anweisungen mehrmals wiederholen? Es gibt keinen Befehl, um die Kompilierungsflags für ** alle ** die Quelldateien festzulegen – Spiros

10

Hilft es, die FORCE Flagge zu benutzen?

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

Dies ist die einzige Antwort, die dazu führte, dass die Flags in der ccmake 'curses gui auftauchen, was ich gesucht habe." Danke! –

+1

@Christopher Bruns Gibt es eine Möglichkeit dies zu tun und den Docstring alleine zu lassen 't compare flags ")? –

+0

@DavidDoria Ja, Sie können den vorherigen Docstring wiederverwenden, aber es ist nicht schön. https://cmake.org/Wiki/CMake/Tutorials/SettingVariableGroups –

2

Im speziellen Fall, in dem ein bestimmter Standard für den Compiler erforderlich ist, löst cmake 3.1 das Problem, indem eine Möglichkeit bereitgestellt wird, eine Standardversion oder eine Reihe von Compiler-Features anzufordern. Siehe this answer und official documentation.

2

Um ein wenig auf den ADD_COMPILE_OPTIONS expand() mit Generator Ausdruck Antwort von AR31 zu überprüfen, können Sie laufen in ein Problem, wenn Sie mehrere durch Leerzeichen getrennte Flags hinzufügen möchten, da cmake eine nasty bug in generator expressions hat.

Die Lösung I wurde eine foreach-Schleife ist hier ein Beispiel aus dem Projekt arbeite ich an:

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

Ich habe mit einem besseren Verfahren kommen, die älteren Versionen von cmake arbeitet an, z.B Ubuntu 14 hat 2.8.12, und Zielausdrücke sind 3.3 Feature.

Hier ist, wie Sie einige C++ spezifische Flags gesetzt würde:

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

Der richtige Weg zu set the C++ standard in CMake 3.1 and later ist:

set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_STANDARD_REQUIRED on) 

Es ist möglich, specify the standard for one individual target auch:

set_property(TARGET mylib PROPERTY CXX_STANDARD 11) 

Seit CMake 3.8 gibt es eine new option to the target_compile_features command, die es ermöglicht, die erforderlicher Standard für ein Ziel:

target_compile_features(mylib PUBLIC cxx_std_11) 

Der Vorteil wäre, dass es die Anforderung an abhängige Ziele propagiert. Wenn Sie eine Bibliothek mit der erforderlichen Funktion cxx_std_11 kompilieren, wird diese Anforderung automatisch für jede binäre Verknüpfung festgelegt.

0

Dies ist die Lösung, die ich zur Zeit verwenden:

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

Oder, wenn Sie eine ältere Version von cmake und Sie wollen es in cmake-gui auftauchen sehen:

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