O documento oficial do CMake 2.8.12 diz sobremacro
Quando é invocado, os comandos gravados na macro são primeiro modificados pela substituição dos parâmetros formais ($ {arg1}) pelos argumentos passados e, em seguida, invocados como comandos normais.
e sobre function
Quando é invocado, os comandos registrados na função são primeiro modificados pela substituição dos parâmetros formais ($ {arg1}) pelos argumentos passados e, em seguida, invocados como comandos normais.
Obviamente, duas citações são quase iguais, mas me confundem. Substitui os parâmetros primeiro ao chamar uma função como a macro?
function
emacro
: a semântica dereturn()
: Quando usado em amacro
, você não retornará da macro, mas da função de chamada.${ARGV}
de dentro:macro(my_macro)
,function(my_func)
. E usá-los:set(a 123)
,my_macro("\\\${a}\\\\;\\\;;")
,my_func(\${a}\\;\;;)
. Você vai descobrir que você tem que dupla de escape todo o$
,\
,;
para passar corretamente toda corda inalterada aos comandos aninhados. Isso é real nocmake 3.14+
.Respostas:
Escrevi um código de amostra abaixo:
e a saída é:
Portanto, parece que
arg
é atribuído o valor devar
ao chamarFoo
e${arg}
é apenas substituído por string${var}
ao chamarMoo
.Portanto, acho que as duas citações acima são muito fáceis de confundir, embora os documentos oficiais também dissessem que :
fonte
cmake --trace-expand
é esclarecedormessage("# arg in main scope = '${arg}'")
+ chamar a função antes da macro.Em outras palavras, a função empurra e exibe um novo escopo de variável (as variáveis criadas e alteradas existem apenas na função), a macro não. No entanto, você pode substituir o comportamento padrão da função com o
PARENT_SCOPE
parâmetro doset
comando.fonte
A documentação do cmake que você citou é tão enganosa que está basicamente errada. Deve ser esclarecido / corrigido assim:
cmake --trace-expand
mostra exatamente o que acontece.O doc cmake 3.13.3 não mudou em comparação com 2.8.12 com relação a isso.
fonte
A expansão macro, respondida por Yantao Xie realmente abre meus olhos!
Também descobri que o tutorial abaixo vem com alguns exemplos concretos, o que é útil para entender o conceito de escopo de variável.
Citado em Learn cmake in 15 mins :
No CMake, você pode usar um par de
function
/endfunction
comandos para definir uma função. Aqui está um que duplica o valor numérico de seu argumento e, em seguida, imprime o resultado:As funções são executadas em seu próprio escopo. Nenhuma das variáveis definidas em uma função poluem o escopo do chamador. Se quiser retornar um valor, você pode passar o nome de uma variável para sua função e, em seguida, chamar o
set
comando com o argumento especialPARENT_SCOPE
:Da mesma forma, um par de comandos
macro
/endmacro
define uma macro. Ao contrário das funções, as macros são executadas no mesmo escopo de seu chamador. Portanto, todas as variáveis definidas dentro de uma macro são definidas no escopo do chamador. Podemos substituir a função anterior pela seguinte:Ambas as funções e macros aceitam um número arbitrário de argumentos. Argumentos sem nome são expostos à função como uma lista, por meio de uma variável especial chamada
ARGN
.Aqui está uma função que dobra todos os argumentos que recebe, imprimindo cada um em uma linha separada:
fonte
Outra diferença notável entre
function()
emacro()
é o comportamento dereturn()
.Da documentação cmake de return () :
Portanto, como ele é expandido no local,
macro()
ele retorna do chamador. Enquanto em uma função, ele apenas sai dofunction()
Exemplo:
fonte