cmake - variable - title tag wordpress




Wie lautet die CMake-Syntax zum Festlegen und Verwenden von Variablen? (2)

Ich bitte dies, um mich daran zu erinnern, wenn ich CMake das nächste Mal benutze. Es bleibt nie hängen und die Google-Ergebnisse sind nicht großartig.

Wie lautet die Syntax zum Festlegen und Verwenden von Variablen in CMake?


Hier sind ein paar grundlegende Beispiele, um schnell und schmutzig loszulegen.

Eine Artikelvariable

Variable setzen:

SET(INSTALL_ETC_DIR "etc")

Variable verwenden:

SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")

Variable mit mehreren Elementen (dh Liste)

Variable setzen:

SET(PROGRAM_SRCS
        program.c
        program_utils.c
        a_lib.c
        b_lib.c
        config.c
        )

Variable verwenden:

add_executable(program "${PROGRAM_SRCS}")

CMake-Dokumente zu Variablen


Wenn Sie CMake-Skripte schreiben, müssen Sie viel über die Syntax und die Verwendung von Variablen in CMake wissen.

Die Syntax

Zeichenketten mit set() :

  • set(MyString "Some Text")
  • set(MyStringWithVar "Some other Text: ${MyString}")
  • set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")

Oder mit string() :

  • string(APPEND MyStringWithContent " ${MyString}")

Listen mit set() :

  • set(MyList "a" "b" "c")
  • set(MyList ${MyList} "d")

Oder besser mit list() :

  • list(APPEND MyList "a" "b" "c")
  • list(APPEND MyList "d")

Listen der Dateinamen:

  • set(MySourcesList "File.name" "File with Space.name")
  • list(APPEND MySourcesList "File.name" "File with Space.name")
  • add_excutable(MyExeTarget ${MySourcesList})

Die Dokumentation

Der Bereich oder "Welchen Wert hat meine Variable?"

Zuerst gibt es die "Normalen Variablen" und Dinge, die Sie über ihren Umfang wissen müssen:

  • Normale Variablen sind in der CMakeLists.txt sichtbar, in der sie gesetzt sind, und alles, was von dort aufgerufen wird ( add_subdirectory() , include() , macro() und function() ).
  • Die add_subdirectory() und function() sind etwas Besonderes, da sie einen eigenen Bereich eröffnen.
    • Bedeutungsvariablen, die dort set(...) sind, sind nur dort sichtbar und kopieren alle normalen Variablen der Gültigkeitsbereichsebene, von der aus sie aufgerufen werden (übergeordneter Gültigkeitsbereich genannt).
    • Wenn Sie sich also in einem Unterverzeichnis oder einer Funktion befinden, können Sie eine bereits vorhandene Variable im übergeordneten Bereich mit set(... PARENT_SCOPE)
    • Dies können Sie zB in Funktionen nutzen, indem Sie den Variablennamen als Funktionsparameter übergeben. Ein Beispiel wäre, dass die function(xyz _resultVar) set(${_resultVar} 1 PARENT_SCOPE)
  • Andererseits ändern alle in include() oder macro() Skripten festgelegten Einstellungen Variablen direkt in dem Bereich, von dem aus sie aufgerufen werden.

Zweitens gibt es den "Global Variables Cache". Dinge, die Sie über den Cache wissen müssen:

  • Wenn im aktuellen Bereich keine normale Variable mit dem angegebenen Namen definiert ist, sucht CMake nach einem passenden Cache-Eintrag.
  • Cache-Werte werden in der CMakeCache.txt Datei in Ihrem CMakeCache.txt gespeichert.
  • Die Werte im Cache können in der GUI- Anwendung von CMake geändert werden, bevor sie generiert werden. Deshalb haben sie - im Vergleich zu normalen Variablen - einen type und einen docstring . Normalerweise benutze ich die GUI nicht und set(... CACHE INTERNAL "") mit set(... CACHE INTERNAL "") meine globalen und persistenten Werte.

    Beachten Sie, dass der Variablentyp INTERNAL Cache FORCE impliziert

  • In einem CMake-Skript können Sie vorhandene Cache-Einträge nur ändern, wenn Sie die Syntax set(... CACHE ... FORCE) . Dieses Verhalten wird zB von CMake selbst ausgenutzt, da es normalerweise keine Cache-Einträge selbst erzwingt und Sie es daher mit einem anderen Wert vordefinieren können.

  • Sie können die Befehlszeile verwenden, um Einträge im Cache mit der Syntax cmake -D var:type=value , nur cmake -D var=value oder mit cmake -C CMakeInitialCache.cmake .
  • Mit unset(... CACHE) können Sie Einträge im Cache unset(... CACHE) .

Der Cache ist global und Sie können sie praktisch überall in Ihren CMake-Skripten festlegen. Ich würde Ihnen jedoch empfehlen, zweimal darüber nachzudenken, wo Cache-Variablen verwendet werden sollen (sie sind global und persistent). Normalerweise bevorzuge ich die set_property(GLOBAL PROPERTY ...) und set_property(GLOBAL APPEND PROPERTY ...) , um meine eigenen nicht persistenten globalen Variablen zu definieren.

Variable Fallstricke und "Wie werden Variablenänderungen behoben?"

Um Fallstricke zu vermeiden, sollten Sie Folgendes über Variablen wissen:

  • Lokale Variablen verbergen zwischengespeicherte Variablen, wenn beide denselben Namen haben
  • Die find_... -Befehle schreiben - falls erfolgreich - ihre Ergebnisse als zwischengespeicherte Variablen, "damit kein Aufruf erneut sucht".
  • Listen in CMake sind nur Zeichenfolgen mit Semikolon-Trennzeichen, daher sind die Anführungszeichen wichtig
    • set(MyVar abc) ist "a;b;c" und set(MyVar "abc") ist "abc"
    • Die Empfehlung ist, dass Sie immer Anführungszeichen mit der einen Ausnahme verwenden, wenn Sie eine Liste als Liste angeben möchten
    • Bevorzugen Sie im Allgemeinen den Befehl list() für die Behandlung von Listen
  • Das oben beschriebene Problem mit dem gesamten Geltungsbereich. Insbesondere wird die Verwendung von functions() anstelle von macros() empfohlen, da Ihre lokalen Variablen nicht im übergeordneten Bereich angezeigt werden sollen.
  • Viele von CMake verwendete Variablen werden mit den Aufrufen project() und enable_language() . Daher kann es wichtig werden, einige Variablen festzulegen, bevor diese Befehle verwendet werden.
  • Umgebungsvariablen können sich davon unterscheiden, wo CMake die make-Umgebung erstellt hat und wann die make-Dateien verwendet werden.
    • Eine Änderung einer Umgebungsvariablen löst den Generierungsprozess nicht erneut aus.
    • Insbesondere eine generierte IDE-Umgebung kann von Ihrer Befehlszeile abweichen. Es wird daher empfohlen, Ihre Umgebungsvariablen in eine zwischengespeicherte Umgebung zu übertragen.

Manchmal hilft nur das Debuggen von Variablen. Folgendes kann Ihnen helfen:

Spezielle Syntax

  • Umgebungsvariablen
    • Sie können $ENV{...} lesen und Umgebungsvariablen set(ENV{...} ...) schreiben
  • Generator-Ausdrücke
    • Generator-Ausdrücke $<...> werden nur ausgewertet, wenn der Generator von CMake die make-Umgebung schreibt (ein Vergleich mit normalen Variablen, die vom Parser "an Ort und Stelle" ersetzt werden).
    • Sehr praktisch, zB in Compiler / Linker-Befehlszeilen und in Umgebungen mit mehreren Konfigurationen
  • Verweise
    • Mit ${${...}} Sie Variablennamen in einer Variablen angeben und auf deren Inhalt verweisen.
    • Wird häufig verwendet, wenn ein Variablenname als Funktions- / Makroparameter angegeben wird.
  • Konstante Werte (siehe if() Befehl)
    • Mit if(MyVariable) können Sie eine Variable direkt auf true / false prüfen (hier ist das Einschließen von ${...} nicht erforderlich)
    • True, wenn die Konstante 1 , ON , YES , TRUE , Y oder eine Zahl ungleich Null ist.
    • False, wenn die Konstante 0 , OFF , NO , FALSE , N , IGNORE , NOTFOUND , die leere Zeichenfolge oder das Suffix -NOTFOUND .
    • Diese Syntax wird häufig für etwas wie if(MSVC) , kann jedoch für jemanden verwirrend sein, der diese if(MSVC) nicht kennt.
  • Rekursive Ersetzungen
    • Sie können Variablennamen mithilfe von Variablen erstellen. Nachdem CMake die Variablen ersetzt hat, prüft es erneut, ob das Ergebnis selbst eine Variable ist. Dies ist eine sehr leistungsstarke Funktion, die in CMake selbst verwendet wird, z. B. als eine Art Vorlagensatz set(CMAKE_${lang}_COMPILER ...)
    • Beachten Sie jedoch, dass dies zu Kopfschmerzen bei if() Befehlen führen kann. Hier ist ein Beispiel, in dem CMAKE_CXX_COMPILER_ID "MSVC" und MSVC "1" :
      • if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") ist wahr, da er zu if("1" STREQUAL "1") ausgewertet wird.
      • if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") ist falsch, da er zu if("MSVC" STREQUAL "1") ausgewertet wird.
      • Die beste Lösung hier wäre also - siehe oben - direkt zu prüfen, if(MSVC)
    • Die gute Nachricht ist, dass dies in CMake 3.1 mit der Einführung der Richtlinie CMP0054 behoben wurde . Ich würde empfehlen, cmake_policy(SET CMP0054 NEW) immer so einzustellen, dass " if() -Argumente nur if() als Variablen oder Schlüsselwörter interpretiert werden, if() nicht in Anführungszeichen stehen."
  • Der Befehl option()
    • Hauptsächlich nur zwischengespeicherte Strings, die nur ON oder OFF und eine spezielle Behandlung wie zB dependencies
    • Beachten Sie jedoch , dass Sie die option mit dem Befehl set verwechseln müssen. Der Wert für option ist eigentlich nur der "Anfangswert" (der im ersten Konfigurationsschritt einmal in den Cache übertragen wurde) und soll anschließend vom Benutzer über die Benutzeroberfläche von CMake geändert werden.

Verweise







cmake