Подтвердить что ты не робот

Функция против макроса в CMake

Официальный документ CMake 2.8.12 говорит о macro

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

и около function

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

Очевидно, что две цитаты почти одинаковы, но меня смущает. Вначале заменяет параметры при вызове функции точно так же, как макрос?

4b9b3361

Ответ 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.