Функция против макроса в CMake
Официальный документ CMake 2.8.12 говорит о macro
Когда он вызывается, сначала выполняются команды, записанные в макросе измененный путем замены формальных параметров ($ {arg1}) на аргументы и затем вызывается как обычные команды.
и около function
Когда он вызывается, команды, записанные в функции, сначала измененный путем замены формальных параметров ($ {arg1}) на аргументы и затем вызывается как обычные команды.
Очевидно, что две цитаты почти одинаковы, но меня смущает. Вначале заменяет параметры при вызове функции точно так же, как макрос?
Ответы
Ответ 1
Я написал пример кода ниже:
set(var "ABC")
macro(Moo arg)
message("arg = ${arg}")
set(arg "abc")
message("# After change the value of arg.")
message("arg = ${arg}")
endmacro()
message("=== Call macro ===")
Moo(${var})
function(Foo arg)
message("arg = ${arg}")
set(arg "abc")
message("# After change the value of arg.")
message("arg = ${arg}")
endfunction()
message("=== Call function ===")
Foo(${var})
и вывод:
=== Call macro ===
arg = ABC
# After change the value of arg.
arg = ABC
=== Call function ===
arg = ABC
# After change the value of arg.
arg = abc
Таким образом, кажется, что arg
присваивается значение var
при вызове Foo
а ${arg}
просто заменяется строкой на ${var}
при вызове Moo
.
Поэтому я думаю, что две приведенные выше цитаты очень легко спутать, хотя в официальных документах также сказано, что:
Они являются заменами строк во многом так же, как препроцессор C сделал бы с макросом. Если вы хотите истинные переменные CMake и/или лучший контроль области CMake, вы должны взглянуть на команду функции.
Ответ 2
Другими словами, функция толкает и всплывает область новой переменной (переменные, созданные и измененные, существуют только в функции), макрос - нет. Однако вы можете переопределить поведение по умолчанию функции с параметром PARENT_SCOPE
команды set
.
Ответ 3
Приведенная вами документация по cmake настолько обманчива, что в принципе неверна. Это следует уточнить/исправить следующим образом:
- макрос: когда он вызывается, все команды, записанные в макросе, сначала модифицируются перед запуском любого, заменяя формальные параметры ($ {arg1}) переданными аргументами.
cmake --trace-expand
показывает, что именно происходит.
Документация cmake 3.13.3 не изменилась по сравнению с 2.8.12.