Ich möchte einen globalen Satz von Flags zum Kompilieren eines Projekts verwenden. Dies bedeutet, dass ich in meiner CMakeLists.txt-Datei der obersten Ebene Folgendes angegeben habe:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
Für eine bestimmte Datei (sagen wir "foo.cpp") in einem Unterverzeichnis möchte ich jedoch die Kompilierungsflags so ändern, dass sie nicht -Weffc ++ anwenden (enthaltene kommerzielle Bibliothek, die ich nicht ändern kann). Um die Situation zu vereinfachen, nur -Wall zu verwenden, habe ich versucht:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
, was nicht funktioniert hat. Ich habe es auch versucht
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
und
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
, in denen keiner funktionierte.
Schließlich habe ich versucht, diese Definition zu entfernen:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
, was auch nicht funktioniert hat (was bedeutet, ich bekomme viele Stilwarnungen über die kommerzielle Bibliothek). (** Hinweis: Die Warnungen werden unterdrückt, wenn ich die Direktive -Weffc ++ nach dem Erstellen der ausführbaren Datei NICHT wieder einbinde.)
Ich habe auch versucht, die Kompilierungsflags vorübergehend zu entfernen: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , aber das hat nicht geholfen.
Gibt es dafür keine elegante Lösung?
quelle
Antworten:
Bei den oben genannten Versuchen werden Ihrer Datei / Ihrem Ziel weitere Flags hinzugefügt, anstatt wie erwartet zu überschreiben. Zum Beispiel aus den Dokumenten für Eigenschaften in Quelldateien - COMPILE_FLAGS :
Sie sollten in der Lage sein, das
-Weffc++
Flag für foo.cpp zu kontern, indem Sie dies tunDies sollte dazu führen, dass im Compiler-Befehl
-Wno-effc++
nachher hinzugefügt wird-Weffc++
, und die letztere Einstellung gewinnt. Sie können den vollständigen Befehl anzeigen und überprüfen, ob dies tatsächlich der Fall istAbgesehen davon äußert sich einer der Betreuer der GNU C ++ Standard Library
-Weffc++
in dieser Antwort ziemlich negativ .Ein weiterer Punkt ist, dass Sie
add_definitions
in dem Sinne missbrauchen, dass Sie dies eher für Compiler-Flags als für die beabsichtigten Präprozessor-Definitionen verwenden.Es wäre vorzuziehen, zu verwenden
add_compile_options
oder für CMake-Versionen <3.0, um etwas mehr zu tun wie:
Als Antwort auf weitere Fragen in den Kommentaren unten glaube ich, dass es unmöglich ist , ein Flag in einer einzelnen Datei zuverlässig zu entfernen . Der Grund ist, dass für jede gegebene Quelldatei das
COMPILE_OPTIONS
und 1 vorhanden istCOMPILE_FLAGS
des Ziels angewendet wird, diese jedoch in keiner der Eigenschaften für diese Quelldatei angezeigt werden.Sie können versuchen, das Problemflag vom Ziel zu
COMPILE_OPTIONS
entfernen und es dann einzeln auf jede Quelle des Ziels anzuwenden und es bei Bedarf aus der spezifischen Quelldatei zu entfernen.Dies kann zwar in vielen Szenarien funktionieren, weist jedoch einige Probleme auf.
Die Eigenschaften der First- Source-Dateien enthalten nicht
COMPILE_OPTIONS
nurCOMPILE_FLAGS
. Dies ist ein Problem, da dasCOMPILE_OPTIONS
eines Ziels Generatorausdrücke enthalten kann , dieseCOMPILE_FLAGS
jedoch nicht unterstützt. Sie müssten also Generatorausdrücke berücksichtigen, während Sie nach Ihrem Flag suchen, und Sie müssten möglicherweise sogar Generatorausdrücke "analysieren", wenn Ihr Flag in einem oder mehreren enthalten wäre, um zu sehen, ob es erneut auf die verbleibenden angewendet werden sollte Quelldaten.Zweitens: Seit CMake v3.0 können Ziele angeben
INTERFACE_COMPILE_OPTIONS
. Dies bedeutet, dass eine Abhängigkeit Ihres Ziels die Ihres ZielsCOMPILE_OPTIONS
über seine hinzufügen oder überschreiben kannINTERFACE_COMPILE_OPTIONS
. Sie müssten also alle Abhängigkeiten Ihres Ziels rekursiv durchlaufen (keine besonders einfache Aufgabe, da die ListeLINK_LIBRARIES
für das Ziel auch Generatorausdrücke enthalten kann), um diejenigen zu finden, die das Problemflag anwenden, und versuchen, es aus diesen zu entfernen Ziele 'INTERFACE_COMPILE_OPTIONS
auch.In dieser Phase der Komplexität möchte ich einen Patch an CMake senden, um die Funktionalität zum bedingungslosen Entfernen eines bestimmten Flags aus einer Quelldatei bereitzustellen.
1: Beachten Sie, dass im Gegensatz zur
COMPILE_FLAGS
Eigenschaft für Quelldateien dieCOMPILE_FLAGS
Eigenschaft für Ziele veraltet ist.quelle
Fügen Sie einfach @ Frasers richtige Antwort hinzu.
Wenn Sie bestimmten Ordnern das spezielle Flag hinzufügen möchten, haben Sie folgende Möglichkeiten:
oder
Beachten Sie, dass es nicht empfohlen wird, GLOB wie hier beschrieben zu verwenden
quelle
Mit der Antwort @Fraser habe ich Folgendes erstellt, um die Qt-Includes zu verarbeiten, da die Variable mehrere durch Semikolons getrennte Pfade enthält. Dies bedeutet, dass ich zuerst eine
foreach()
Schleife hinzufügen und die Include-Flags von Hand erstellen musste . Damit kann ich jedoch eine Ausnahme haben: foo.cpp (diese eine Datei verwendet derzeit Qt, aber langfristig möchte ich diese Abhängigkeit entfernen und sicherstellen, dass sich Qt nirgendwo anders einschleicht).Beachten Sie auch, dass ich das
-isystem
anstelle von verwende-I
, um einige Warnungen zu vermeiden, die Qt-Header andernfalls generieren (ich habe eine Menge Warnungen aktiviert).quelle