Le document officiel de CMake 2.8.12 parle demacro
Lorsqu'elle est invoquée, les commandes enregistrées dans la macro sont d'abord modifiées en remplaçant les paramètres formels ($ {arg1}) par les arguments passés, puis invoquées comme des commandes normales.
Et à propos function
Lorsqu'elle est invoquée, les commandes enregistrées dans la fonction sont d'abord modifiées en remplaçant les paramètres formels ($ {arg1}) par les arguments passés, puis invoquées comme des commandes normales.
Évidemment, deux citations sont presque identiques mais me déroutent. Remplace-t-il d'abord les paramètres lors de l'appel d'une fonction comme une macro?
function
etmacro
: la sémantique dereturn()
: Lorsqu'il est utilisé dans amacro
, vous ne reviendrez pas de la macro mais de la fonction appelante.${ARGV}
de l'intérieur:macro(my_macro)
,function(my_func)
. Et les utiliser:set(a 123)
,my_macro("\\\${a}\\\\;\\\;;")
,my_func(\${a}\\;\;;)
. Vous constaterez que vous devez échapper à double tout$
,\
,;
pour passer correctement chaîne entière sans changement aux commandes imbriquées. C'est réel dans lecmake 3.14+
.Réponses:
J'ai écrit un exemple de code ci-dessous:
et la sortie est:
Il semble
arg
donc que la valeur de l'var
appel soit attribuéeFoo
et${arg}
que la chaîne soit simplement remplacée par une chaîne${var}
lors de l'appelMoo
.Je pense donc que les deux citations ci-dessus sont très faciles à confondre, bien que les documents officiels disaient également que :
la source
cmake --trace-expand
est éclairantmessage("# arg in main scope = '${arg}'")
+ appeler la fonction avant la macro.En d'autres termes, la fonction pousse et affiche une nouvelle portée de variable (les variables créées et modifiées n'existent que dans la fonction), ce n'est pas le cas de la macro. Cependant, vous pouvez remplacer le comportement par défaut de la fonction avec le
PARENT_SCOPE
paramètre de laset
commande.la source
La documentation cmake que vous avez citée est tellement trompeuse qu'elle est fondamentalement erronée. Il devrait être clarifié / corrigé comme ceci:
cmake --trace-expand
montre exactement ce qui se passe.Le document cmake 3.13.3 n'a pas changé par rapport à 2.8.12 à ce sujet.
la source
Une autre différence notable entre
function()
etmacro()
est le comportement dereturn()
.À partir de la documentation cmake de return () :
Donc, parce qu'il est étendu sur place, dans un
macro()
il revient de l'appelant. Dans une fonction, il quitte simplement lefunction()
Exemple:
la source
L' expansion macro, répondue par Yantao Xie, m'ouvre vraiment les yeux!
J'ai également trouvé que le didacticiel ci-dessous contient des exemples concrets, ce qui est utile pour comprendre le concept de portée variable.
Cité de Learn cmake in 15 minutes :
Dans CMake, vous pouvez utiliser une paire de commandes
function
/endfunction
pour définir une fonction. En voici un qui double la valeur numérique de son argument, puis imprime le résultat:Les fonctions s'exécutent dans leur propre étendue. Aucune des variables définies dans une fonction ne pollue la portée de l'appelant. Si vous souhaitez renvoyer une valeur, vous pouvez passer le nom d'une variable à votre fonction, puis appeler la
set
commande avec l'argument spécialPARENT_SCOPE
:De même, une paire de commandes
macro
/endmacro
définit une macro. Contrairement aux fonctions, les macros s'exécutent dans la même portée que leur appelant. Par conséquent, toutes les variables définies dans une macro sont définies dans la portée de l'appelant. Nous pouvons remplacer la fonction précédente par la suivante:Les fonctions et les macros acceptent un nombre arbitraire d'arguments. Les arguments sans nom sont exposés à la fonction sous forme de liste, via une variable spéciale nommée
ARGN
.Voici une fonction qui double chaque argument qu'elle reçoit, en imprimant chacun sur une ligne distincte:
la source