
build2 自定义规则深度解析ad hoc 规则与 Buildscript 实战指南【免费下载链接】build2build2 build system项目地址: https://gitcode.com/gh_mirrors/bu/build2build2 是一款现代化的 C/C 构建系统它最大的特色之一就是支持在 buildfile 中直接内联自定义规则也就是本文要讲的build2 ad hoc 规则。与传统的先写插件、再注册规则方式不同ad hoc 规则让你用极简的 Buildscript 语法甚至直接用 C 代码把构建逻辑就地写在构建描述文件里。本指南面向新手和普通用户带你从零掌握 build2 自定义规则的三种形态ad hoc Buildscript 规则、ad hoc C 规则与 ad hoc 模式规则pattern rule并附上可直接运行的实战示例。为什么需要自定义规则标准构建场景编译、链接、安装build2 开箱即用但现实项目总有特殊需求生成代码后要做文本替换拷贝、压缩、签名等自定义加工自定义测试步骤或清理逻辑批量处理同一类目标如所有doc{}文件。如果每次都为这些需求去写一个 C 规则插件并编译进构建系统成本太高。build2 的 ad hoc 规则正是为此而生规则即配方recipe配方即代码且无需重新编译构建系统。核心概念recipe 与 rule 的关系在 build2 中recipe配方描述如何构建一个目标而rule规则负责决定是否匹配、以及如何应用配方。ad hoc 规则把两者合二为一通过{{ }}语法内联配方规则本身由 build2 自动注册无需手工rule {}声明支持按目标、按类型、按正则模式pattern三种匹配粒度。相关实现可参考 libbuild2/adhoc-rule-buildscript.hxx 与 libbuild2/adhoc-rule-cxx.hxx。一、ad hoc Buildscript 规则最简单入门方式基础语法与最小示例ad hoc Buildscript 规则使用{{ ... }}包裹配方语法与 buildfile 脚本一致最典型的写法如下foo: bar {{ cp $path($) $path($) }}这里的关键元素foo: bar—— 声明目标foo及其先决条件bar{{ ... }}—— 配方体默认作用于update操作$—— 先决条件prerequisite的路径$—— 目标target的路径。执行b update时build2 会先构建bar然后运行配方中的cp命令生成foo。这段示例与官方测试用例 tests/recipe/cxx/testscript 中的写法完全一致。用 diag 输出友好诊断信息默认情况下配方中的命令会原样回显。若想输出更友好的诊断信息可使用diag伪内建命令alias{strip}: exe{hello} {{ diag strip $ strip $path($) }}diag会按 verbosity 级别智能显示信息这一用法也是手册中推荐的 alias 动作 模式见 doc/manual.cli 的 targets 章节。绑定到不同操作update、clean、test配方默认绑定update但通过前置操作声明行可以绑定到任意操作。在{{ }}之前用%开头的行指定操作即可foo: bar % update clean {{ ... }}官方测试中就有% update clean同时覆盖更新与清理的场景。同理声明% test可让配方只在b test时执行——ad hoc 规则让目标即动作成为可能。二、ad hoc C 规则深度定制高级玩法当 Buildscript 无法表达复杂逻辑时build2 允许你把配方直接写成 C 代码在{{ }}首行声明c 11 为 API 版本其后紧跟 C 实现foo: bar {{ c 1 recipe apply (action a, target t) const override { ... return perform_update; } }}C 规则的核心结构recipe—— 声明这是配方类apply()—— 匹配/应用阶段返回最终 recipe如perform_update可配合match_prerequisite_members()、inject_fsdir()等辅助函数处理先决条件与目录。例如官方测试 tests/recipe/cxx/testscript 中展示了一个完整的cp配方它用execute_prerequisitesfile()更新先决条件、用depdb做依赖数据库记录、最后调用cpfile()完成拷贝还顺带处理了perform_clean清理逻辑。何时选择 C 配方需要访问 build2 内部 API依赖数据库、目标状态机需要精确控制诊断输出与 verbosity需要动态依赖、文件缓存等高级能力需要跨目标共享复杂逻辑。C 配方的实现类位于 libbuild2/adhoc-rule-cxx.hxx 中的cxx_rule_v1它封装了 recipe 库的位置与状态确保规则变化时能正确触发重建。三、ad hoc 模式规则Pattern Rule一次匹配一类目标前面两种规则针对单个目标而ad hoc pattern rule用正则表达式批量匹配目标一条规则服务整个目标族。语法上在{{ }}首行加上pattern关键字{{ buildscript pattern pattern-target: pattern-prereq ... }}也可以写成 C 版本{{ c 1 pattern ... }}。模式规则能做什么按目标类型/名称正则匹配例如对所有doc{*.md}执行同一套处理在配方中通过apply_group_members()注入组成员、通过apply_prerequisites()注入先决条件支持捕获组把正则匹配结果用于配方逻辑。模式规则的核心是 libbuild2/adhoc-rule-regex-pattern.hxx 中的adhoc_rule_regex_pattern类——它保存正则表达式文本在匹配阶段解析目标签名并把匹配结果安全地保存在 target 辅助存储中供后续apply_*()调用使用。NEWS 中还提到模式规则支持自定义名称、ad hoc 组成员替换、先决条件替换等高级特性。四、实战对比三种规则怎么选规则类型语法入口匹配粒度适用场景学习成本ad hoc Buildscript 规则{{ ... }}单目标拷贝、替换、打包等 Shell 级操作⭐ 低ad hoc C 规则{{ c 1 ... }}单目标复杂逻辑、依赖数据库、API 调用⭐⭐⭐ 高ad hoc 模式规则{{ ... pattern }}目标族批量处理同类型/同名目标⭐⭐ 中新手建议从 Buildscript 规则起步80% 的定制需求都能用它解决逻辑变复杂再升级为 C 配方需要批量覆盖时才引入 pattern 关键字。五、进阶技巧与避坑提示路径函数配方中尽量用$path($)、$path($)这类路径函数取绝对路径避免工作目录歧义。先决条件更新Buildscript 规则中先决条件默认在配方执行前更新若需更新后再匹配可关注updateunmatch语义见 adhoc-rule-buildscript.hxx 中的include_unmatch相关常量。诊断规范优先使用diag而非裸命令回显让日志更专业。静态链接限制官方测试注明ad hoc C 规则在静态链接的构建系统中不受支持跨平台测试时注意这一点。从源码学案例官方仓库的 tests/recipe/cxx/testscript 和 tests/recipe/buildscript/testscript 是绝佳的学习素材覆盖了更新、清理、测试、动态依赖等完整场景。写在最后build2 的 ad hoc 规则体系把构建系统可扩展性从写插件降低到了写配方让自定义构建逻辑真正融入构建描述文件既保留了 build2 强大的依赖追踪与并行调度能力又获得了极高的表达自由。无论你是想快速解决一个拷贝问题还是需要深度定制一套构建流程从本文的 ad hoc Buildscript 实战开始你都能在几分钟内写出第一条属于自己的 build2 自定义规则。【免费下载链接】build2build2 build system项目地址: https://gitcode.com/gh_mirrors/bu/build2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考