Spec-Zone.ru › CMake 3.14

macro

Начать запись макроса для последующего вызова в качестве команды

macro(<name> [<arg1> ...])
  <commands>
endmacro()

Определяет макрос с именем <name>, который принимает аргументы с именами <arg1>, … Команды, перечисленные после макроса, но до соответствующей endmacro(), не выполняются до вызова макроса.

В соответствии с устаревшими соглашениями, команда endmacro() допускает необязательный аргумент <name>. Если используется, он должен быть дословным повторением аргумента открывающей команды macro.

См. документацию по команде cmake_policy() для получения информации о поведении политик внутри макросов.

См. раздел Макрос против функции ниже, чтобы узнать о различиях между макросами CMake и functions.

Вызов

Вызов макроса не чувствителен к регистру. Макрос, определенный как

macro(foo)
  <commands>
endmacro()

может быть вызван через любой из

foo()
Foo()
FOO()

и так далее. Однако настоятельно рекомендуется придерживаться регистра, выбранного в определении макроса. Как правило, макросы используют имена в нижнем регистре.

Аргументы

Когда вызывается макрос, команды, записанные в макросе, сначала изменяются путем замены формальных параметров (${arg1}, …) на переданные аргументы, а затем вызываются как обычные команды.

В дополнение к ссылкам на формальные параметры, вы можете ссылаться на значения ${ARGC}, которые будут установлены в количестве аргументов, переданных в функцию, а также ${ARGV0}, ${ARGV1}, ${ARGV2}, … которые будут иметь фактические значения переданных аргументов. Это облегчает создание макросов с необязательными аргументами.

Кроме того, ${ARGV} содержит список всех аргументов, переданных макросу, а ${ARGN} содержит список аргументов после последнего ожидаемого аргумента. Ссылка на ${ARGV#} аргументов за пределами ${ARGC} имеет неопределенное поведение. Проверка того, что ${ARGC} больше, чем #, является единственным способом убедиться, что ${ARGV#} был передан функции в качестве дополнительного аргумента.

Макрос против функции

Команда macro очень похожа на команду function(). Тем не менее, есть несколько важных отличий.

В функции ARGN, ARGC, ARGV и ARGV0, ARGV1, … являются истинными переменными в обычном смысле CMake. В макросе они не являются переменными, они являются заменами строк, подобно тому, как это делал бы препроцессор C с макросом. Это имеет ряд последствий, как объясняется в разделе Оговорки по аргументам ниже.

Другое различие между макросами и функциями заключается в управлении потоком. Функция выполняется путем передачи управления от вызывающего оператора к телу функции. Макрос выполняется так, как если бы тело макроса было вставлено вместо вызывающего оператора. Это имеет следствием, что return() в теле макроса не просто завершает выполнение макроса; скорее, управление возвращается из области вызова макроса. Во избежание путаницы рекомендуется вообще избегать использования return() в макросах.

Оговорки по аргументам

Так как ARGN, ARGC, ARGV, ARGV0 и т.д. не являются переменными, вы НЕ сможете использовать такие команды, как

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)
    <commands>
  endforeach()
endmacro()

function(foo)
  bar(x y z)
endfunction()

foo(a b c)

Будет перебирать a;b;c а не x;y;z, как можно было бы ожидать. Если вам нужны истинные переменные CMake и/или лучший контроль области видимости CMake, вам следует посмотреть на команду function.

© 2000–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.14/command/macro.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API