Bilibili 同步视频
开篇絮语
编译构工程之骨架,分支定脚本之枢机;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 内存在两种写法:直接书写变量名 、${变量名} 取值解析,二者逻辑有本质区别:
-
直接写变量名称:读取变量内部存储值做真伪校验,为官方推荐写法,代码简洁无替换隐患;
-
包裹
${}符号: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 构建脚本条理清明,项目编译高效稳健。

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