macro¶
Start recording a macro for later invocation as a command
macro(<name> [<arg1> ...])
<commands>
endmacro()
Defines a macro named <name>
that takes arguments named
<arg1>
, … Commands listed after macro, but before the
matching endmacro()
, are not executed until the macro
is invoked.
Per legacy, the endmacro()
command admits an optional
<name>
argument. If used, it must be a verbatim repeat of the
argument of the opening macro
command.
See the cmake_policy()
command documentation for the behavior
of policies inside macros.
See the Macro vs Function section below for differences
between CMake macros and functions
.
Invocation¶
The macro invocation is case-insensitive. A macro defined as
macro(foo)
<commands>
endmacro()
can be invoked through any of
foo()
Foo()
FOO()
and so on. However, it is strongly recommended to stay with the case chosen in the macro definition. Typically macros use all-lowercase names.
Arguments¶
When a macro 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.
In addition to referencing the formal parameters you can reference the
values ${ARGC}
which will be set to the number of arguments passed
into the function as well as ${ARGV0}
, ${ARGV1}
, ${ARGV2}
,
… which will have the actual values of the arguments passed in.
This facilitates creating macros with optional arguments.
Furthermore, ${ARGV}
holds the list of all arguments given to the
macro and ${ARGN}
holds the list of arguments past the last expected
argument.
Referencing to ${ARGV#}
arguments beyond ${ARGC}
have undefined
behavior. Checking that ${ARGC}
is greater than #
is the only
way to ensure that ${ARGV#}
was passed to the function as an extra
argument.
Macro vs Function¶
The macro
command is very similar to the function()
command.
Nonetheless, there are a few important differences.
In a function, ARGN
, ARGC
, ARGV
and ARGV0
, ARGV1
, …
are true variables in the usual CMake sense. In a macro, they are not,
they are string replacements much like the C preprocessor would do
with a macro. This has a number of consequences, as explained in
the Argument Caveats section below.
Another difference between macros and functions is the control flow.
A function is executed by transferring control from the calling
statement to the function body. A macro is executed as if the macro
body were pasted in place of the calling statement. This has the
consequence that a return()
in a macro body does not
just terminate execution of the macro; rather, control is returned
from the scope of the macro call. To avoid confusion, it is recommended
to avoid return()
in macros altogether.
Argument Caveats¶
Since ARGN
, ARGC
, ARGV
, ARGV0
etc. are not variables,
you will NOT be able to use commands like
if(ARGV1) # ARGV1 is not a variable
if(DEFINED ARGV2) # ARGV2 is not a variable
if(ARGC GREATER 2) # ARGC is not a variable
foreach(loop_var IN LISTS ARGN) # ARGN is not a variable
In the first case, you can use if(${ARGV1})
. In the second and
third case, the proper way to check if an optional variable was
passed to the macro is to use if(${ARGC} GREATER 2)
. In the
last case, you can use foreach(loop_var ${ARGN})
but this will
skip empty arguments. If you need to include them, you can use
set(list_var "${ARGN}")
foreach(loop_var IN LISTS list_var)
Note that if you have a variable with the same name in the scope from which the macro is called, using unreferenced names will use the existing variable instead of the arguments. For example:
macro(bar)
foreach(arg IN LISTS ARGN)
<commands>
endforeach()
endmacro()
function(foo)
bar(x y z)
endfunction()
foo(a b c)
Will loop over a;b;c
and not over x;y;z
as one might have expected.
If you want true CMake variables and/or better CMake scope control you
should look at the function command.