cmake进阶:宏定义

一.  简介

前面学习了 CMakeLists.txt语法中是如何定义函数,本文继续学习 cmake中的宏定义。

二.  cmake进阶:宏定义

cmake 提供了定义宏的方法,cmake 函数 function 宏定义 macro 在某种程度上来说是一样的,都是创建一段有名字的代码可以在后面被调用,还可以传参数。

通过 macro()命令定义宏,如下所示:

macro(<name> [arg1 [arg2 [arg3 ...]]])
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
 ...
endmacro(<name>)

endmacro 括号中的 <name> 可写可不写,如果写了,就必须和 macro 括号中的<name>一致。
参数 name 表示宏定义的名字。
在宏定义中也可以使用前面给大家介绍的 ARGVX(X 是一个数字)、ARGCARGVARGN 这些变量所以这些也是宏定义的内部变量。
在 顶层 CMakeLists.txt 文件中添加如下代码
# macro 宏定义测试
macro(XYZ arg1 arg2)
 message("ARGC: ${ARGC}")
 message("ARGV: ${ARGV}")
 message("ARGN: ${ARGN}")
 message("ARGV0: ${ARGV0}")
 message("ARGV1: ${ARGV1}")

 # 循环打印出各个参数
 set(i 0)
 foreach(loop ${ARGV})
     message("arg${i}: " ${loop})
     math(EXPR i "${i} + 1")
 endforeach()
endmacro()

# 使用宏
XYZ(A B C D E)

进入 build目录下,执行"cmake .."命令后打印信息如下:

从定义上看他们貌似一模一样,宏和函数确实差不多,但还是有区别的。

譬如,宏的参数和诸如 ARGV、ARGCARGN 之类的值不是通常 CMake 意义上的变量,它们是字符串替换,就像 C 语言预处理器对宏所做的一样,因此,您将无法使用以下命令:
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
因为在宏定义中,宏的参数和诸如 ARGC ARGV ARGN 等这些值并不是变量,它们是字符串替换。
也就是说,当 cmake 执行宏定义时,会先将宏的参数和 ARGC ARGV ARGN 等这些值进行字符串替换, 然后再去执行这段宏,其实就像是 C 语言中的预处理步骤,这是与函数不同的地方。
我们来进行测试:
# macro 宏
macro(abc arg1 arg2)
 if(DEFINED ARGC)
 message(true)
 else()
 message(false)
 endif()
endmacro()

# function 函数
function(xyz arg1 arg2)
 if(DEFINED ARGC)
 message(true)
 else()
 message(false)
 endif()
endfunction()

# 调用宏
abc(A B C D)
# 调用函数
xyz(A B C D)

上面的代码中,我们定义了一个宏 abc 和一个函数 xyz ,它们俩的代码是一样的,都是在内部使用 if() 判断 ARGC 是不是一个变量,如果是打印 true ,如果不是打印 false
下面会分别调用宏 abc 和函数 xyz ,打 印信息如下所示:

从打印信息可知,在宏定义中, ARGC 确实不是变量,其实在执行宏之前,会将 ARGC 进行替换,如下所示:
if(DEFINED 4)
message(true)
else()
message(false)
endif()
ARGC 替换为 4 (因为我们实际传入了 4 个参数)。
当然,除此之外,cmake 中函数和宏定义还有其它的区别,譬如函数有自己的作用域、而宏定义是没有作用域的概念。

关于 cmake的宏定义暂时学习到这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值