【写在前面】

CMake 的生成器表达式用于在构建系统级别上进行条件判断和逻辑运算,它们通常用在目标属性和生成器表达式上下文中。这些表达式允许你根据不同的平台、配置或编译器来定制构建过程。

本文引用的文档链接:

cmake 生成器表达式 (7) — CMake 3.26.4 Documentation


【正文开始】

本篇文章将介绍《条件表达式》《逻辑运算符》

  • 条件表达式:

生成器表达式的一个基本类别与条件逻辑有关。支持两种形式的条件生成器表达式:

$<condition:true_string>

如果 condition 为 “1”,则评估为“true_string”,如果 condition 评估为“0”,则评估为空字符串。 condition 的任何其他值都会导致错误。

$<IF:condition,true_string,false_string>

在 3.8 版本加入.

如果 condition 为 “1”,则评估为“true_string”,如果 condition 为“0”,则评估为“false_string”。 condition 的任何其他值都会导致错误。

通常,condition 本身就是一个生成器表达式。例如,当使用 Debug 配置时,以下表达式扩展为 DEBUG_MODE,所有其他配置为空字符串:

$<$<CONFIG:Debug>:DEBUG_MODE>

使用示例:

#条件表达式 $<condition:true_string>
#等价于C++ if (condition == "1") return true_string else return ""
add_custom_command(
TARGET MyExecutable PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "[1]: WIN32: ${WIN32} | $<${WIN32}:is win32> | $<0:is 0>"
) #条件表达式 $<IF:condition,true_string,false_string>
#等价于C++ condition ? true_string : false_string
set(IS_DEBUG "1")
add_custom_command(
TARGET MyExecutable PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "[2]: IS_DEBUG: ${IS_DEBUG} | $<IF:${IS_DEBUG},is debug,is release>"
)

除了 1 或 0 之外的类似布尔的 condition 值可以通过用 $<BOOL:...> 生成器表达式包装它们来处理:

$<BOOL:string>

将 string 转换为 0 或 1。如果以下任何一项为真,则评估为“0”:

  • string 为空,

  • string 是不区分大小写的等于 0FALSEOFFNNOIGNORE 或  NOTFOUND

  • string 以后缀 -NOTFOUND 结尾(区分大小写)。

否则计算为“1”。

当 CMake 变量提供 condition 时,经常使用 $<BOOL:...>生成器表达式:

$<$<BOOL:${HAVE_SOME_FEATURE}>:-DENABLE_SOME_FEATURE>

使用示例:

#条件表达式 $<BOOL:string>
#等价于C++ if (string) return "1" else return "0"
set(STRING2BOOL "not empty")
add_custom_command(
TARGET MyExecutable PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "[3]: STRING2BOOL: ${STRING2BOOL} | $<BOOL:${STRING2BOOL}> | $<$<BOOL:${STRING2BOOL}>:STRING2BOOL is not empty>"
)

三个示例的输出如下:

  • 逻辑运算符

支持常见的布尔逻辑运算符:

 $<AND:conditions>

其中 conditions 是以逗号分隔的布尔表达式列表,所有这些表达式的计算结果必须为 1 或 0。如果所有条件都为“1”,则整个表达式的计算结果为“1”。如果任何条件为“0”,则整个表达式的计算结果为“0”。

$<OR:conditions>

其中 conditions 是以逗号分隔的布尔表达式列表。所有这些都必须评估为“1”或“0”。如果 condition 中的至少一个为“1”,则整个表达式的计算结果为“1”。如果所有 condition 的计算结果为“0”,则整个表达式的计算结果为“0”。

$<NOT:condition>

condition 必须是 0 或 1。如果 condition 为“1”,则表达式的结果为“0”,否则为“1”。

使用示例:

#逻辑运算符 $<AND:conditions>
#等价于C++ if (condition && condition && ...) return "1" else return "0"
add_custom_command(
TARGET MyExecutable PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "[1]: (1 && 0 && 1) = $<AND:1,0,1>"
) #逻辑运算符 $<OR:conditions>
#等价于C++ if (condition || condition || ...) return "1" else return "0"
add_custom_command(
TARGET MyExecutable PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "[2]: (1 || 0 || 0) = $<OR:1,0,0>"
) #逻辑运算符 $<NOT:condition>
#等价于C++ if (!condition) return "1" else return "0"
add_custom_command(
TARGET MyExecutable PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "[3]: !1 = $<NOT:1>"
)

结果如下:


【结语】

项目链接(多多star呀.._):

Github 地址:https://github.com/mengps/LearnCMake

CMake 生成器表达式---条件表达式和逻辑运算符的更多相关文章

  1. 【C语言探索之旅】 第一部分第六课:条件表达式

    内容简介 1.课程大纲 2.第一部分第六课:条件表达式 3.第一部分第七课预告:循环语句 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. ...

  2. shell之条件表达式

    conditional expressions are used by the [[ compound command and the test and [ builtin commands. ari ...

  3. Less的条件表达式

    Less的条件表达式 当需要根据表达式,而不是参数的值或数量进行匹配时,条件表达式(Guards)就显得非常有用.如果你熟悉函数式编程的话,对条件表达式也不会陌生. 为了尽可能地接近CSS的语言结构, ...

  4. if的条件表达式

    常用的: [ -a FILE ] 如果 FILE 存在则为真. [ -d FILE ] 如果 FILE 存在且是一个目录则返回为真. [ -e FILE ] 如果 指定的文件或目录存在时返回为真. [ ...

  5. Dart学习笔记-运算符-条件表达式-类型转换

    Dart学习笔记-运算符-条件表达式-类型转换 一.运算符 1.算术运算符 + (加)- (减)* (乘)/ (除)~/ (取整) %(取余) 2.关系运算符 == (等等) != (不等) > ...

  6. javascript面向对象编程笔记(基本数据类型,数组,循环及条件表达式)

    javascript面向对象编程指南 最近在看这本书,以下是我的笔记,仅供参考. 第二章 基本数据类型.数组.循环及条件表达式 2.1 变量 区分大小写 2.3 基本数据类型 数字:包括浮点数与整数 ...

  7. [Django]模型提高部分--聚合(group by)和条件表达式+数据库函数

    前言:本文以学习记录的形式发表出来,前段时间苦于照模型聚合中group by 找了很久,官方文章中没有很明确的说出group by,但在文档中有提到!!! 正文(最后编辑于2016-11-12): 聚 ...

  8. Scala:条件表达式的好处

    条件表达式的好处之一是:让代码更简洁,例如在一个需要根据不同条件收集不同值的场景中,多数语言提供的代码如下: ; ) { tmp = xxx; } ) { tmp = yyy; } else { tm ...

  9. Shell 条件表达式汇总

    条件表达式 文件表达式 if [ -f  file ]    如果文件存在if [ -d ...   ]    如果目录存在if [ -s file  ]    如果文件存在且非空 if [ -r f ...

  10. Python学习教程(learning Python)--3.3 分支语句的条件表达式详解

    本节主要讨论分支语句的条件表达式问题. 在if或者if-else分支控制语句里由于都用到条件判断(表达式是真还是假),条件判断可以是一种关系运算也可以是布尔表达式. 本节将对if及if-else语句的 ...

随机推荐

  1. [CEOI2018] Lottery 题解

    前言 题目链接:洛谷. 题意简述 给出序列 \(a_1 \ldots a_n\) 和常数 \(l \leq n\),定义: \[\operatorname{dis}(i, j) = \sum _ {k ...

  2. Apache DolphinScheduler使用图关系解决核心链路告警问题,减轻任务运维负担!

    转载自程序员小陶 Apache DolphinScheduler 在使用过程中,肯定会有任务出现失败的情况,那么问题来了:调度任务的告警是需要人为配置的,在生产环境中,面对海量的任务,如何找到重要的任 ...

  3. Flutter&Dart Callback转同步

    前言 怎么将一个Callback回调转化成Future同步方法(Callback to Future),可以配套async / await去使用呢? 个人觉得,这是一个很常见的现象,不知道为啥,很多人 ...

  4. 一步步开发Windows服务(Windows Service)[转]

    基于0起步来创建一个服务,做到简单的记录时间日志功能,其具体招行方法可自行添加. 1.创建服务 2.删除默认服务文件 3.添加自己的服务文件 4.更改启动项目 5. 引用 using System.T ...

  5. 如何让您的 .NET应用程序更智能-- 请参加 8.20 的 .NET Conf -- Focus on AI

    Microsoft 将于 2024 年 8 月 20 日举办免费的 .NET Conf: Focus on AI.该虚拟活动为开发人员提供了如何集成 .NET 和 AI 以增强应用程序开发和用户体验的 ...

  6. 使用一次sql请求,返回分页数据和总条数

    日常搬砖,总少不了需要获取分页数据和总行数. 一直以来的实践是编码两次sql请求,分别拉分页数据和totolCount. 最近我在思考: 常规实践为什么不是 在一次sql请求中中执行多次sql查询或多 ...

  7. SPI转can芯片CSM300详解以及Linux驱动移植调试笔记

    一.CSM300概述 CSM300(A)系列是一款可以支持 SPI / UART 接口的CAN模块. 1. 简介 CSM300(A)系列隔离 SPI / UART 转 CAN 模块是集成微处理器. C ...

  8. Typora 上传到 Github 实现笔记同步管理

    首先在 Github 上 new 一个 repository ,我建的名称是 md_notes 然后在本地 terminal 中启动以下命令新建一个 ssh key  ssh-keygen -o 生成 ...

  9. Go make 介绍

    Go 语言中的 make 函数用于创建和初始化特定类型的对象,主要是用于创建切片(slice).映射(map)和通道(channel).make 函数与 new 函数不同,new 函数是用于分配内存, ...

  10. Java多线程并发之同步容器和并发容器-第一篇

    Java多线程并发之同步容器和并发容器-第一篇 概述 本文主要讲解在Java多线程并发开发中,集合中有哪些支持并发的的.什么是同步容器(集合),什么是并发容器(集合)?并发容器分类有哪些?每个分类都有 ...