Was ist die moderne Methode zum Setzen allgemeiner Kompilierungsflags in CMake?

84

CMake bietet mehrere Mechanismen, um Flags an den Compiler zu senden:

Gibt es eine Methode, die im modernen Gebrauch der anderen vorgezogen wird? Wenn ja warum? Wie kann diese Methode auch mit mehreren Konfigurationssystemen wie MSVC verwendet werden?

Peter Clark
quelle

Antworten:

92

Für modernes CMake (Versionen 2.8.12 und höher) sollten Sie verwenden target_compile_options, das intern Zieleigenschaften verwendet.

CMAKE_<LANG>_FLAGSist eine globale Variable und die fehleranfälligste. Es werden auch keine Generatorausdrücke unterstützt , was sehr nützlich sein kann.

add_compile_options basiert auf Verzeichniseigenschaften, was in einigen Situationen in Ordnung ist, aber normalerweise nicht die natürlichste Art, Optionen anzugeben.

target_compile_optionsarbeitet auf Zielbasis (durch Festlegen der Eigenschaften COMPILE_OPTIONSund INTERFACE_COMPILE_OPTIONStarget), was normalerweise zu dem saubersten CMake-Code führt, da die Kompilierungsoptionen für eine Quelldatei davon abhängen, zu welchem ​​Projekt die Datei gehört (und nicht von welchem ​​Verzeichnis sie abgelegt wird) auf der Festplatte). Dies hat den zusätzlichen Vorteil, dass auf Anfrage automatisch Optionen an abhängige Ziele weitergegeben werden.

Obwohl sie etwas ausführlicher sind, ermöglichen die Befehle pro Ziel eine einigermaßen fein abgestimmte Kontrolle über die verschiedenen Erstellungsoptionen und verursachen (meiner persönlichen Erfahrung nach) auf lange Sicht am wenigsten Kopfschmerzen.

Theoretisch können Sie die jeweiligen Eigenschaften auch direkt mit einstellen set_target_properties, sind aber target_compile_optionsnormalerweise besser lesbar.

Um beispielsweise die Kompilierungsoptionen eines Ziels foobasierend auf der Konfiguration mithilfe von Generatorausdrücken festzulegen, können Sie Folgendes schreiben:

target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
ComicSansMS
quelle
11
Beachten Sie, dass target_compile_options Add - Optionen, so können Sie letzte Zeile wie verändern diese zu machen es besser lesbar)
2
@ComicSansMS Tolle Antwort und die beste (und aktuellste), die ich im Internet finden konnte. Vielen Dank!
Ela782
Was ist der beste moderne Weg, wenn ich weltweit die gleichen strengen Kompilierungsflags haben möchte? Es scheint eine schlechte Idee zu sein, immer wieder dieselben Flags für verschiedene Ziele mit target_compile_options
anzugeben
1
@ user3667089 Die zielspezifischen Eigenschaften werden normalerweise durch eine Variable oder eine Verzeichniseigenschaft initialisiert. Die Manpage für die jeweilige Eigenschaft gibt Ihnen genau an, welche. Bei Kompilierungsoptionen führt die COMPILE_OPTIONSVerzeichniseigenschaft dies aus. Sie können den add_compile_optionsBefehl verwenden, um dies festzulegen. Die Optionen, für die dies ein guter Ansatz ist, sind normalerweise selten.
ComicSansMS
3
@ComicSansMS Was nützt PUBLICin target_compile_options?
Ramana Reddy