CMake 从入门到崩溃4 - 基础语法之函数和宏

CMake 从入门到崩溃4 - 基础语法之函数和宏

函数

function(<someName> [<arg1> ...])
<commands>
endfunction()

🔑 CMake 函数名不区分大小写

函数可以接受两种参数:命名参数和可选参数,命名参数是强制性的,如果不提供,会抛异常

可选参数可以通过一些预定义的变量来访问

  • ARGC
    • 参数的总数(命名参数+可选参数)
  • ARGV
    • 包含命名参数和可选参数的参数列表
  • ARGN
    • 仅包含可选参数的参数列表
  • ARGV0, ARGV1, ARGV2......
    • 分别对应这些位置的参数,引用一个超过 ARGC 的参数是未定义行为

由于 CMake 函数没有返回值且函数有自己的作用域,在函数里执行 set 不会反映到外层作用域的变量上,因此 CMake 引入了 PARENT_SCOPE 关键词,用于设置外层作用域的变量

可以调用 return() 以提前退出某个函数

macro(<name> [<arg1> ...])  
<commands>  
endmacro()

在宏里面调用 return() ,会导致宏的调用者返回,因此避免在宏中使用 return()

函数 VS 宏

函数有自己的作用域,而宏没有,意味着宏里面的变量设置会渗透到调用者的作用域中去

另一个区别在于参数传递的方式,在函数中 ARGN, ARGC, ARGV, ARGV0, ARGV1 等是真实的 CMake 变量,而对于宏来说其实是做了字符串替换,因此可能产生一些奇怪的错误

macro(print_list my_list)
  foreach(var IN LISTS my_list)
    message("${var}")
  endforeach()
endmacro()

set(my_list a b c d)
set(my_list_of_numbers 1 2 3 4)
print_list(my_list_of_numbers)
# prints:
# a
# b
# c
# d

重定义函数和宏

定义函数和宏时,如果已经有一个同名的函数或宏存在,那么前一个命令将被覆盖掉,但仍能通过下划线加名字的方式访问前一个命令

如果再次定义该命令,那么带下划线的名字只能访问前一次的定义,最初的定义就被永远的覆盖掉了

posted @ 2022-02-27 21:25  路过的摸鱼侠  阅读(325)  评论(0编辑  收藏  举报