cmake:macro、endmacro 男娘i 2022-11-15 01:15 115阅读 0赞 # macro # 开始记录一个宏,以便以后作为命令调用 macro(<name> [<arg1> ...]) <commands> endmacro() 定义了一个名为< name >的宏,它接受名为< arg1 >,…在宏之后,但在匹配的endmacro()之前列出的命令,在宏被调用之前不会执行。 每个遗留的endmacro()命令允许一个可选的< name >参数。如果使用,它必须是打开宏命令的参数的逐字重复。 请参阅cmake\_policy()命令文档了解宏中策略的行为。 关于CMake宏和函数之间的区别,请参阅下面的宏和函数部分。 ## 调用 ## 宏调用是不区分大小写的。一个宏定义为 macro(foo) <commands> endmacro() 可以通过任何 foo() Foo() FOO() cmake_language(CALL foo) 等等。但是,强烈建议使用宏定义中选择的案例。通常,宏使用全小写名称。 3.18新版功能:cmake\_language(CALL…)命令也可以用来调用宏。 ## 参数 ## 当调用宏时,宏中记录的命令首先用传递的参数替换正式参数($\{arg1\},…),然后作为普通命令调用。 除了引用正式参数之外,您还可以引用值`${ARGC}`,它将被设置为传递到函数中的参数的数量,以及`${ARGV0}, ${ARGV1}, ${ARGV2},…`它将具有传入参数的实际值。这有助于创建带有可选参数的宏。 此外,`${ARGV}`保存给宏的所有参数的列表,`${ARGN}`保存超过最后一个期望参数的参数列表。引用`${ARGC}`以外的`${ARGV#}`参数有未定义的行为。检查`${ARGC}`是否大于\#是确保`${ARGV#}`作为额外参数传递给函数的唯一方法。 # endmacro # 结束宏块中的命令列表。 endmacro([<name>]) 请参见macro()命令。 可选的参数只支持向后兼容。如果使用它,它必须完全重复打开宏命令的参数。 # Macro vs Function # ## 相同点 ## macro 形式如下: macro(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endmacro(<name>) function 形式如下: function(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... function(<name>) 定义一个名称为 name 的宏 (函数),arg1… 是传入的参数我们除了可以用 $\{arg1\} 来引用变量以外, 系统为我们提供了一些特殊的变量: <table> <thead> <tr> <th>变量</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td><code>ARGV#</code></td> <td># 是一个下标,0 指向第一个参数,累加</td> </tr> <tr> <td><code>ARGV</code></td> <td>所有的定义时要求传入的参数</td> </tr> <tr> <td><code>ARGN</code></td> <td>定义时要求传入的参数以外的参数,比如定义宏(函数)时,要求输入 1 个,书记输入了 3 个,则剩下的两个会以数组形式存储在 ARGN 中</td> </tr> <tr> <td><code>ARGC</code></td> <td>传入的实际参数的个数,也就是调用函数是传入的参数个数</td> </tr> </tbody> </table> ## 不同点 ## > * 在函数中,ARGN,ARGC,ARGV和ARGV0,ARGV1。。。是通常意义上的真变量。在宏中,它们不是,而是字符串替换,很像C预处理器对宏所做的那样 因为ARGN, ARGC, ARGV, ARGV0等不是变量,因此,如下命令是错误的: if(ARGV1) # ARGV1 is not a variable if(DEFINED ARGV2) # ARGV2 is not a variable if(ARGC GREATER 2) # ARGC is not a variable foreach(loop_var IN LISTS ARGN) # ARGN is not a variable 正确写法如下: if(${ ARGV1}) if(DEFINED ${ ARGV2}) if(${ ARGC} GREATER 2) foreach(loop_var IN LISTS ${ ARGN}) or set(list_var "${ARGN}") foreach(loop_var IN LISTS list_var) 请注意,如果在调用宏的作用域中有一个同名的变量,那么使用未引用的名称将使用现有的变量而不是参数。例如: macro(bar) foreach(arg IN LISTS ARGN) <commands> endforeach() endmacro() function(foo) bar(x y z) endfunction() foo(a b c) 会在a;b;c上循环而不是在x;y;z上循环。如果您想要真正的CMake变量和/或更好的CMake范围控制,您应该查看function命令。 > * 宏和函数之间的另一个区别是控制流。通过将控制从调用语句转移到函数体来执行函数。宏的执行就像宏体被粘贴在调用语句的位置一样。其结果是宏体中的return()不仅仅终止宏的执行;相反,从宏调用的作用域返回控件。**为了避免混淆,建议在宏中完全避免return()** > * 与函数不同,不为宏设置CMAKE\_CURRENT\_FUNCTION, CMAKE\_CURRENT\_FUNCTION\_LIST\_DIR, CMAKE\_CURRENT\_FUNCTION\_LIST\_FILE, CMAKE\_CURRENT\_FUNCTION\_LIST\_LINE变量没有为宏设置。 # 例子1 # macro(FOO arg1 arg2 arg3) message(STATUS "this is arg1:${arg1},ARGV0=${ARGV0}") message(STATUS "this is arg2:${arg2},ARGV1=${ARGV1}") message(STATUS "this is arg3:${arg3},ARGV2=${ARGV2}") message(STATUS "this is argc:${ARGC}") message(STATUS "this is args:${ARGV},ARGN=${ARGN}") if(arg1 STREQUAL one) message(STATUS "this is arg1") endif() if(ARGV2 STREQUAL "two") message(STATUS "this is arg2") endif() set(${ arg1} nine) message(STATUS "after set arg1=${${arg1}}") endmacro(FOO) function(BAR arg1) message(STATUS "this is arg1:${arg1},ARGV0=${ARGV0}") message(STATUS "this is argn:${ARGN}") if(arg1 STREQUAL first) message(STATUS "this is first") endif() set(arg1 ten) message(STATUS "after set arg1=${arg1}") endfunction(BAR arg1) set(p1 one) set(p2 two) set(p3 three) set(p4 four) set(p5 five) set(p6 first) set(p7 second) FOO(${ p1} ${ p2} ${ p3} ${ p4} ${ p5}) BAR(${ p6} ${ p7}) message(STATUS "after bar p6=${p6}") 输出结果如下: ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaXpoZW5nZ3Vhbg_size_16_color_FFFFFF_t_70] # 例子2 # macro(_bar) foreach(arg IN LISTS ARGN) message(STATUS "this is in macro ${arg}") endforeach() endmacro() function(_foo) foreach(arg IN LISTS ARGN) message(STATUS "this in function is ${arg}") endforeach() _bar(x y z) endfunction() _foo(a b c) 看一下输出: ![在这里插入图片描述][20210330155124815.png] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaXpoZW5nZ3Vhbg_size_16_color_FFFFFF_t_70]: /images/20221022/02e69b809ac841fa973aa8deca799364.png [20210330155124815.png]: /images/20221022/be4942b6d8444affbc96930db668d9b1.png
还没有评论,来说两句吧...