目录
- 1.条件判断
- 1.基本表达式
- 2.逻辑判断
- 3.比较
- 4.文件操作
- 5.其他
- 2.循环
- 1.foreach
- 2.while
1.条件判断
- 在进行条件判断的时候,如果有多个条件,那么可以写多个
elseif
,最后一个条件可以使用else
,但是开始和结束是必须要成对出现的,分别为:if
和endif
- 语法:
if(<condition>)<commands> elseif(<condition>) # 可选快, 可以重复<commands> else() # 可选快<commands> endif()
1.基本表达式
- 语法:
if(<expression>)
- 如果是基本表达式,
expression
有以下三种情况:常量、变量、字符串- 如果是
1
,ON
,YES
,TRUE
,Y
,非零值
,非空字符串
时,条件判断返回True
- 如果是
0
,OFF
,NO
,FALSE
,N
,IGNORE
,NOTFOUND
,空字符串
时,条件判断返回False
- 如果是
2.逻辑判断
- NOT:逻辑取反
if(NOT <condition>)
- AND:逻辑与
if(<cond1> AND <cond2>)
- OR:逻辑或
if(<cond1> OR <cond2>)
3.比较
- 基于数值的比较
if(<variable|string> LESS <variable|string>) if(<variable|string> GREATER <variable|string>) if(<variable|string> EQUAL <variable|string>) if(<variable|string> LESS_EQUAL <variable|string>) if(<variable|string> GREATER_EQUAL <variable|string>)
- 基于字符串的比较
if(<variable|string> STRLESS <variable|string>) if(<variable|string> STRGREATER <variable|string>) if(<variable|string> STREQUAL <variable|string>) if(<variable|string> STRLESS_EQUAL <variable|string>) if(<variable|string> STRGREATER_EQUAL <variable|string>)
4.文件操作
- 判断文件或者目录是否存在
if(EXISTS path-to-file-or-directory)
- 判断是不是目录:此处
path
必须是绝对路径if(IS_DIRECTORY path)
- 判断是不是软链接:此处的
file-name
必须是绝对路径if(IS_SYMLINK file-name)
- 判断是不是绝对路径
if(IS_ABSOLUTE path)
5.其他
- 判断某个元素是否在列表中:CMake版本要求 > 3.3
if(<variable|string> IN_LIST <variable>)
- 比较两个路径是否相等:CMake版本要求 > 3.24
if(<variable|string> PATH_EQUAL <variable|string>)
- 关于路径的比较其实就是两个字符串的比较,如果路径格式书写没有问题也可以通过下面这种方式进行比较
if(<variable|string> STREQUAL <variable|string>)
- 在书写某个路径的时候,可能由于误操作会多写几个分隔符,比如把
/a/b/c
写成/a//b///c
,此时通过STREQUAL
对这两个字符串进行比较肯定是不相等的,但是通过PATH_EQUAL
去比较两个路径,得到的结果确实相等的,可以看下面的例子:cmake_minimum_required(VERSION 3.26) project(test)if("/home//robin///Linux" PATH_EQUAL "/home/robin/Linux")message("路径相等") # √ else()message("路径不相等") endif()message(STATUS "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")if("/home//robin///Linux" STREQUAL "/home/robin/Linux")message("路径相等") else()message("路径不相等") # √ endif()
- 结论:在进行路径比较的时候
- 如果使用
PATH_EQUAL
可以自动剔除路径中多余的分割线然后再进行路径的对比 - 使用
STREQUAL
则只能进行字符串比较
- 如果使用
- 关于路径的比较其实就是两个字符串的比较,如果路径格式书写没有问题也可以通过下面这种方式进行比较
2.循环
1.foreach
- 通过
foreach
就可以对items
中的数据进行遍历,然后通过loop_var
将遍历到的当前的值取出 - 语法:
foreach(<loop_var> <items>)<commands> endforeach()
loop_var
在取值的时候有以下几种用法:foreach(<loop_var> RANGE <stop>)
- 参数:
RANGE
:关键字,表示要遍历范围stop
:这是一个正整数,表示范围的结束值,[0, stop]
loop_var
:存储每次循环取出的值
- 示例:
cmake_minimum_required(VERSION 3.2) project(test)foreach(item RANGE 10)message(STATUS "当前遍历的值为: ${item}" ) endforeach()
- 参数:
foreach(<loop_var> RANGE <start> <stop> [<step>])
- 在遍历一个整数区间的时候,除了可以指定起始范围,还可以指定步长
- 参数:
RANGE
:关键字,表示要遍历范围start
:这是一个正整数,表示范围的起始值,也就是说最小值为start
stop
:这是一个正整数,表示范围的结束值,也就是说最大值为stop
step
:控制每次遍历的时候以怎样的步长增长,默认为1,可以不设置loop_var
:存储每次循环取出的值
- 示例:
cmake_minimum_required(VERSION 3.2) project(test)foreach(item RANGE 10 30 2)message(STATUS "当前遍历的值为: ${item}" ) endforeach()
foreach(<loop_var> IN [LISTS [<lists>]] [ITEMS [<items>]])
- 这是
foreach
的另一个变体,通过这种方式可以对更加复杂的数据进行遍历,前两种方式只适用于对某个正整数范围内的遍历 - 参数:
IN
:关键字,表示在xxx
里面LISTS
:关键字,对应的是列表list
,通过set、list
可以获得ITEMS
:关键字,对应的也是列表loop_var
:存储每次循环取出的值
- 示例1:
cmake_minimum_required(VERSION 3.2) project(test)# 创建 list set(WORD a b c d) set(NAME I am DieSnowK)# 遍历 list foreach(item IN LISTS WORD NAME)message(STATUS "当前遍历的值为: ${item}" ) endforeach()
- 结果1
-- 当前遍历的值为: a -- 当前遍历的值为: b -- 当前遍历的值为: c -- 当前遍历的值为: d -- 当前遍历的值为: I -- 当前遍历的值为: am -- 当前遍历的值为: DieSnowK
- 示例2
cmake_minimum_required(VERSION 3.2) project(test)set(WORD a b c "d e f") set(NAME I am DieSnowK)foreach(item IN ITEMS ${WORD} ${NAME})message(STATUS "当前遍历的值为: ${item}" ) endforeach()
- 结果2
-- 当前遍历的值为: a -- 当前遍历的值为: b -- 当前遍历的值为: c -- 当前遍历的值为: d e f -- 当前遍历的值为: I -- 当前遍历的值为: am -- 当前遍历的值为: DieSnowK
- 两种示例的区别:
- 遍历过程中将关键字
LISTS
改成了ITEMS
,后边跟的还是一个或者多个列表 - 只不过此时需要通过
${}
将列表中的值取出
- 遍历过程中将关键字
- 这是
foreach(<loop_var>... IN ZIP_LISTS <lists>)
- 注意:CMake版本要求 > 3.17
- 通过这种方式,遍历的还是一个或多个列表,可以理解为是方式3的加强版
- 因为通过上面的方式遍历多个列表,但是又想把指定列表中的元素取出来使用是做不到的,在这个加强版中就可以轻松实现
- 参数:
IN
:关键字,表示在xxx
里面ZIP_LISTS
:关键字,对应的是列表list
,通过set、list
可以获得loop_var
:存储每次循环取出的值,可以根据要遍历的列表的数量指定多个变量,用于存储对应的列表当前取出的那个值- 如果指定了多个变量名,它们的数量应该和列表的数量相等
- 如果只给出了一个
loop_var
,那么它将一系列的loop_var_N
变量来存储对应列表中的当前项loop_var_0
对应第一个列表loop_var_1
对应第二个列表- 以此类推…
- 示例:
cmake_minimum_required(VERSION 3.17) project(test)# 通过list给列表添加数据 list(APPEND WORD Die SnowK "Die SnowK") list(APPEND NAME I am Die SnowK haha)# 遍历列表 foreach(item1 item2 IN ZIP_LISTS WORD NAME)message(STATUS "当前遍历的值为: item1 = ${item1}, item2=${item2}" ) endforeach()message("=============================") # 遍历列表 foreach(item IN ZIP_LISTS WORD NAME)message(STATUS "当前遍历的值为: item1 = ${item_0}, item2=${item_1}" ) endforeach()
- 结果
-- 当前遍历的值为: item1 = Die, item2=I -- 当前遍历的值为: item1 = SnowK, item2=am -- 当前遍历的值为: item1 = Die SnowK, item2=Die -- 当前遍历的值为: item1 = , item2=SnowK -- 当前遍历的值为: item1 = , item2=haha ============================= -- 当前遍历的值为: item1 = Die, item2=I -- 当前遍历的值为: item1 = SnowK, item2=am -- 当前遍历的值为: item1 = Die SnowK, item2=Die -- 当前遍历的值为: item1 = , item2=SnowK -- 当前遍历的值为: item1 = , item2=haha
2.while
- 语法:循环结束对应的条件判断的书写格式和
if/elseif
是一样的while(<condition>)<commands> endwhile()
- 示例:
cmake_minimum_required(VERSION 3.5) project(test)# 创建一个列表 NAME set(NAME I am Die SnowK haha) # 得到列表长度 list(LENGTH NAME LEN)# 循环 while(${LEN} GREATER 0)message(STATUS "names = ${NAME}")# 弹出列表头部元素list(POP_FRONT NAME)# 更新列表长度list(LENGTH NAME LEN) endwhile()
- 结果
-- names = I;am;Die;SnowK;haha -- names = am;Die;SnowK;haha -- names = Die;SnowK;haha -- names = SnowK;haha -- names = haha