CMake 021: IF 条件判据详诠

Bilibili 同步视频

CMake 021:IF条件判据详诠

开篇絮语

编译构工程之骨架,分支定脚本之枢机;CMake 以 IF 掌条件之取舍,凭判据分路径之殊途。变量藏值,有定义未定义之分野;字符成文,有真伪字面之区划;数字定规,分零与非零之鸿沟;逻辑三符,统取反、相与、相或之妙用。凡构写 CMake 构建脚本,IF 条件判定为不可或缺之基石,倘不明甄别细则,极易埋下隐性 BUG,拖累项目编译稳定性。今缕析 IF 判定全套定则,剖解取值隐微之处,附落地可运行代码,兼注性能优劣与避坑要点,供诸位开发同仁实操参考。

一、变量入判:明定义与未定义之殊分

骈文小序:变量储常量于方寸,判真假于 IF 之间;未申明则空归虚妄,已赋值则循常量之规;直写变量免取值符之扰,添符取值易生嵌套之危。

在 CMake 的 IF 语法体系中,变量参与条件判断是日常高频场景,变量真伪判定依托其存储内容,同时区分未定义变量已初始化变量两类场景,二者判定逻辑迥然不同。

1.1 未定义变量判定规则

凡脚本内从未通过set关键字申明的标识符,直接放入 IF 条件时,CMake 预解析阶段默认将其视作空值,判定结果恒为false不会触发语法报错

性能备注:CMake 在脚本预处理阶段扫描标识符,未定义变量跳过内存赋值环节,解析速度略快,但无报错提醒的特性极易造成逻辑隐蔽故障,为工程埋坑。

实操示例代码:

cmake 复制代码
# DF变量全程未定义,直接用于IF判断
if(DF)
    message("DF判定为true")
else()
    message("DF未定义,默认判定结果:false") # 最终执行本行
endif()

1.2 已定义变量两种引用方式

已通过set赋值的变量,IF 内存在两种写法:直接书写变量名${变量名} 取值解析,二者逻辑有本质区别:

  1. 直接写变量名称:读取变量内部存储值做真伪校验,为官方推荐写法,代码简洁无替换隐患;

  2. 包裹${}符号:CMake 会先替换为变量实际存储内容,再执行条件判断,若变量内容恰好是另一变量标识符,会触发二次解析,极易产生代码冲突。

开发规约:日常 IF 条件判断优先裸写变量名,杜绝变量内部嵌套存储其他变量名,规避不可预期的替换 BUG。

实操示例代码:

cmake 复制代码
# 定义变量VR1,内部存储真值true
set(VR1 true)
# 写法1:直接使用变量名(推荐)
if(VR1)
    message("直接引用变量名:VR1结果为true")
endif()
# 写法2:${}取值解析
if(${VR1})
    message("使用${}取值,提取变量原值参与判定")
endif()

# 风险示例:变量嵌套赋值,极易逻辑错乱,不推荐使用
set(VRE "VR1")
if(VRE)
    # VRE存储字符串"VR1",不属于真值列表,判定为false
    message("嵌套赋值测试")
endif()

二、字符串入式:辨真伪字面之界限

骈文小序:引号圈字符而成串,五类真字定取舍之纲;on、yes、true、y 列真之名录,杂字空串尽入虚妄之壤;大小写不拘,字面定真伪。

字符串以双引号包裹作为 IF 条件入参时,CMake 拥有固定白名单规则,仅白名单内字面字符串判定为真,其余自定义字符串、空字符串统一判定为false,且白名单关键字大小写不敏感(TRUE/True/true等效)。 真值白名单:true、on、yes、y,除此四类字面,任意文本字符串皆为假。

实操示例代码:

cmake 复制代码
# 白名单真值字符串测试
if("true")
    message("字符串true:判定为真")
endif()
if("ON")
    message("字符串ON:大小写无关,判定为真")
endif()

# 自定义非真值普通字符串
if("test")
else()
    message("普通字符串test:不在真值列表,判定false")
endif()

# 空字符串校验
if("")
else()
    message("空字符串:无有效字符,判定false")
endif()

三、数值参判:定零与非零之判准

骈文小序:数值分正负巨细,判据唯零定假真;零居虚妄之隅,非零归真确之域,大数负数同遵此律。

数字常量直接写入 IF 条件时遵循数字判值法则:所有非 0 整数(正数、负数、超大数值)统一判定为 true;仅数字 0 固定判定为 false,此规则是 CMake 内置常量体系的重要组成。

实操示例代码:

cmake 复制代码
# 正整数非0:true
if(1234)
    message("正数1234:非零,判定true")
endif()
# 负整数非0:true
if(-99)
    message("负数-99:非零,判定true")
endif()
# 数值0:false
if(0)
else()
    message("数字0:固定判定false")
endif()

四、逻辑三符:阐取反、相与、相或之妙用

骈文小序:NOT 持取反之令,真易伪而伪成真;AND 守双契之规,两全真方得真;OR 秉独胜之约,一存真即为真;括号分先后之序,内先运算而后外衍。

单一条件仅能完成简单分支,工程多条件组合判定依赖NOT/AND/OR三大逻辑运算符,三者可搭配圆括号嵌套使用,遵循括号优先、由内向外运算的优先级规则;且 CMake 逻辑运算自带短路优化,能缩减脚本运算耗时。

性能优化:AND 运算符左条件为 false 时直接短路,不再校验右侧表达式;OR 运算符左条件为 true 直接短路,跳过右侧运算,合理利用短路可优化大批量条件编译脚本运行效率。

4.1 NOT 取反运算符

对原有条件结果进行翻转:原 true 变 false,原 false 变 true,常用于反向逻辑,替代冗余 else 分支。

cmake 复制代码
set(VR_off OFF)
# 原VR_off为false,NOT取反后整体条件为true
if(NOT VR_off)
    message("NOT取反生效:原false转为true")
endif()

4.2 AND 与 OR 双目运算符

  • AND:左右两侧条件全部为 true,整体结果才为 true,任一为 false 则整体假;

  • OR:左右两侧条件任意一个为 true,整体结果即为 true,双侧全假才为假。

cmake 复制代码
# AND全真示例
if(ON AND true)
    message("AND:双条件全true,结果true")
endif()
# AND单假示例
if(ON AND OFF)
else()
    message("AND:任一条件false,整体判定false")
endif()

# OR单真示例
if(true OR OFF)
    message("OR:单侧true,整体判定true")
endif()

4.3 括号嵌套组合运算

圆括号改变天然运算优先级,优先运算括号内部逻辑,运算结束后将结果参与外层逻辑计算,是复杂多条件的标准写法。

cmake 复制代码
# 运算顺序:先算括号内 OFF OR ON = true,再执行 true AND true
if(true AND (OFF OR ON))
    message("嵌套运算:括号优先计算,最终条件为true")
endif()

文末总括

骈文结语:综 IF 判据之纲要,五类真值为准绳:on、yes、true、y 与非零数值;除却此五项之外,字符空值、零数、杂串、未定变量,尽归 false 之属。变量直引以避替换之弊,逻辑嵌套以括号定先后之序。深谙此 IF 判定法度,删脚本冗余之分支,绝隐伏难查之故障,令 CMake 构建脚本条理清明,项目编译高效稳健。

拓展贴士:日常项目可将真值白名单整理为全局宏定义,统一封装条件判断函数,减少重复编码,适配大型工程模块化开发。

相关推荐
_wyt00115 小时前
洛谷 B3930 [GESP202312 五级] 烹饪问题 题解
c++·gesp
玖玥拾19 小时前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
один but you20 小时前
constexpr函数
c++
凡人叶枫20 小时前
Effective C++ 条款41:了解隐式接口和编译期多态
java·开发语言·c++·effective c++
凡人叶枫20 小时前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
小胖xiaopangss21 小时前
BRpc使用
c++·rpc
-森屿安年-21 小时前
63. 不同路径 II
c++·算法·动态规划
chase_my_dream21 小时前
Cartographer详细讲解
c++·人工智能·自动驾驶
森G21 小时前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt