Spec-Zone.ru › CMake

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} приводит к неопределённому поведению. Единственный способ убедиться, что ${ARGV#} был передан функции в качестве дополнительного аргумента, — проверить, что ${ARGC} больше #.

Макрос или функция

Команда 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–2026 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/latest/command/macro.html

Spec-Zone.ru

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