[C++][CMake][流程控制]详细讲解

DieSnowK 2024-07-25 11:05:03 阅读 84

目录

1.条件判断1.基本表达式2.逻辑判断3.比较4.文件操作5.其他

2.循环1.foreach2.while


1.条件判断

在进行条件判断的时候,如果有多个条件,那么可以写多个<code>elseif,最后一个条件可以使用else,但是开始和结束是必须要成对出现的,分别为:ifendif语法

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:这是一个正整数,表示范围的起始值,也就是说最小值为startstop:这是一个正整数,表示范围的结束值,也就是说最大值为stopstep:控制每次遍历的时候以怎样的步长增长,默认为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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。