В официальном документе CMake 2.8.12 говорится оmacro
Когда он вызывается, команды, записанные в макросе, сначала модифицируются путем замены формальных параметров ($ {arg1}) переданными аргументами, а затем вызываются как обычные команды.
и о function
При его вызове команды, записанные в функции, сначала изменяются путем замены формальных параметров ($ {arg1}) переданными аргументами, а затем вызываются как обычные команды.
Очевидно, две цитаты почти одинаковы, но сбивают меня с толку. Заменяет ли сначала параметры при вызове функции точно так же, как макрос?
function
иmacro
: семантикаreturn()
: при использовании в amacro
вы возвращаетесь не из макроса, а из вызывающей функции.${ARGV}
изнутри:macro(my_macro)
,function(my_func)
. И использовать их:set(a 123)
,my_macro("\\\${a}\\\\;\\\;;")
,my_func(\${a}\\;\;;)
. Вы обнаружите , что у вас есть двойной побег все$
,\
,;
чтобы правильно передать всю строку без изменений на вложенные команды. Это актуально вcmake 3.14+
.Ответы:
Я написал пример кода ниже:
и вывод:
Так что , похоже
arg
присваивается значениеvar
при вызовеFoo
и${arg}
просто строка заменяется${var}
при вызовеMoo
.Поэтому я думаю, что приведенные выше две цитаты очень легко сбить с толку, хотя в официальных документах также сказано, что :
источник
cmake --trace-expand
поучительноmessage("# arg in main scope = '${arg}'")
+ вызов функции перед макросом.Другими словами, функция подталкивает и выталкивает новую область видимости переменной (созданные и измененные переменные существуют только в функции), макрос - нет. Однако вы можете переопределить поведение функции по умолчанию с помощью
PARENT_SCOPE
параметраset
команды.источник
Приведенная вами документация по cmake настолько вводит в заблуждение, что в корне неверна. Это нужно уточнить / исправить так:
cmake --trace-expand
показывает, что именно происходит.Документ cmake 3.13.3 не изменился по сравнению с 2.8.12 в этом отношении.
источник
Еще одно заметное различие между
function()
иmacro()
- это поведениеreturn()
.Из документации cmake для return () :
Так как он расширяется на месте,
macro()
он возвращается от вызывающего. Находясь в функции, он просто выходит изfunction()
Пример:
источник
Макрорасширения ответили Yantao С действительно открывает мне глаза!
Я также обнаружил, что в приведенном ниже руководстве есть несколько конкретных примеров, которые помогают понять концепцию области видимости переменных.
Цитируется по Learn cmake за 15 минут :
В CMake вы можете использовать пару команд
function
/endfunction
для определения функции. Вот тот, который удваивает числовое значение своего аргумента, а затем выводит результат:Функции выполняются в своей собственной области. Ни одна из переменных, определенных в функции, не загрязняет область действия вызывающего. Если вы хотите вернуть значение, вы можете передать имя переменной своей функции, а затем вызвать
set
команду со специальным аргументомPARENT_SCOPE
:Точно так же пара команд
macro
/endmacro
определяет макрос. В отличие от функций, макросы выполняются в той же области, что и их вызывающий объект. Следовательно, все переменные, определенные внутри макроса, устанавливаются в области действия вызывающего. Мы можем заменить предыдущую функцию следующей:И функции, и макросы принимают произвольное количество аргументов. Безымянные аргументы предоставляются функции в виде списка через специальную переменную с именем
ARGN
.Вот функция, которая удваивает каждый получаемый аргумент, выводя каждый из них в отдельной строке:
источник