目录
for循环
普通方式
demo
cmake3.17中添加了一种特殊的形式,可以在一次循环多个列表,其形式如下:
demo
类似python语言的for循环
demo
while循环
demo
cmake跳出循环(break)和继续下次循环(continue)
demo
block()和endblock()命令定义的块内也是允许break()和continue()命令的
for循环
普通方式
foreach(loopVar arg1 arg2 ...)<commands>endforeach()foreach(loopVar IN [LISTS listVar1 ...] [ITEMS item1 ...])<commands>endforeach()
第一种形式很简单,每一次循环,loopVar都将从arg1 arg2 ...中取出一个值,然后在循环体中使用.
第二种形式比较通用,但是只有有IN关键字,那后面的[LISTS listVar1 ...] [ITEMS item1 ...]就必须有其中一个或者都有,当两者都有的时候,[ITEMS item1 ...]需要全部放到[LISTS listVar1 ...]后面.
还有一点需要注意的是,[ITEMS item1 ...]中的item1 ..都不会最为变量使用,就仅仅是字符串或者值.
demo
第二个循环 IN LISTS ITEMS是关键字 IN是必须的,LISTS关键字后面的列表是按照list里面的值打印出来的,ITEMS关键字后面的如果没有${}修饰会把他们当成值,是什么就打印什么比如bar就直接打印出来了,如果有${}修饰会把他当成变量来打印里面的值.
message("-------------------------------")
set(list1 A B)
set(list2)
set(foo willNotBeShown)foreach(num 1 2 3 4 5 6)message(STATUS "num = ${num}")
endforeach()foreach(loopVar IN LISTS list1 list2 ITEMS ${foo} bar)message(STATUS "Iteration for: ${loopVar}")
endforeach()
message("-------------------------------")
cmake3.17中添加了一种特殊的形式,可以在一次循环多个列表,其形式如下:
foreach(loopVar ... IN ZIP_LISTS listVar ...)#...
#endforeach
如果只给出一个loopVar,则该命令将在每次迭代时设置loopVar_N形式的变量,N对应的是listVarN变量,编号从0开始.如果每一listVar都有一个loopVar,那么该命令会一对一映射他们,而不是创建loopVar_N 变量.
以这种方式"压缩"的列表长度不必相同.当迭代超过较短的列表时,取未定义变量的值会导致空字符.
demo
message("-------------------------------")message("设置一个loopVar")
set(list1 A B)
set(list2 1 2 3 4 5)
foreach(var IN ZIP_LISTS list1 list2)message(STATUS "vars = ${var_0} : ${var_1}")
endforeach()
message("设置两个loopVar")
foreach(var0 var1 IN ZIP_LISTS list1 list2)message(STATUS "var0 = ${var0} : var1 = ${var1}")
endforeach()
类似python语言的for循环
第一种形式在start到stop之间迭代,可以指定步长[step],第二种形式等价于:
foreach(loopVar RANGE 0 value).为了清晰,我们应该避免第二种形式,只使用第一种形式.
foreach(loopVar RANGE start stop [step])endforeach()foreach(loopVar RANGE value)endforeach()
demo
message("-------------------------------")
message("不添加步长")
foreach(num RANGE 0 6)message(STATUS "num = ${num}")
endforeach()message("添加步长")
foreach(num RANGE 0 6 2)message(STATUS "num = ${num}")
endforeach()
message("第二种形式")
foreach(loopVar RANGE 6)message(STATUS "loopVar = ${loopVar}")
endforeach()
while循环
cmake也支持while循环,当一个条件表达式为真的时候while循环将执行其中的语句,然后再次验证条件表达式是否为假,否则将重复执行while循环体中的命令.cmake while循环格式如下:
while(condition)# ...
endwhile()
condition的判断规则如同if()命令.
demo
message("-------------------------------")
set(num 4)while(num GREATER 0)message(STATUS "num = ${num}")math(EXPR num "${num} - 1")
endwhile()
cmake跳出循环(break)和继续下次循环(continue)
while循环和for循环都支持提前退出循环,使用break()命令实现,也支持跳出当前循环,进入下一次循环,使用continue()命令实现.这两个命令和C++中关键字行为是相同的.
demo
注意一点:
string(LENGTH "${s}" length)message("s length = ${length} s = ${s}")
求length的长度,s是一个列表求长度会算分号的长度,例如a1;a2这个是s的list,他的长度是5因为分号长度也为1.
message("-------------------------------")
foreach(outerVar IN ITEMS a b c)unset(s)foreach(innerVar IN ITEMS 1 2 3)list(APPEND s "${outerVar}${innerVar}")string(LENGTH "${s}" length)message("s length = ${length} s = ${s}")if(length GREATER 5)break()endif()if(outerVar STREQUAL "b")continue()endif()message("Processing ${outerVar}-${innerVar}")endforeach()message("Accumulated list: ${s}")
endforeach()
block()和endblock()命令定义的块内也是允许break()和continue()命令的
PROPAGATE 抛出在block里操作的对外面有效果
list(POP_FRONT values next)从前抛出到next
if(next MATCHES "skip")正则表达式,是否存在"skip"
message("-------------------------------")
set(log "Value: ")
set(values one two skipMe three stopHere four)
set(didSkip FALSE)
while(NOT values STREQUAL "")list(POP_FRONT values next)block(PROPAGATE didSkip)string(APPEND log "${next}")if(next MATCHES "skip")set(didSkip TRUE)continue()elseif(next MATCHES "stop")break()elseif(next MATCHES "t")string(APPEND log ", has t")endif()message("${log}")endblock()
endwhile()
message("Did skip: ${didSkip}")
message("Remaining values: ${values}")