Das offizielle Dokument von CMake 2.8.12 sagt übermacro
Wenn es aufgerufen wird, werden die im Makro aufgezeichneten Befehle zuerst geändert, indem formale Parameter ($ {arg1}) durch die übergebenen Argumente ersetzt und dann als normale Befehle aufgerufen werden.
und über function
Beim Aufrufen werden die in der Funktion aufgezeichneten Befehle zuerst geändert, indem formale Parameter ($ {arg1}) durch die übergebenen Argumente ersetzt und dann als normale Befehle aufgerufen werden.
Offensichtlich sind zwei Zitate fast gleich, aber verwirrend. Ersetzt man zuerst Parameter, wenn man eine Funktion wie ein Makro aufruft?
function
undmacro
: die Semantik vonreturn()
: Bei Verwendung in amacro
kehren Sie nicht vom Makro zurück, sondern von der aufrufenden Funktion.${ARGV}
von innen:macro(my_macro)
,function(my_func)
. Und nutzen sie:set(a 123)
,my_macro("\\\${a}\\\\;\\\;;")
,my_func(\${a}\\;\;;)
. Sie werden feststellen, dass Sie alle Zeichen doppelt maskieren$
müssen\
,;
um die gesamte Zeichenfolge unverändert an die verschachtelten Befehle zu übergeben. Dies ist aktuell in dercmake 3.14+
.Antworten:
Ich habe unten einen Beispielcode geschrieben:
und die Ausgabe ist:
Es scheint
arg
also, dass der Wertvar
beim Aufrufen zugewiesen wirdFoo
und${arg}
nur die Zeichenfolge${var}
beim Aufrufen durch ersetzt wirdMoo
.Also ich denke , die beiden oben genannten Zitate sind sehr leicht verwirrt zu machen, obwohl die offiziellen Dokumente auch gesagt , dass :
quelle
cmake --trace-expand
message("# arg in main scope = '${arg}'")
+ Aufruf der Funktion vor dem Makro.Mit anderen Worten, die Funktion pusht und öffnet einen neuen Variablenbereich (erstellte und geänderte Variablen existieren nur in der Funktion), das Makro nicht. Sie können jedoch das Standardverhalten der Funktion mit dem
PARENT_SCOPE
Parameter desset
Befehls überschreiben .quelle
Die von Ihnen zitierte cmake-Dokumentation ist so irreführend, dass sie grundsätzlich falsch ist. Es sollte wie folgt geklärt / behoben werden:
cmake --trace-expand
zeigt genau was passiert.Das cmake 3.13.3-Dokument hat sich diesbezüglich gegenüber 2.8.12 nicht geändert.
quelle
Ein weiterer bemerkenswerter Unterschied zwischen
function()
undmacro()
ist das Verhalten vonreturn()
.Aus der cmake-Dokumentation von return () :
Da es also an Ort und Stelle erweitert wird,
macro()
kehrt es vom Anrufer zurück. Während einer Funktion wird nur die beendetfunction()
Beispiel:
quelle
Die Makro-Erweiterung, die von Yantao Xie beantwortet wurde, öffnet mir wirklich die Augen!
Ich fand auch, dass das folgende Tutorial einige konkrete Beispiele enthält, die hilfreich sind, um das Konzept des variablen Bereichs zu verstehen.
Zitiert von Learn cmake in 15 Minuten :
In CMake können Sie ein Paar
function
/endfunction
Befehle verwenden, um eine Funktion zu definieren. Hier ist eine, die den numerischen Wert ihres Arguments verdoppelt und dann das Ergebnis druckt:Funktionen laufen in ihrem eigenen Bereich. Keine der in einer Funktion definierten Variablen verschmutzt den Bereich des Aufrufers. Wenn Sie einen Wert zurückgeben möchten, können Sie den Namen einer Variablen an Ihre Funktion übergeben und dann den
set
Befehl mit dem speziellen Argument aufrufenPARENT_SCOPE
:In ähnlicher Weise definiert ein Paar von
macro
/endmacro
Befehlen ein Makro. Im Gegensatz zu Funktionen werden Makros im selben Bereich wie ihr Aufrufer ausgeführt. Daher werden alle in einem Makro definierten Variablen im Bereich des Aufrufers festgelegt. Wir können die vorherige Funktion durch folgende ersetzen:Sowohl Funktionen als auch Makros akzeptieren eine beliebige Anzahl von Argumenten. Unbenannte Argumente werden der Funktion als Liste über eine spezielle Variable mit dem Namen angezeigt
ARGN
.Hier ist eine Funktion, die jedes empfangene Argument verdoppelt und jedes in einer separaten Zeile druckt:
quelle