web-dev-qa-db-fra.com

Fonction vs Macro dans CMake

Le document officiel de CMake 2.8.12 dit à propos de macro

Lors de l'appel, 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 appelées en tant que commandes normales.

et à propos de function

Lorsqu'il est appelé, 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 appelées en tant que commandes normales.

De toute évidence, deux citations sont presque les mêmes mais me déroutent. Est-ce que les paramètres de remplacement en premier lors de l'appel d'une fonction comme macro?

75
Yantao Xie

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 le résultat 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

Il semble donc que arg se voit attribuer la valeur de var lors de l'appel de Foo et de ${arg} est juste une chaîne remplacée par ${var} lorsque vous appelez Moo.

Je pense donc que les deux citations ci-dessus sont très faciles à confondre, bien que les documents officiels indiquent également que:

Ce sont des remplacements de chaînes, un peu comme le ferait le préprocesseur avec une macro. Si vous voulez de vraies variables CMake et/ou un meilleur contrôle de la portée de CMake, consultez la commande function.

81
Yantao Xie

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

29
robert

La documentation de cmake que vous avez citée est tellement trompeuse que c'est fondamentalement faux. Cela devrait être clarifié/corrigé comme ceci:

  • macro: lorsqu’elle est appelée, les commandes enregistrées dans la macro sont toutes d’abord modifiées avant toute exécution en remplaçant les paramètres formels ($ {arg1}) par les arguments passés.

cmake --trace-expand montre exactement ce qui se passe.

Le cmake 3.13.3 doc n'a pas changé par rapport à 2.8.12 à cet égard.

4
MarcH