尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

RisingWave 的 workspace-hack 构建机制:用 cargo-hakari 统一 Cargo 特性解析加速大型工作区编译

RisingWave 的 workspace-hack 构建机制:用 cargo-hakari 统一 Cargo 特性解析加速大型工作区编译 数据库流处理后端数据工程【免费下载链接】risingwaveEvent streaming platform for agentic AI. Continuously ingest, transform, and serve event streams in real time, at scale.项目地址https://gitcode.com/gh_mirrors/ri/risingwave点击查看免费下载本文以 RisingWave 仓库中的 src/workspace-hack/README.md 为核心线索结合仓库内 40 余个 crate 的Cargo.toml、根工作区清单以及Makefile.toml/ CI 脚本中的真实用法系统讲解 workspace-hack 这个由 cargo-hakari 管理的魔法 crate在 Cargo 大型工作区中解决什么问题、如何工作、如何重新生成与校验以及仓库里围绕它留下的边界约束。读完本文你将理解 Cargo 特性统一feature unification的代价与 workspace-hack 的化解思路并能在自己的多 crate 工程里复现同样的构建优化实践。一、背景Cargo 特性统一为什么会成为大型工作区的痛点Cargo 的 feature 解析遵循特性统一feature unification规则当同一个依赖被多个包以不同的 feature 集合引用时Cargo 会在解析阶段将各方声明的 feature 取并集最终这个依赖只以一份开了所有被请求 feature的形式参与构建。这套规则保证了最终二进制中依赖版本唯一、行为一致但也带来了两个大型工作区特有的问题特性解析开销大工作区越大、依赖越多Cargo 需要反复计算每个依赖最终应启用哪些 feature解析时间随 crate 数量与 feature 组合显著增长编译产物碎片化feature 集合参与了 crate 的构建指纹。一旦不同包对同一依赖请求了不同 feature 组合即使最终并集相同Cargo 也可能在多处重复编译同一依赖的不同 feature 变体拉长全量构建与 CI 时间。RisingWave 是一个拥有上百个成员 crate 的巨型 Rust 工作区见根 Cargo.toml 的[workspace] members列表涵盖src/batch、src/common、src/meta、src/storage、src/stream、src/frontend等全部核心模块这类问题会被放大得十分明显。workspace-hack 正是为化解这一问题而生的仓库内建方案。二、workspace-hack 是什么仓库内那个魔法 cratesrc/workspace-hack/README.md的开篇标题就是How this magic works这个魔法是如何运作的其核心内容可以浓缩为两点这个 crate 由cargo-hakari工具管理README 原文This crate is managed by cargo-hakari它的作用一句话概括无论工作区中哪个包正在被构建都强制整个工作区使用统一后的 feature 集合README 原文it forces the workspace to use the unified features, regardless of which package is being built。展开来说workspace-hack 的运作思路是由cargo-hakari自动分析整个工作区的依赖图把所有 crate 依赖过的第三方库及其全部 feature 并集汇总成一份清单写进 workspace-hack 自己的Cargo.toml然后让工作区里每一个 crate 都把 workspace-hack 声明为依赖。这样任何一次构建都必然包含这份全量 feature依赖Cargo 解析器从任意入口出发得到的特征解析结果都一致从而消除按包构建时 feature 组合漂移导致的重复编译让特性解析结果全局唯一加快解析与增量编译命中率保证测试、benchmark、各节点二进制compute / meta / frontend / compactor构建出行为一致的依赖变体。需要说明的是cargo-hakari把这一机制称为 workspace-hack package其详细原理解释包括为什么能加快构建在其官方文档中有专门章节上文是基于仓库 README 表述与 Cargo 特性统一语义的展开。三、仓库中的落地形态从文件结构看这个 crate3.1 crate 本体生成物 空壳实现src/workspace-hack/目录下只有三个文件职责分工非常清晰Cargo.toml由cargo hakari生成的清单文件文件头部注释写明 This file is generated bycargo hakari 与再生成命令cargo hakari generatesrc/lib.rs一个没有任何逻辑的 stubThis is a stub lib.rs.workspace-hack 只是承载依赖声明的汇聚点本身不需要任何代码README.md即本文所依据的核心文档说明该 crate 的定位与维护方式。在 Cargo.toml 中可以看到它的包属性[package] name workspace-hack version { workspace true } edition { workspace true } homepage { workspace true } keywords { workspace true } license { workspace true } repository { workspace true } description workspace-hack package, managed by hakari publish false其中两个细节值得注意version、edition、license等全部继承自[workspace.package]见根 Cargo.toml保证它始终与工作区主版本保持一致publish false表明这是一个纯内部构建辅助 crate不会发布到 crates.io文件头部的注释也提示了可以选择发布该 crate这一选项但 RisingWave 选择了不发布。3.2 被 37 个以上 crate 依赖全员接入workspace-hack 的价值取决于被整个工作区共同依赖。在 RisingWave 中从核心模块到测试套件几乎全员声明了对它的依赖统一使用相对路径形式workspace-hack { path ../workspace-hack }例如src/batch/Cargo.toml批处理执行引擎src/cmd_all/Cargo.tomlall-in-onerisingwave二进制入口src/common/Cargo.toml、src/stream/Cargo.toml、src/storage/Cargo.toml、src/frontend/Cargo.toml、src/meta/Cargo.toml二层嵌套的 crate 则使用../../workspace-hack如 src/batch/executors/Cargo.toml、src/meta/service/Cargo.toml、src/storage/compactor/Cargo.toml、src/utils/pgwire/Cargo.toml各类测试 crate 同样接入如 src/tests/sqlsmith/Cargo.toml、src/tests/regress/Cargo.toml、src/tests/state_cleaning_test/Cargo.toml以 src/cmd_all/Cargo.toml 为例它构建的risingwave单二进制是 meta-node、compute-node、frontend-node、compactor 等全部组件的合集因此它必须与所有模块共享同一套特性解析结果——把 workspace-hack 挂在这里等于给整棵依赖树钉死了统一坐标。四、从 Cargo.toml 的 HAKARI SECTION 看生成物的自描述结构workspace-hack 的 Cargo.toml 中最核心的结构是文件中部由 hakari 划定的保护区### BEGIN HAKARI SECTION # Disabled by running cargo hakari disable. # To re-enable, run: # cargo hakari generate ### END HAKARI SECTIONcargo-hakari用BEGIN/END HAKARI SECTION注释把由工具管理的部分与其他手写内容隔开。工具每次重新生成时只重写这段区域其余手写字段包名、描述、publish 等保持不变避免工具与人工编辑互相覆盖。值得如实指出当前仓库的状态这一 HAKARI SECTION 内部目前只有说明注释、没有任何实际依赖条目说明该仓库在某个时点执行过cargo hakari disable当前 workspace-hack 处于禁用状态——即 crate 骨架与全员依赖声明仍在但特征并集清单暂未生成。这与仓库中两处证据吻合CI 脚本 ci/scripts/check.sh 中 hakari 检查被注释掉并写明Disable hakari until we make sure its useful在确认它确实有用之前先停用# Disable hakari until we make sure its useful # echo --- Rust cargo-hakari check # cargo hakari generate --diff # cargo hakari verifysrc/object_store/Cargo.toml 中的注释说明该 crate 在引入 hdfs 后从 hakari 管理中排除其workspace-hack依赖被注释掉。这也解释了为何src/lib.rs只是一个空壳当清单区为空时workspace-hack 退化为一个无依赖、无逻辑的占位 crate依赖它的各模块不受影响而一旦需要重新启用只需跑一次cargo hakari generate即可。五、日常维护重新生成与校验的命令流程README 指出该 crate 完全由 cargo-hakari 管理因此日常维护不涉及手写依赖而是围绕两条命令展开cargo hakari generate扫描整个工作区重新计算所有依赖的 feature 并集并将结果写回 workspace-hack 的 HAKARI SECTION。这也是 Cargo.toml 头部注释标注的再生成命令cargo hakari verify校验当前生成的清单是否与工作区实际状态一致若依赖或 feature 发生变化而未重新生成会报错退出起到 CI 门禁作用。RisingWave 通过 cargo-make 把这条流程封装成了标准化任务。在根 Makefile.toml 的check-hakari任务中可以看到完整闭环[tasks.check-hakari] private true category RiseDev - Check description Run cargo hakari check and attempt to fix install_crate { min_version 0.9.24, crate_name cargo-hakari, binary cargo, test_arg [hakari, --help], install_command binstall } script echo Running $(tput setaf 4)cargo hakari$(tput sgr0) checks and attempting to fix cargo hakari generate --diff --quiet || cargo hakari generate cargo hakari verify /dev/null test $? -eq 0 || exit 1 这里体现了工程化的容错设计先用cargo hakari generate --diff --quiet做只对比、不落盘的检查如果 diff 非空说明清单已过期则自动执行完整cargo hakari generate修复最后用cargo hakari verify严格校验并让 CI 失败。另外install_crate声明了 cargo-hakari 的最小版本0.9.24并用cargo binstall安装与 Makefile.toml 的install-tools任务中批量安装 cargo-hakari 的做法一致保证开发者与 CI 环境工具版本一致。六、边界约束与 workspace-config 的互斥、与依赖检查工具的协作6.1 workspace-hack 不能依赖 workspace-config仓库里还有一个与 workspace-hack 定位类似但用途相反的 cratesrc/utils/workspace-config/README.md。它同样是利用 Cargo 特性统一机制来强制某些配置但方向恰好互补workspace-config负责把部分依赖的 feature 固定下来例如静态编译期的日志级别、通过rw-static-link特性静态链接 OpenSSL并且只能被最终二进制入口risingwave_cmd与risingwave_cmd_all依赖它的 README 中明确写了一条硬性约束It should not be depended by workspace-hack, otherwise the features will be always enabled.——如果 workspace-hack 依赖了 workspace-config那么 workspace-config 所固定的 feature 会被工作区中所有 crate 无条件继承只为最终二进制生效的设计意图就被破坏了。这两条约束合在一起勾勒出了仓库对特性统一工具的精细分工workspace-hack 解决全局解析一致workspace-config 解决二进制专属配置二者互不越界。6.2 依赖检查工具对 workspace-hack 的豁免workspace-hack 这类只声明依赖、从不被使用的 crate 会触发cargo-machete、cargo-udeps这类未使用依赖检查工具的误报。RisingWave 在根 Cargo.toml 中显式做了豁免配置[workspace.metadata.cargo-machete] ignored [ workspace-hack, expect-test, pretty_assertions, serde, ... ] [workspace.metadata.cargo-udeps.ignore] normal [workspace-hack] development [expect-test, pretty_assertions]此外最依赖 workspace-hack 的 src/cmd_all/Cargo.toml 也在cargo-machete与cargo-udeps两处ignored列表中单独列出了workspace-hack。这一方面说明工具链已经理解这类 crate 的依赖是构建期全局性的不能按普通未使用依赖处理另一方面也说明任何新增的依赖检查/清理工具接入时都需要把 workspace-hack以及 workspace-config纳入豁免名单否则会误报。七、总结在大型工作区复现这套实践回到 src/workspace-hack/README.md 那句无论构建哪个包都强制使用统一 feature的核心表述RisingWave 的这套实践可以提炼为可在其他工程复用的四步方案引入 cargo-hakari安装工具仓库要求最小版本 0.9.24让src/workspace-hack成为工作区成员对应根 Cargo.toml 中的src/workspace-hack全员依赖工作区所有需要统一解析的 crate 通过workspace-hack { path ../workspace-hack }声明依赖让任意构建入口都触达统一 feature 清单生成与门禁用cargo hakari generate维护清单、cargo hakari verify做一致性校验并把二者封装进Makefile.toml的check-hakari任务或 CI 脚本处理边界为依赖检查工具配置豁免明确哪些 crate如 object_store 这类带特殊条件依赖的需要排除在 hakari 管理之外同时注意与 workspace-config 这类二进制专属特性工具保持互斥避免特性被意外全局放大。最后需要再次强调当前仓库的客观状态workspace-hack 的清单区处于cargo hakari disable之后的空状态CI 中的 hakari 检查被注释src/object_store/Cargo.toml 也标注了排除说明。这意味着读者若在本仓库执行cargo hakari generate会重新生成并激活这套统一机制——这正是 README 所描述的魔法从概念走向可运行的完整路径。赞分享数据库流处理后端数据工程【免费下载链接】risingwaveEvent streaming platform for agentic AI. Continuously ingest, transform, and serve event streams in real time, at scale.项目地址https://gitcode.com/gh_mirrors/ri/risingwave点击查看免费下载相关推荐深入解析 Diem 工作区的 diem-workspace-hack用 Cargo 特性统一机制加速大型 Rust 项目编译缓存深入解析 Diem 工作区的 diem workspace hack用 Cargo 特性统一机制加速大型 Rust 项目编译缓存 diem workspace区块链金融科技RisingWave 的 workspace-config通过 Cargo Feature 统一机制配置静态链接与编译期日志RisingWave 的 workspace config通过 Cargo Feature 统一机制配置静态链接与编译期日志 导读 workspace con数据库流处理后端数据工程Spacedrive 的 Cargo 构建环境.cargo/config.toml 模板化生成机制与 cargo xtask 工作流Spacedrive 的 Cargo 构建环境 .cargo/config.toml 模板化生成机制与 cargo xtask 工作流 本文聚焦 Spaced桌面应用移动开发后端存储数据同步上一篇Qwen3-Next重磅发布80B参数如何实现10倍推理提速下一篇5步精准定位彻底解决PyTorch动态链接库加载失败难题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表