build2 构建语言进阶:函数、变量展开、条件与循环完全教程
【免费下载链接】build2build2 build system项目地址: https://gitcode.com/gh_mirrors/bu/build2
本文是 build2 构建语言的中级教程,从变量展开、内置函数到条件判断与循环控制,循序渐进带你写出可维护、可复用的 buildfile 构建脚本。
为什么你需要掌握 build2 构建语言
build2 是一款开源(MIT 协议)、跨平台的 C/C++ 构建工具链,由通用构建系统、包管理器与项目管理器三层构成。它的构建脚本(buildfile)不是简单的"编译清单",而是一门具备变量、函数、条件与循环能力的声明式语言。
对新手来说,写出能用的 buildfile 并不难;但想让项目在 Linux、macOS、Windows 上都能一次构建成功,学会 build2 构建语言的控制结构就非常关键。本文将围绕build2 变量展开、build2 内置函数、build2 条件判断与build2 循环语法四个核心主题,配合真实示例逐层拆解。文中所有示例都来自项目自带的测试用例,你可以在仓库的tests/目录下找到对应文件验证。
如果你还没安装环境,可以先克隆源码仓库:
git clone https://gitcode.com/gh_mirrors/bu/build2一、变量与展开:build2 构建语言的基石
变量声明与引用
build2 变量用=赋值,用$前缀引用,与 shell 的体验类似:
x = hello print $x值得注意的细节是:build2 变量是带类型的。你可以用方括号显式指定类型:
x = [bool] true i = [uint64] 1 s = [string] "hello"类型会随着展开传播:y = $x之后,$type($y)依然是bool;而一旦放进双引号y = "$x",类型就会被抹掉变成普通字符串。这一特性让 build2 能够在构建时做类型安全的检查,参考测试文件tests/expansion/type.testscript。
展开的三种形态
| 写法 | 含义 | 示例 |
|---|---|---|
$var | 普通展开 | print $x |
$(expr) | 求值展开 | print ($i + 1) |
$(target: attr) | 目标/作用域属性展开 | print $(file{foo}: x) |
作用域属性展开是 build2 的特色,它能读取某个 target 或 scope 上的变量值,例如$(./: x)取当前目录下的变量 x,$(file{foo}: y)取目标file{foo}上的变量 y。这些模式在tests/variable/target-specific/testscript中有完整覆盖。
二、build2 内置函数:让构建逻辑更聪明
函数调用语法
build2 函数的调用形式为$命名空间.函数名(参数...),无命名空间时也可省略前缀。最常用的字符串函数如下:
print $string.contains(abcd, bc) # true print $string.starts_with(abcd, ab) # true print $string.icasecmp("a", "A") # true print $icasecmp([string] "a", "A") # truecontains还支持icase(忽略大小写)与once(只匹配一次)等选项:
print $string.contains(aBcD, bC, icase) # true类型与元信息函数
构建时经常需要检查变量的类型与状态,build2 提供了$type()、$null()、$identity()等元函数:
x = [bool] true print $type($x) # bool print $null([null]) # true print $identity(42) # 42在tests/function/目录下,字符串、路径、正则、JSON、整数等函数都有对应的测试用例(如tests/function/string/testscript),是学习函数用法的绝佳资料。
三、build2 条件判断:if / elif / else 全解析
基础 if 语法
if ($i == 2) print two else print other条件表达式写在括号里,支持&&、||、!等逻辑运算,也支持数值、字符串比较。
三种判断变体:if / ifn / ife
这是 build2 容易让新手困惑的地方,却非常实用:
| 关键字 | 判断依据 | 场景 |
|---|---|---|
if/if! | 值是否为 true | 布尔判断 |
ifn/ifn! | 值是否非空 | 变量是否已定义 |
ife/ife! | 值是否为空 | 空值分支 |
foo = ifn $foo print "foo is not null" ife $foo print "foo is empty"同一套规则也适用于elif、elifn、elife,可以串联出多分支逻辑。完整示例见tests/if-else/testscript。
四、build2 循环语法:for 与 while
for 循环遍历值列表
for i: 1 2 3 print $i循环体可以是单行语句,也可以用花括号包成代码块:
for i: 1 2 3 { j = $i print $j }for 循环还支持continue与break做流程控制。要注意的是,continue不能带属性和多余参数,否则会报错——这些边界情况在tests/loop/for.testscript里有专门的测试。
while 循环与计数器
i = [uint64] 1 while ($i != 4) { print $i i += 1 }while 循环常与类型化变量搭配使用,上面的例子会依次输出 1、2、3。它同样支持continue/break和块语法,详见tests/loop/while.testscript。
五、switch 分支:多值匹配的优雅写法
当分支较多时,switch比层层 if 更清晰:
for i: 1 2 3 4 5 { switch $i { case 1 print 1 case 0|4 print 0,4 default print d } }switch 的几个实用特性:
- 合并匹配:
case 0后紧跟case 3表示两个值走同一分支; - 或匹配:
case 0|4表示匹配 0 或 4; - 多值 switch:
switch $i, $j配合case 1, 2可以同时匹配多个变量; - 默认分支:
default兜底。
完整行为参考tests/switch/testscript。
六、综合实战:写一个可复用的构建脚本
把前面学的知识串起来,一个典型的 buildfile 片段长这样:
# 依据配置选择源文件列表 sources = hello.cxx if ($config.build == debug) sources += extra-debug.cxx for s: $sources print "compiling: $s" lib{hello}: $sources这个例子同时用到了变量展开、if 条件、for 循环与目标定义,正是真实项目中常见的组合模式。日常开发中还可以把通用逻辑放进build/root.build或build/export.build(模块导出配置),实现跨目录复用,这也是 build2 推荐的项目组织方式。
七、学习路径与调试技巧
- 多读测试:
tests/eval/、tests/expansion/、tests/loop/、tests/function/下的 testscript 文件就是最权威的语法手册; - 善用 print:用
print输出变量值,是最直接的调试手段; - 注意类型:展开时的类型传播(typed / untyped)常常是隐性 bug 的来源;
- 缩进与块:单行语句与花括号块可以混用,但语义要分清。
总结
build2 构建语言用一套统一而克制的语法,把变量展开、内置函数、条件判断与循环控制整合进构建脚本,让复杂项目的构建逻辑变得可读、可测、可维护。掌握本文的四个核心主题,你就已经跨过了 build2 入门到进阶的门槛。下一步,不妨打开仓库中的tests/目录,亲手运行几个 testscript 示例,把知识变成手感。
【免费下载链接】build2build2 build system项目地址: https://gitcode.com/gh_mirrors/bu/build2
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考