Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function vs. Macro in CMake

Tags:

cmake

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?

like image 568
Yantao Xie Avatar asked Jun 19 '14 02:06

Yantao Xie


People also ask

What is a CMake macro?

CMake supports both functions and macros to provide a named abstraction for some repetitive works. A function or macro always define a new command.

How does CMake function return value?

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.

What is option in CMake?

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


2 Answers

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.

like image 149
Yantao Xie Avatar answered Oct 10 '22 20:10

Yantao Xie


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.

like image 29
robert Avatar answered Oct 10 '22 22:10

robert