El documento oficial de CMake 2.8.12 dice sobremacro
Cuando se invoca, los comandos registrados en la macro se modifican primero reemplazando los parámetros formales ($ {arg1}) con los argumentos pasados y luego se invocan como comandos normales.
y sobre function
Cuando se invoca, los comandos registrados en la función se modifican primero reemplazando los parámetros formales ($ {arg1}) con los argumentos pasados y luego se invocan como comandos normales.
Obviamente, dos citas son casi iguales pero me confunden. ¿Reemplaza los parámetros al principio cuando se llama a una función como una macro?
function
ymacro
: la semántica dereturn()
: Cuando se usa en amacro
, no regresará de la macro sino de la función de llamada.${ARGV}
desde adentro:macro(my_macro)
,function(my_func)
. Y utilizarlos:set(a 123)
,my_macro("\\\${a}\\\\;\\\;;")
,my_func(\${a}\\;\;;)
. Usted encontrará que hay que hacer doble escape de todo el$
,\
,;
para pasar adecuadamente toda la cadena sin cambios a los comandos anidados. Esto es real en elcmake 3.14+
.Respuestas:
Escribí un código de muestra a continuación:
y la salida es:
Así que parece que
arg
se le asigna el valor devar
cuando se llamaFoo
y${arg}
solo se reemplaza la cadena con${var}
cuando se llamaMoo
.Así que creo que las dos citas anteriores son muy fáciles de confundir, aunque los documentos oficiales también dicen que :
fuente
cmake --trace-expand
es esclarecedormessage("# arg in main scope = '${arg}'")
+ llamar a la función antes de la macro.En otras palabras, la función empuja y muestra el nuevo alcance de la variable (las variables creadas y cambiadas existen solo en la función), la macro no. Sin embargo, puede anular el comportamiento predeterminado de la función con el
PARENT_SCOPE
parámetro delset
comando.fuente
La documentación de cmake que citó es tan engañosa que básicamente es incorrecta. Debería aclararse / arreglarse así:
cmake --trace-expand
muestra exactamente lo que sucede.El documento cmake 3.13.3 no ha cambiado en comparación con 2.8.12 con respecto a esto.
fuente
Otra diferencia notable entre
function()
ymacro()
es el comportamiento dereturn()
.De la documentación de cmake de return () :
Entonces, debido a que se expande en su lugar,
macro()
regresa de la persona que llama. Mientras está en una función, simplemente sale delfunction()
Ejemplo:
fuente
La macro expansión, respondida por Yantao Xie realmente me abre los ojos!
También encontré que el tutorial a continuación viene con algunos ejemplos concretos, lo cual es útil para comprender el concepto de alcance variable.
Citado de Learn cmake en 15 minutos :
En CMake, puede usar un par de comandos
function
/endfunction
para definir una función. Aquí hay uno que duplica el valor numérico de su argumento y luego imprime el resultado:Las funciones se ejecutan en su propio ámbito. Ninguna de las variables definidas en una función contamina el alcance de la persona que llama. Si desea devolver un valor, puede pasar el nombre de una variable a su función, luego llamar al
set
comando con el argumento especialPARENT_SCOPE
:Del mismo modo, un par de
macro
endmacro
comandos / define una macro. A diferencia de las funciones, las macros se ejecutan en el mismo ámbito que su llamador. Por lo tanto, todas las variables definidas dentro de una macro se establecen en el alcance del llamador. Podemos reemplazar la función anterior por la siguiente:Tanto las funciones como las macros aceptan un número arbitrario de argumentos. Los argumentos sin nombre se exponen a la función como una lista, a través de una variable especial llamada
ARGN
.Aquí hay una función que duplica cada argumento que recibe, imprimiendo cada uno en una línea separada:
fuente