Flow Controls

代码仓库地址

https://github.com/zzu-andrew/linux-sys/tree/dfew/CMake

The ubiquitous if() command provides the expected if-then-else behavior and looping is provided through the foreach() and while() commands.

The if() Command

if(expression1)
# commands ...
elseif(expression2)
# commands ...
else()
# commands ...
endif()

Basic Expressions

最简单的if语句是如下:

if(value)
  • value是数值1、ON、YES、TRUE、Y或者一个非空的数值都被认为是真,test对大小写不敏感。
  • value是数值0、NO、OFF、FALSE、N、IGNORE、NOTFPOUND、空字符串或者以-NOTFOUND结尾的字符串的时候,被认为是假,判别假的时候value同样大小写不敏感
  • 如果不是上述两种情况,将会被认为是一个变量名,或者后面会说明的过程

忽略endif()的示例:

# Examples of unquoted constants
if(YES)
if(0)
if(TRUE)
# These are also treated as unquoted constants because the
# variable evaluation occurs before if() sees the values
set(A YES)
set(B 0)
if(${A}) # Evaluates to true
if(${B}) # Evaluates to false
# Does not match any of the true or false constants, so proceed
# to testing as a variable name in the fall through case below
if(someLetters)
# Quoted value, so bypass the true/false constant matching
# and fall through to testing as a variable name or string
if("someLetters")
# Common pattern, often used with variables defined
# by commands such as option(enableSomething "...")
if(enableSomething)
# ...
endif()

Logic Operators

CMake supports the usual AND, OR and NOT logical operators, as well as parentheses to control order of precedence.

# Logical operators
if(NOT expression)
if(expression1 AND expression2)
if(expression1 OR expression2)
# Example with parentheses
if(NOT (expression1 AND (expression2 OR expression3)))

按照通常的约定,首先计算括号内的表达式,从最里面的括号开始。

Comparison Tests

CMake将比较测试分为三种不同的类型:数字、字符串和版本号,但是语法形式都遵循相同的模式。

if(value1 OPERATOR value2)

value1value2可以是变量名或值。如果一个值与一个变量名一样,将会被视为一个变量,否则将会被视为字符串或者值。

OPERATOR总结:

Numeric String Version numbers
LESS STRLESS VERSION_LESS
GREATER STRGREATER VERSION_GREATER
EQUAL STREQUAL VERSION_EQUAL
LESS_EQUAL STRLESS_EQUAL VERSION_LESS_EQUAL
GREATER_EQUAL STRGREATER_EQUAL VERSION_GREATER_EQUAL

当比对的是含有字符和数字的混合情况,比对结果是未定义的,根据具体的CMake版本

# Valid numeric expressions, all evaluating as true
if(2 GREATER 1)
if("23" EQUAL 23)
set(val 42)
if(${val} EQUAL 42)
if("${val}" EQUAL 42)
# Invalid expression that evaluates as true with at
# least some CMake versions. Do not rely on this behavior.
if("23a" EQUAL 23)

版本号对比,次版本号没有给出就默认为0

if(1.2  VERSION_EQUAL 1.2.0)
if(1.2  VERSION_LESS 1.2.3)
if(1.2.3  VERSION_GREATER 1.2)
if(2.0.1  VERSION_GREATER 1.9.7)
if(1.8.2  VERSION_LESS 2)*

字符串对比支持正则比对,但是支持简单的正则比对

if(value MATCHES regex)
if("Hi from ${who}" MATCHES "Hi from (Fred|Barney).*")message("${CMAKE_MATCH_1} says hello")
endif()

File System Tests

CMake中有一系列文件测试函数,IS_NEWER_THAN当两个文件时间戳一样或者一个文件丢失的时候都会返回true

if(EXISTS pathToFileOrDir)
if(IS_DIRECTORY pathToDir)
if(IS_SYMLINK fileName)
if(IS_ABSOLUTE path)
if(file1 IS_NEWER_THAN file2)

Existence Tests

大型和复杂工程中经常使用,用于决定哪些需要使用哪些不需要

if(DEFINED name)
if(COMMAND name)
if(POLICY name)
if(TARGET name)
if(TEST name) # Available from CMake 3.4 onward

Each of the above will return true if an entity of the specified name exists at the point where the if command is issued.

DEFINED

如果对应的name定义了就返回true,用于测试变量或者环境变量是否被定义了

if(DEFINED SOMEVAR)       # Checks for a CMake variable
if(DEFINED ENV{SOMEVAR})  # Checks for an environment variable

COMMAND

测试对应的name是否是CMake的命令,函数或者宏。

POLICY

测试特定的策略是否是已知,通常的形式是 CMPxxxxxxxx部分通常是数字

TARGET

当一个目标被add_executable(), add_library() or add_custom_target()其中之一定义的时候,会返回true

TEST

add_test()定义之后会返回true

CMake3.5以上支持以下语句

if(value IN_LIST listVar)

Common Examples

if(WIN32)set(platformImpl source_win.cpp)
else()set(platformImpl source_generic.cpp)
endif()message("platformImpl = ${platformImpl} WIN32 = ${WIN32}")

expect output:

platformImpl = source_generic.cpp WIN32 =
if(MSVC)set(platformImpl source_msvc.cpp)
else()set(platformImpl source_generic.cpp)
endif()
if(APPLE)
# Some Xcode-specific settings here...
else()
# Things for other platforms here...
endif()
if(CMAKE_GENERATOR STREQUAL "Xcode")
# Some Xcode-specific settings here...
else()
# Things for other CMake generators here...
endif()

设置变量作为一个库是否编译的开关

option(BUILD_MYLIB "Enable building the myLib target" ON)if(BUILD_MYLIB)add_library(myLib src1.cpp src2.cpp)
endif()

Looping

使用循环,持续进行检测,直到特定的环境发生

foreach()

foreach(loopVar arg1 arg2 ...)
# ...
endforeach()

In the above form, for each argN value, loopVar is set to that argument and the loop body is executed.

Rather than listing out each item explicitly, the arguments can also be specified by one or more list variables using the more general form of the command:

foreach(loopVar IN [LISTS listVar1 ...] [ITEMS item1 ...])
# ...
endforeach()

示例如下:

set(list1 A B)
set(list2)
set(foo WillNotBeShown)
foreach(loopVar IN LISTS list1 list2 ITEMS foo bar)message("Iteration for: ${loopVar}")
endforeach()

output:

Iteration for: A
Iteration for: B
Iteration for: foo
Iteration for: bar

当在数值型中使用foreach时,可以使用类C风格

foreach(loopVar RANGE start stop [step])

默认的step为1,也就是从start开始每次+1直到值大于stop停止循环。

foreach(loopVar RANGE 1 10 6)message("echo loopVar = ${loopVar}")
endforeach()

output:

echo loopVar = 1
echo loopVar = 7

同时也支持单个value形式的,如下:

foreach(loopVar RANGE value)

等价于foreach(loopVar RANGE 0 value)

while()

while(condition)
# ...
endwhile()

执行到conditiontrue为止

Interrupting Loops

Both while() and foreach() loops support the ability to exit the loop early with break() or to skip to the start of the next iteration with continue().

foreach(outerVar IN ITEMS a b c)unset(s)foreach(innerVar IN ITEMS 1 2 3)# Stop inner loop once string s gets longlist(APPEND s "${outerVar}${innerVar}")string(LENGTH s length)if(length GREATER 5)break()endif()# Do no more processing if outer var is "b"if(outerVar STREQUAL "b")continue()endif()message("Processing ${outerVar}-${innerVar}")endforeach()message("Accumulated list: ${s}")
endforeach()

output:

Processing a-1
Processing a-2
Processing a-3
Accumulated list: a1;a2;a3
Accumulated list: b1;b2;b3
Processing c-1
Processing c-2
Processing c-3
Accumulated list: c1;c2;c3

cmake的使用-if-else的逻辑流程详解相关推荐

  1. Android事件流程详解

    Android事件流程详解 网络上有不少博客讲述了android的事件分发机制和处理流程机制,但是看过千遍,总还是觉得有些迷迷糊糊,因此特地抽出一天事件来亲测下,向像我一样的广大入门程序员详细讲述an ...

  2. 基于spark mllib_Spark高级分析指南 | 机器学习和分析流程详解(下)

    - 点击上方"中国统计网"订阅我吧!- 我们在Spark高级分析指南 | 机器学习和分析流程详解(上)快速介绍了一下不同的高级分析应用和用力,从推荐到回归.但这只是实际高级分析过程 ...

  3. View的绘制-layout流程详解

    目录 作用 根据 measure 测量出来的宽高,确定所有 View 的位置. 具体分析 View 本身的位置是通过它的四个点来控制的: 以下涉及到源码的部分都是版本27的,为方便理解观看,代码有所删 ...

  4. 推荐系统整体架构及算法流程详解

    省时查报告-专业.及时.全面的行研报告库 省时查方案-专业.及时.全面的营销策划方案库 知识图谱在美团推荐场景中的应用实践 搜索场景下的智能实体推荐 机器学习在B站推荐系统中的应用实践 小红书推荐系统 ...

  5. 推荐系统架构与算法流程详解

    你知道的越多,不知道的就越多,业余的像一棵小草! 成功路上并不拥挤,因为坚持的人不多. 编辑:业余草 zhuanlan.zhihu.com/p/259985388 推荐:https://www.xtt ...

  6. MySQL系列---架构与SQL执行流程详解

    文章目录 1. 背景 2. 架构体系 2.1 架构图 2.2 模块详解 2.3 架构分层 3. 查询SQL语句执行流程 3.1 连接 3.1.1 MySQL支持的通信协议 3.1.2 通信方式 3.2 ...

  7. View系列 (三) — Measure 流程详解

    Measure 流程详解 一.概述 二.单一 View 的测量流程 1. 流程图 2. 源码分析 三.ViewGroup 的测量流程 1. 流程图 2. 源码分析 一.概述 测量过程分为 View的m ...

  8. 【联机对战】微信小程序联机游戏开发流程详解

    现有一个微信小程序叫中国象棋项目,棋盘类的单机游戏看着有缺少了什么,现在给补上了,加个联机对战的功能,增加了可玩性,对新手来说,实现联机游戏还是有难度的,那要怎么实现的呢,接下来给大家讲一下. 考虑到 ...

  9. 电商新零售系统划分及供应链系统流程详解

    [声明在先]:文中所有业务流程及系统设计均由电商标准流程改造,不具有任何商业倾向性. 前序文章讲解了产品经理从接到任务开始,到出具电商后台整体解决方案的过程,本文重点讲述电商后台核心系统的划分及主营供 ...

最新文章

  1. ITK:跟踪两个代码执行之间的内存费用
  2. python slice函数画高维图_六维图见过么?Python 画出来了
  3. There is no Action mapped for namespace [/] and action name [LoginAction_home] associ
  4. 数据结构——基于 Dijsktra 算法的最短路径求解
  5. jQuery源码的基础知识
  6. struts2的namespace的问题
  7. 运行第一个node.js文件
  8. java mvc mvp_MVC和MVP设计模式
  9. JavaFX中将FXML文件自动转换为Java代码
  10. linux配置sftp-server,Ubuntu Server如何配置SFTP(建立用户监狱)
  11. 使用开源框架Sqlsugar结合mysql开发一个小demo
  12. 嵌入式linux gif 缩放_嵌入式环境动力监控主机
  13. Web前端开发工具(编辑器)汇总
  14. 从知网或PDF复制英文单词间隔过大问题
  15. 视频开头独白怎么做?一分钟学会
  16. matlab 数学符号输入,matlab输入数学符号
  17. 为什么编辑器打开PDF文档后提示缺少字体
  18. matlab的persistent,MATLAB局部静态变量类型persistent
  19. NLP-文本摘要:Rouge评测方法【Rouge-1、Rouge-2、Rouge-L、Rouge-W、Rouge-S】
  20. BGP带宽是什么意思

热门文章

  1. 同步异步网络搜集到的比喻
  2. NYOJ 336 子序列
  3. NYOJ 762 第k个互质数(二分 + 容斥)
  4. mybatis的动态sql的一些记录
  5. 转: 基于elk 实现nginx日志收集与数据分析
  6. ubuntu16.04 nginx安装
  7. 【转】使用C#发送Http 请求实现模拟登陆(以博客园为例)
  8. docker network
  9. 分享我设计的iOS项目目录结构
  10. TListBox的项目个数