macro
Начать запись макроса для последующего вызова как команды:
macro(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endmacro(<name>)
Определите макрос с именем <name>, который принимает аргументы с именами arg1, arg2, arg3, (…). Команды, перечисленные после макроса, но перед соответствующим endmacro(), не вызываются до тех пор, пока макрос не будет вызван. Когда он вызывается, команды, записанные в макросе, сначала изменяются путем замены формальных параметров (${arg1}) переданными аргументами, а затем вызываются как обычные команды. В дополнение к ссылке на формальные параметры, вы можете сослаться на значения ${ARGC}, которые будут установлены в количество переданных аргументов, а также на ${ARGV0}, ${ARGV1}, ${ARGV2}, …, которые будут иметь фактические значения переданных аргументов. Это облегчает создание макросов с необязательными аргументами. Кроме того, ${ARGV} содержит список всех аргументов, переданных макросу, а ${ARGN} содержит список аргументов, следующих за последним ожидаемым аргументом. Ссылка на аргументы ${ARGV#} за пределами ${ARGC} имеет неопределённое поведение. Проверка того, что ${ARGC} больше, чем #, является единственным способом гарантировать, что ${ARGV#} был передан в функцию в качестве дополнительного аргумента.
Обратитесь к документации команды cmake_policy() для получения информации о поведении политик внутри макросов.
Осторожность при использовании аргументов макроса
Обратите внимание, что параметры макроса и значения, такие как ARGN, не являются переменными в обычном смысле CMake. Они представляют собой подстановку строк, аналогично тому, как это делал бы препроцессор C с макросом. Поэтому вы НЕ сможете использовать команды, такие как:
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
В первом случае вы можете использовать if(${ARGV1}). Во втором и третьем случае правильным способом проверки того, был ли необязательный аргумент передан в макрос, является использование if(${ARGC} GREATER 2). В последнем случае вы можете использовать foreach(loop_var ${ARGN}), но это пропустит пустые аргументы. Если вам нужно включить их, вы можете использовать:
set(list_var "${ARGN}")
foreach(loop_var IN LISTS list_var)
Обратите внимание, что если у вас есть переменная с тем же именем в области видимости, из которой вызывается макрос, использование неиспользуемых имён будет использовать существующую переменную вместо аргументов. Например:
macro(_BAR)
foreach(arg IN LISTS ARGN)
[...]
endforeach()
endmacro()
function(_FOO)
_bar(x y z)
endfunction()
_foo(a b c)
Будет перебирать a;b;c, а не x;y;z, как можно было ожидать. Если вам нужны настоящие переменные CMake и/или лучший контроль над областью видимости CMake, вам следует обратиться к команде функции.
© 2000–2019 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.11/command/macro.html