博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cmake使用教程(八)-macro和function
阅读量:7220 次
发布时间:2019-06-29

本文共 3175 字,大约阅读时间需要 10 分钟。

【cmake系列使用教程】

这个系列的文章翻译自官方cmake教程:。

示例程序地址:

不会仅仅停留在官方教程。本人作为一个安卓开发者,实在是没有linux c程序开发经验,望大佬们海涵。教程是在macos下完成,大部分linux我也测试过,有特殊说明的我会标注出来。本教程基于cmake-3.10.2,同时认为你已经安装好cmake。

cmake中有两个相似的关键字,macro和function。这两个都是创建一段有名字的代码稍后可以调用,还可以传参数。

macro宏定义与function函数的相同点

macro形式如下:

macro(
[arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ...endmacro(
)复制代码

function形式如下:

function(
[arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ...function(
)复制代码

定义一个名称为name的宏(函数),arg1...是传入的参数。我们除了可以用${arg1}来引用变量以外,系统为我们提供了一些特殊的变量:

变量 说明
ARGV# #是一个下标,0指向第一个参数,累加
ARGV 所有的定义时要求传入的参数
ARGN 定义时要求传入的参数以外的参数,比如定义宏(函数)时,要求输入1个,书记输入了3个,则剩下的两个会以数组形式存储在ARGN中
ARGC 传入的实际参数的个数,也就是调用函数是传入的参数个数

macro宏定义与function函数的不同点

宏的ARGN、ARGV等参数不是通常CMake意义上的变量。 它们是字符串替换,很像C预处理器对宏的处理。 因此,如下命令是错误的:

if(ARGV1) # ARGV1 is not a variable if(DEFINED ARGV2) # ARGV2 is not a variableif(ARGC GREATER 2) # ARGC is not a variableforeach(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})orset(list_var "${ARGN}")foreach(loop_var IN LISTS list_var)复制代码

一个简单的例子

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}")复制代码

输出结果如下:

-- this is arg1:one,ARGV0=one-- this is arg2:two,ARGV1=two-- this is arg3:three,ARGV2=three-- this is argc:5-- this is args:one;two;three;four;five,ARGN=four;five-- after set arg1=nine-- this is arg1:first,ARGV0=first-- this is argn:second-- this is first-- after set arg1=ten-- after bar p6=first复制代码

接下来看一个让我们蛋都能疼碎了的例子,简直不想用cmake:

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)复制代码

看一下输出:

-- this in function is a-- this in function is b-- this in function is c-- this is in macro a-- this is in macro b-- this is in macro c复制代码

就是这么蛋疼,我们传给了_bar(x y z),结果打印出来的是a b c,那我们把第二行的foreach改成foreach(arg IN LISTS ${ARGN}), 看一下结果:

-- this in function is a-- this in function is b-- this in function is c复制代码

没有输出_bar中的信息。为啥?因为这个ARGN的作用域是在function中的,也就是_foo函数中的那个ARGN。有兴趣的话可以试试在macro中调用function。

转载地址:http://gjhym.baihongyu.com/

你可能感兴趣的文章
输入,输出与Mad Libs游戏
查看>>
浅谈IC卡密码的破解方法
查看>>
文件服务器批量建立用户
查看>>
java的八种基本数据类型
查看>>
H3C交换机、路由器Console和Telnet密码配置
查看>>
37.系统所有临时文件夹的具体位置:
查看>>
50.逐条运行以下命令, 轻松修复IE浏览器:
查看>>
dump to rar to iso
查看>>
4.9Python数据处理篇之Matplotlib系列(九)---子图分布
查看>>
可以永久免费下载、免费使用、免费升级、
查看>>
【云简评】之二《不做不死的Verizon云服务48小时停机事件》
查看>>
Oracle RAC日常基本维护命令
查看>>
QT Sqlite ARM 编写程序
查看>>
Oralce7和Oralce8里大对象的比较
查看>>
2011年存储行业重点厂商盘点---初志
查看>>
Activiti初学者教程
查看>>
SVN 1053: 服务没有及时响应启动或控制请求
查看>>
==与equal的区别 这次我理解了,你呢?
查看>>
利用searchview搜索应用程序
查看>>
教你用Python解决非平衡数据问题(附代码)
查看>>