Oficjalny dokument CMake 2.8.12 mówi omacro
Po wywołaniu polecenia zapisane w makrze są najpierw modyfikowane przez zastąpienie parametrów formalnych ($ {arg1}) przekazanymi argumentami, a następnie wywoływane jak zwykłe polecenia.
i o function
Po wywołaniu polecenia zapisane w funkcji są najpierw modyfikowane przez zastąpienie parametrów formalnych ($ {arg1}) przekazanymi argumentami, a następnie wywoływane jako zwykłe polecenia.
Oczywiście dwa cytaty są prawie takie same, ale mnie mylą. Czy najpierw zastępuje parametry podczas wywoływania funkcji, tak jak makro?
function
imacro
: semantykareturn()
: Gdy zostanie użyta w amacro
, nie powrócisz z makra, ale z funkcji wywołującej.${ARGV}
od wewnątrz:macro(my_macro)
,function(my_func)
. I korzystać z nich:set(a 123)
,my_macro("\\\${a}\\\\;\\\;;")
,my_func(\${a}\\;\;;)
. Przekonasz się, że masz do podwójnej ucieczki wszystko$
,\
,;
aby prawidłowo przechodzić cały ciąg niezmienionej do zagnieżdżonych poleceń. To jest aktualne wcmake 3.14+
.Odpowiedzi:
Poniżej napisałem przykładowy kod:
a wynik to:
Wydaje się więc, że
arg
przypisano wartośćvar
, gdy dzwoniFoo
i${arg}
jest po prostu ciąg zastąpione${var}
podczas wywoływaniaMoo
.Myślę więc, że powyższe dwa cytaty są bardzo łatwe do pomylenia, chociaż oficjalne dokumenty również mówią że :
źródło
cmake --trace-expand
jest pouczającemessage("# arg in main scope = '${arg}'")
+ wywołanie funkcji przed makrem.Innymi słowy, funkcja wypycha i zdejmuje nowy zakres zmiennej (utworzone i zmienione zmienne istnieją tylko w funkcji), makro nie. Można jednak przesłonić domyślne zachowanie funkcji
PARENT_SCOPE
parametremset
polecenia.źródło
Cytowana przez ciebie dokumentacja cmake jest tak myląca, że w zasadzie jest błędna. Należy to wyjaśnić / naprawić w następujący sposób:
cmake --trace-expand
pokazuje dokładnie, co się dzieje.Dokument cmake 3.13.3 nie zmienił się w porównaniu z wersją 2.8.12 pod tym względem.
źródło
Inną zauważalną różnicą między
function()
imacro()
jest zachowaniereturn()
.Z dokumentacji cmake zwrotu () :
Tak więc, ponieważ jest rozwijany w miejscu, w a
macro()
wraca od wywołującego. W funkcji po prostu wychodzi zfunction()
Przykład:
źródło
Rozszerzenie makro, na które odpowiedział Yantao Xie, naprawdę otwiera mi oczy!
Zauważyłem również, że poniższy samouczek zawiera kilka konkretnych przykładów, które są pomocne w zrozumieniu pojęcia zakresu zmiennych.
Cytowane z Learn cmake w 15 minut :
W CMake możesz użyć pary plików
function
endfunction
poleceń / do zdefiniowania funkcji. Oto przykład, który podwaja wartość liczbową swojego argumentu, a następnie wyświetla wynik:Funkcje działają we własnym zakresie. Żadna ze zmiennych zdefiniowanych w funkcji nie zanieczyszcza zakresu wywołującego. Jeśli chcesz zwrócić wartość, możesz przekazać nazwę zmiennej do swojej funkcji, a następnie wywołać
set
polecenie ze specjalnym argumentemPARENT_SCOPE
:Podobnie, para
macro
/endmacro
poleceń definiuje makro. W przeciwieństwie do funkcji makra działają w tym samym zakresie co ich obiekt wywołujący. Dlatego wszystkie zmienne zdefiniowane wewnątrz makra są ustawiane w zakresie wywołującego. Możemy zastąpić poprzednią funkcję następującą:Zarówno funkcje, jak i makra akceptują dowolną liczbę argumentów. Nienazwane argumenty są przedstawiane funkcji jako lista za pośrednictwem specjalnej zmiennej o nazwie
ARGN
.Oto funkcja, która podwaja każdy otrzymany argument, wypisując każdy z nich w osobnym wierszu:
źródło