The official document of CMake 2.8.12 says about macro
When it is invoked, the commands recorded in the macro are first modified by replacing formal parameters (${arg1}) with the arguments passed, and then invoked as normal commands.
and about function
When it is invoked, the commands recorded in the function are first modified by replacing formal parameters (${arg1}) with the arguments passed, and then invoked as normal commands.
Obviously, the two quotes are almost the same but it's confusing. Does parameter replacement behave the same in functions and macros?
CMake supports both functions and macros to provide a named abstraction for some repetitive works. A function or macro always define a new command.
Return values from functions There is no built-in notion of a return value from a function. To get values out of a function, write to one of the arguments. Another issue is the variable name for the output value needs to be dereferenced before being set.
Provide a boolean option that the user can optionally select. option(<variable> "<help_text>" [value]) If no initial <value> is provided, boolean OFF is the default value. If <variable> is already set as a normal or cache variable, then the command does nothing (see policy CMP0077 ).
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.
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With