Spec-Zone.ru › CMake 3.31

macro

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

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

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

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

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

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

Вызов

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

macro(foo)
  <commands>
endmacro()

можно вызвать любым из

foo()
Foo()
FOO()
cmake_language(CALL foo)

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

Добавлена в версии 3.18: Команда cmake_language(CALL ...) также может быть использована для вызова макроса.

Аргументы

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

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

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

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

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

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

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

В отличие от функции, переменные CMAKE_CURRENT_FUNCTION, CMAKE_CURRENT_FUNCTION_LIST_DIR, CMAKE_CURRENT_FUNCTION_LIST_FILE, CMAKE_CURRENT_FUNCTION_LIST_LINE для макроса не задаются.

Особенности аргументов

Поскольку 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.

См. также

  • cmake_parse_arguments()
  • endmacro()

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

Spec-Zone.ru

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