Function versus Macro in CMake

White Paper CMake 2.8.12 talks about macro

When it is called, the commands written in the macro, changed by replacing the formal parameters ($ {arg1}) with arguments, are executed first and then called like regular commands.

and about function

When it is called, the commands written to the function are first modified by replacing the formal parameters ($ {arg1}) with arguments and then called like regular commands.

Obviously the two quotes are almost the same, but it bothers me. Does it replace parameters first when calling a function, just like a macro?

+72
cmake
Jun 19 '14 at 2:48
source share
3 answers

I wrote an example 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 conclusion:

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

Thus, it seems that arg assigned the value of var when calling Foo and ${arg} simply replaced by a string with ${var} when calling Moo .

Therefore, I think that the two quotes above are very easy to confuse, although official documents also say that:

They are string replacements in much the same way that a C preprocessor would do with a macro. If you want true CMake variables and / or better control of the CMake scope, you should take a look at the function command.

+78
Jun 19 '14 at 2:48
source share

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

+28
Jun 09 '16 at 18:42 on
source share

The cmake documentation you provided is so deceiving that it is basically incorrect. This should be clarified / corrected as follows:

  • macro: when it is called, all commands written in the macro are first modified before running any , replacing the formal parameters ($ {arg1}) with the arguments passed.

cmake --trace-expand shows exactly what is happening.

The cmake 3.13.3 documentation has not changed compared to 2.8.12.

+3
Jan 24 '19 at 18:51
source share



All Articles