else(expression)
else section.
COMMAND1(ARGS …) COMMAND2(ARGS …) #… endif(expression)
此处有一点注意:else和endif中的表达式是可以省略的,看到现在大部分网上的教程有必须加SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) 这句才能省略表达式,一脸懵逼,关于那个变量,我也查不到api,包括废弃的,所以我都不写这句。
if表达式可以用长表达式,优先级顺序如下:
EXISTS, COMMAND, DEFINED EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, STREQUAL, STRLESS, STRLESS_EQUAL, STRGREATER, STRGREATER_EQUAL, VERSION_EQUAL, VERSION_LESS, VERSION_LESS_EQUAL, VERSION_GREATER, VERSION_GREATER_EQUAL, MATCHES NOT,AND,OR
别看下面这张表很长,其实没什么内容:
表达式 | true | false | 说明 |
---|
| 1, ON, YES, TRUE, Y,或者是非0数字 | 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND,空字符串,或者带-NOTFOUND后缀 | 布尔判断值大小写不敏感 | <variable | string> | 已经定义且不是false的变量 | 未定义或者是false的变量 | | expression为false | expression为true | | AND | 两个条件全部成立 | 至少有一个为假 | | COMAND command-name | 已经定义的command,macro或者function | 未定义 | | POLICY policy-id | policy存在 | policy不存在 | 形式为CMP | TARGET target-name | 已经用add_executable(), add_library(), or add_custom_target()定义过的target | 未定义 | | TEST test-name | add_test()创建过的测试名称 | 未创建 | | EXISTS path-to-file-or-directory | 文件或者路径存在 | 文件或者路径不存在 | 此处是全路径 | file1 IS_NEWER_THAN file2 | file1的时间戳大于file2的时间戳 | | |
其中一个文件不存在 两个文件时间戳相同 | 其他情况 | 文件路径必须是全路径 | | IS_DIRECTORY path-to-directory | 给定的变量是文件夹 | 不是文件夹 | 全路径 | | IS_SYMLINK file-name | 变量是链接 | 不是 | 全路径 | | IS_ABSOLUTE path | 是绝对路径 | 不是 | | | <variable|string> MATCHES regex | 正则表达式匹配成功 | 匹配失败 | | | <variable|string> LESS <variable|string> | 给定的变量是数字并且左边小于右边 | 左边大于右边 | 用于比较数字的大小 LESS:小于 GREATER:大于 EQUAL:等于 GREATER_EQUAL:大于等于 LESS_EQUAL:小于等于 | | <variable|string> STRLESS <variable|string> | 按字典顺序左边小于右边 | 左边大于右边 | 用于比较字符串 LESS:小于 STRGREATER:大于 STREQUAL:等于 STRLESS_EQUAL:小于等于 STRGREATER_EQUAL:大于等于 | | <variable|string> VERSION_LESS <variable|string> | 左边的版本号小于右边的版本号 | 大于 | 用于版本号的比较 LESS:小于 VERSION_GREATER:大于 VERSION_EQUAL:等于 VERSION_LESS_EQUAL:小于等于 VERSION_GREATER_EQUAL:大于等于 | | <variable | string> IN_LIST | 右边的item中有左边 | 没有 | | DEFINED | 已定义变量 | 未定义变量 | | | (expr1) AND (expr2 OR (expr3)) | 1为真且2或者3至少有一个为真 | 其他情况 | |
在if条件表达式中,是不必用${var} 来取变量的值的,系统会自动转换。例如设置两个变量,
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
然后比较各种取值的情况:
set(var1 OFF) set(var2 “var1”)
if(var2) 实际是判断var1是否为false; if(${var2}) 相当于if(var1) ,实际是判断OFF;
foreach循环
1. 第一种形式
foreach(loop_var arg1 arg2 …) COMMAND1(ARGS …) COMMAND2(ARGS …) … endforeach(loop_var)
此处注意endforeach(loop_var) 的变量最好不要省略,因为foreach循环是依靠变量来跳出循环的。
在foreach 和匹配endforeach 之间的所有命令都会被系统记录而不被调用。 一旦找到了了endforeach ,则会执行原来记录的命令。在循环的每次迭代之前,${loop_var} 将被设置为具有列表中当前值的变量。
foreach(i 0 1 2 3) message(STATUS “current is ${i}”) endforeach(i) message(STATUS “end”) endforeach(i)
一个简单的循环,但是多了一个endforeach 。看一下结果
? StepTest git:(master) ? cmake -P foreach.cmake – current is 0 – current is 1 – current is 2 – current is 3 – end CMake Error at foreach.cmake:5 (endforeach): endforeach An ENDFOREACH command was found outside of a proper FOREACH ENDFOREACH structure. Or its arguments did not match the opening FOREACH command.
报错了。没有匹配的foreach。
2. 第二种形式
foreach(loop_var RANGE total)
从0开始直到total 结束(包含total)
foreach(i RANGE 3) message(STATUS “current is ${i}”) endforeach(i)
范围将会是0-3,查看一下结果:
? StepTest git:(master) ? cmake -P foreach.cmake – current is 0 – current is 1 – current is 2 – current is 3
3. 第三种形式
foreach(loop_var RANGE start stop [step])
从start开始直到stop结束之间的值,可以设置步进值step。
foreach(i RANGE 0 3 1) message(STATUS “current is ${i}”) endforeach(i)
输出结果和上面的一样.
注意一点:最后的结果不会大于stop值,步进值是浮点数时会被转为整形
4. 第四种形式
foreach(loop_var IN [LISTS [list1 […]]] [ITEMS [item1 […]]])
也比较简单,多了LIST关键字来循环list。不多讲。
while循环
while(condition) COMMAND1(ARGS …) COMMAND2(ARGS …) … endwhile(condition)
注意endwhile中的条件最好不要省略。这个条件和if中的表达式是一样的规则。 循环形式和foreach循环类似,直到碰到endwhile才开始执行每一条指令。
|