当前位置: 首页 > java >正文

6、CMake基础:流程控制

流程控制

  • 1. 条件判断
    • 1.1 基本表达式
    • 1.2 逻辑判断
    • 1.3 比较
      • 基于数值的比较
      • 基于字符串的比较
    • 1.4 文件操作
    • 1.5 其他
  • 2. 循环
    • 2.1 foreach
      • 方法1
      • 方法2
      • 方法3
      • 方法4
    • 2.2 while

在 CMake 的 CMakeLists.txt 中也可以进行流程控制,也就是说可以像写 shell 脚本那样进行条件判断和循环。

1. 条件判断

关于条件判断其语法格式如下:

if(<condition>)<commands>
elseif(<condition>) # 可选快, 可以重复<commands>
else()              # 可选快<commands>
endif()

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

1.1 基本表达式

if(<expression>)

如果是基本表达式,expression 有以下三种情况:常量、变量、字符串。

  1. 如果是1, ON, YES, TRUE, Y, 非零值,非空字符串时,条件判断返回True
  2. 如果是 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND,空字符串时,条件判断返回False

1.2 逻辑判断

if(NOT <condition>)
if(<cond1> AND <cond2>)
if(<cond1> OR <cond2>)
  1. NOT:其实这就是一个取反操作,如果条件condition为True将返回False,如果条件condition为False将返回True。
  2. AND:如果cond1和cond2同时为True,返回True否则返回False。
  3. or:如果cond1和cond2两个条件中至少有一个为True,返回True,如果两个条件都为False则返回False。

1.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>)
  1. LESS:如果左侧数值小于右侧,返回True
  2. GREATER:如果左侧数值大于右侧,返回True
  3. EQUAL:如果左侧数值等于右侧,返回True
  4. LESS_EQUAL:如果左侧数值小于等于右侧,返回True
  5. GREATER_EQUAL:如果左侧数值大于等于右侧,返回True

基于字符串的比较

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>)
  1. STRLESS:如果左侧字符串小于右侧,返回True
  2. STRGREATER:如果左侧字符串大于右侧,返回True
  3. STREQUAL:如果左侧字符串等于右侧,返回True
  4. STRLESS_EQUAL:如果左侧字符串小于等于右侧,返回True
  5. STRGREATER_EQUAL:如果左侧字符串大于等于右侧,返回True

1.4 文件操作

if(EXISTS path-to-file-or-directory)

判断文件或者目录是否存在:如果文件或者目录存在返回True,否则返回False。

if(IS_DIRECTORY path)

判断是不是目录:此处目录的 path 必须是绝对路径。如果目录存在返回True,目录不存在返回False。

if(IS_SYMLINK file-name)

此处的 file-name 对应的路径必须是绝对路径。如果软链接存在返回True,软链接不存在返回False。
软链接相当于 Windows 里的快捷方式

if(IS_ABSOLUTE path)

关于绝对路径:如果是Linux,该路径需要从根目录开始描述;如果是Windows,该路径需要从盘符开始描述。
如果是绝对路径返回True,如果不是绝对路径返回False。

1.5 其他

if(<variable|string> IN_LIST <variable>)

判断某个元素是否在列表中。如果这个元素在列表中返回True,否则返回False。

if(<variable|string> PATH_EQUAL <variable|string>)

比较两个路径是否相等。关于路径的比较其实就是两个字符串的比较,如果路径格式书写没有问题也可以通过下面这种方式进行比较:

if(<variable|string> STREQUAL <variable|string>)

我们在书写某个路径的时候,可能由于误操作会多写几个分隔符,比如把/a/b/c写成/a//b///c,此时通过STREQUAL对这两个字符串进行比较肯定是不相等的,但是通过PATH_EQUAL去比较两个路径,得到的结果确实相等的。
在进行路径比较的时候,如果使用 PATH_EQUAL 可以自动剔除路径中多余的分割线然后再进行路径的对比,使用 STREQUAL 则只能进行字符串比较。

2. 循环

在 CMake 中循环有两种方式,分别是:foreach和while。

2.1 foreach

使用 foreach 进行循环,语法格式如下:

foreach(<loop_var> <items>)<commands>
endforeach()

通过foreach我们就可以对items中的数据进行遍历,然后通过loop_var将遍历到的当前的值取出,在取值的时候有以下几种用法。

方法1

foreach(<loop_var> RANGE <stop>)
  1. RANGE:关键字,表示要遍历范围
  2. stop:这是一个正整数,表示范围的结束值,在遍历的时候从 0 开始,最大值为 stop。
  3. loop_var:存储每次循环取出的值
cmake_minimum_required(VERSION 3.2)
project(test)
# 循环
foreach(item RANGE 10)message(STATUS "当前遍历的值为: ${item}" )
endforeach()

结果:在对一个整数区间进行遍历的时候,得到的范围是这样的 【0,stop】,右侧是闭区间包含 stop 这个值。

$ cmake ..
-- 当前遍历的值为: 0
-- 当前遍历的值为: 1
-- 当前遍历的值为: 2
-- 当前遍历的值为: 3
-- 当前遍历的值为: 4
-- 当前遍历的值为: 5
-- 当前遍历的值为: 6
-- 当前遍历的值为: 7
-- 当前遍历的值为: 8
-- 当前遍历的值为: 9
-- 当前遍历的值为: 10
-- Configuring done
-- Generating done
-- Build files have been written to: /home/robin/abc/a/build

方法2

foreach(<loop_var> RANGE <start> <stop> [<step>])
  1. RANGE:关键字,表示要遍历范围
  2. start:这是一个正整数,表示范围的起始值,也就是说最小值为 start
  3. stop:这是一个正整数,表示范围的结束值,也就是说最大值为 stop
  4. step:控制每次遍历的时候以怎样的步长增长,默认为1,可以不设置
  5. loop_var:存储每次循环取出的值
cmake_minimum_required(VERSION 3.2)
project(test)foreach(item RANGE 10 30 2)message(STATUS "当前遍历的值为: ${item}" )
endforeach()

结果:

$ cmake ..
-- 当前遍历的值为: 10
-- 当前遍历的值为: 12
-- 当前遍历的值为: 14
-- 当前遍历的值为: 16
-- 当前遍历的值为: 18
-- 当前遍历的值为: 20
-- 当前遍历的值为: 22
-- 当前遍历的值为: 24
-- 当前遍历的值为: 26
-- 当前遍历的值为: 28
-- 当前遍历的值为: 30
-- Configuring done
-- Generating done
-- Build files have been written to: /home/robin/abc/a/build

方法3

foreach(<loop_var> IN [LISTS [<lists>]] [ITEMS [<items>]])
  1. IN:关键字,表示在 xxx 里边
  2. LISTS:关键字,对应的是列表list,通过set、list可以获得
  3. ITEMS:关键字,对应的也是列表
  4. loop_var:存储每次循环取出的值
cmake_minimum_required(VERSION 3.2)
project(test)
# 创建 list
set(WORD a b c d)
set(NAME ace sabo luffy)
# 遍历 list
foreach(item IN LISTS WORD NAME)message(STATUS "当前遍历的值为: ${item}" )
endforeach()

结果:

$ cd build/
$ cmake ..
-- 当前遍历的值为: a
-- 当前遍历的值为: b
-- 当前遍历的值为: c
-- 当前遍历的值为: d
-- 当前遍历的值为: ace
-- 当前遍历的值为: sabo
-- 当前遍历的值为: luffy
-- Configuring done
-- Generating done
-- Build files have been written to: /home/robin/abc/a/build

接下来看另外一种方式:

cmake_minimum_required(VERSION 3.2)
project(test)set(WORD a b c "d e f")
set(NAME ace sabo luffy)
foreach(item IN ITEMS ${WORD} ${NAME})message(STATUS "当前遍历的值为: ${item}" )
endforeach()

遍历过程中将关键字LISTS改成了ITEMS,后边跟的还是一个或者多个列表,只不过此时需要通过${}将列表中的值取出。其输出的信息和上一个例子是一样的。

方法4

foreach(<loop_var>... IN ZIP_LISTS <lists>)
  1. loop_var:存储每次循环取出的值,可以根据要遍历的列表的数量指定多个变量,用于存储对应的列表当前取出的那个值。
    1. 如果指定了多个变量名,它们的数量应该和列表的数量相等
    2. 如果只给出了一个 loop_var,那么它将一系列的 loop_var_N 变量来存储对应列表中的当前项,也就是说 loop_var_0 对应第一个列表,loop_var_1 对应第二个列表,以此类推…
    3. 如果遍历的多个列表中一个列表较短,当它遍历完成之后将不会再参与后续的遍历(因为其它列表还没有遍历完)。
  2. IN:关键字,表示在 xxx 里边
  3. ZIP_LISTS:关键字,对应的是列表list,通过set 、list可以获得
cmake_minimum_required(VERSION 3.17)
project(test)
# 通过list给列表添加数据
list(APPEND WORD hello world "hello world")
list(APPEND NAME ace sabo luffy zoro sanji)
# 遍历列表
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()

结果:

$ cd build/
$ cmake ..
-- 当前遍历的值为: item1 = hello, item2=ace
-- 当前遍历的值为: item1 = world, item2=sabo
-- 当前遍历的值为: item1 = hello world, item2=luffy
-- 当前遍历的值为: item1 = , item2=zoro
-- 当前遍历的值为: item1 = , item2=sanji
=============================
-- 当前遍历的值为: item1 = hello, item2=ace
-- 当前遍历的值为: item1 = world, item2=sabo
-- 当前遍历的值为: item1 = hello world, item2=luffy
-- 当前遍历的值为: item1 = , item2=zoro
-- 当前遍历的值为: item1 = , item2=sanji
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/robin/abc/a/build

2.2 while

while(<condition>)<commands>
endwhile()

while循环比较简单,只需要指定出循环结束的条件即可。

cmake_minimum_required(VERSION 3.5)
project(test)
# 创建一个列表 NAME
set(NAME luffy sanji zoro nami robin)
# 得到列表长度
list(LENGTH NAME LEN)
# 循环
while(${LEN} GREATER  0)message(STATUS "names = ${NAME}")# 弹出列表头部元素list(POP_FRONT NAME)# 更新列表长度list(LENGTH NAME LEN)
endwhile()

结果:

$ cd build/
$ cmake ..
-- names = luffy;sanji;zoro;nami;robin
-- names = sanji;zoro;nami;robin
-- names = zoro;nami;robin
-- names = nami;robin
-- names = robin
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/robin/abc/a/build
http://www.xdnf.cn/news/4492.html

相关文章:

  • Linux 信号(下篇)
  • 元子与元组的关系解析:从简单到复杂大跨界大综合的融智学研究
  • 深入理解 Node.js 模块化(CommonJS):原理、用法与避坑指南
  • 无人机上的热成像相机可以单独使用吗?
  • 康养休闲旅游行程服务实训室:打造沉浸式康养旅游人才培养新模式
  • 【linux常用指令】du命令
  • base64与图片的转换和预览
  • Python Bug 修复案例分析:多线程共享资源引发的数据不一致问题修复
  • SSRF请求伪造
  • -CoderOilStationJava高级工程师
  • 民宿管理系统6
  • 时间序列数据集构建方案Pytorch
  • Vuerouter 的底层实现原理
  • 【机器学习】Logistic 回归
  • 藏文助词标注器入门实践
  • SQLite数据库加密(Java语言、python语言)
  • 第8章-1 查询性能优化-优化数据访问
  • 微信小程序预览文件 兼容性苹果
  • redis bitmap数据类型调研
  • TB6600HG是一款PWM(脉宽调制)斩波型单芯片双极性正弦波微步进电机驱动集成电路。
  • 三款实用工具推荐:配音软件+Windows暂停更新+音视频下载!
  • ZYNQ移植FreeRTOS与OpenAMP双核开发实践指南
  • 《汽车噪声控制》复习重点
  • AI开发playwright tool提示词
  • 信奥赛CSP-J复赛集训(图和树专题)(1):P8604 [蓝桥杯 2013 国 C] 危险系数
  • 蓝桥杯 20. 倍数问题
  • 传输层协议 1.TCP 2.UDP
  • 碰一碰发视频源码搭建的技术迭代与升级实践
  • 16.Excel:数据收集
  • cuda矩阵加法