【cmake系列使用教程】
这个系列的文章翻译自官方cmake教程:cmake tutorial。
示例程序地址:github.com/rangaofei/t…
不会仅仅停留在官方教程。本人作为一个安卓开发者,实在是没有linux c程序开发经验,望大佬们海涵。教程是在macos下完成,大部分linux我也测试过,有特殊说明的我会标注出来。本教程基于cmake-3.10.2,同时认为你已经安装好cmake。
cmake中有两个相似的关键字,macro和function。这两个都是创建一段有名字的代码稍后可以调用,还可以传参数。
macro宏定义与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}
来引用变量以外,系统为我们提供了一些特殊的变量:
变量 | 说明 |
---|---|
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 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(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。
今天的文章cmake使用教程(八)-macro和function分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21704.html