Function vs. Macro in CMake

In other words, function pushes and pops new variable scope (variables created and changed exist only in the function), macro does not. However, you can override the function default behaviour with the PARENT_SCOPE parameter of the set command.


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.

Tags:

Cmake