Function vs. Macro in CMake

I wrote a sample code below:

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})

and the output is:

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

So it seems arg is assigned the value of var when calling Foo and ${arg} is just string replaced with ${var} when calling Moo.

So I think the above two quotes are very easy to make one confused, although the official documents also said that:

Note that the parameters to a macro and values such as ARGN are not variables in the usual CMake sense. They are string replacements much like the C preprocessor would do
with a macro. If you want true CMake variables and/or better CMake
scope control you should look at the function command.

UPDATE (1/29/2021)

Add the following statement after the statement Moo(${var}) to make the difference between macro and function even more clear.

message(${arg})

This statement will print out abc.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)