Fonction vs Macro dans CMake

Le document officiel de CMake 2.8.12 dit à propos de la macro

Lorsqu’elle est invoquée, les commandes enregistrées dans la macro sont d’abord modifiées en remplaçant les parameters formels ($ {arg1}) par les arguments transmis, puis invoquées en tant que commandes normales.

et à propos de la function

Lorsqu’elle est invoquée, les commandes enregistrées dans la fonction sont d’abord modifiées en remplaçant les parameters formels ($ {arg1}) par les arguments transmis, puis appelées en tant que commandes normales.

De toute évidence, deux citations sont presque identiques mais confondues. Est-ce que remplacer les parameters au début lors de l’appel d’une fonction comme macro?

J’ai écrit un exemple de code ci-dessous

 set(var "ABC") macro(Moo arg) message("arg = ${arg}") set(arg "abc") message("# After change the value of arg.") message("arg = ${arg}") endmacro() message("=== Call macro ===") Moo(${var}) function(Foo arg) message("arg = ${arg}") set(arg "abc") message("# After change the value of arg.") message("arg = ${arg}") endfunction() message("=== Call function ===") Foo(${var}) 

et la sortie est

 === Call macro === arg = ABC # After change the value of arg. arg = ABC === Call function === arg = ABC # After change the value of arg. arg = abc 

Donc, il semble que arg ait la valeur de var lorsque l’appel Foo et ${arg} sont juste remplacés par ${var} quand on appelle Moo .

Donc, je pense que les deux citations ci-dessus sont très faciles à rendre confus même si les documents officiels ont également déclaré que

Ce sont des remplacements de chaînes comme le ferait le préprocesseur C avec une macro. Si vous voulez de vraies variables CMake et / ou un meilleur contrôle de scope CMake, vous devriez regarder la commande de fonction.

En d’autres termes, la fonction pousse et affiche la nouvelle scope de la variable (les variables créées et modifiées n’existent que dans la fonction), contrairement à la macro. Cependant, vous pouvez remplacer le comportement par défaut de la fonction avec le paramètre PARENT_SCOPE de la commande set .