codex-rs 的 Bazel 构建体系:codex_rust_crate 宏、Bzlmod 工具链与 BuildBuddy 远程执行实战
codex-rs 的 Bazel 构建体系codex_rust_crate 宏、Bzlmod 工具链与 BuildBuddy 远程执行实战【免费下载链接】openinterpreterA coding agent for open models like Kimi K3 and GLM 5.3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter本篇基于仓库内的 Bazel 构建文档 展开讲清楚 codex-rs Rust 工作区如何用 Bazel 实现 hermetic可复现、自包含构建MODULE.bazel如何声明工具链、rules_rs如何从Cargo.toml/Cargo.lock导入第三方 crate、defs.bzl中的codex_rust_crate宏如何把 Bazel 目标与 Cargo 约定对齐以及如何通过 BuildBuddy 配置启用远程缓存与远程执行。读完后你应能独立完成本地 Bazel 构建与测试、理解各--config的作用边界并知道新增依赖、新增 crate 时的完整操作流程。需要先说明适用前提文档中注明截至 2026-06-01该 Bazel 体系仍处于实验阶段正在持续稳定化。日常开发仍可以 Cargo 为主Bazel 主要用于 CI、跨平台产物和可复现构建。核心定位Cargo 是事实来源Bazel 是构建执行层原文明确了这一分工原则This repository uses Bazel to build the Rust workspace undercodex-rs. Cargo remains the source of truth for crates and features, while Bazel provides hermetic builds, toolchains, and cross-platform artifacts.这意味着依赖声明、feature、crate 划分全部以 codex-rs/Cargo.toml 和 codex-rs/Cargo.lock 为准Bazel 负责的是构建可复现性版本钉死的 Rust 工具链、自包含hermetic的 LLVM、macOS SDK 等以及跨平台交叉编译产物包括 Windows gnullvm 这种 Cargo 原生不直接支持的 ABI因此你几乎不需要为 Bazel 维护一套并行的依赖清单——这正是后文crate.from_cargo(...)要解决的问题。高层结构四个关键构件原文给出了四段式结构下面逐一结合仓库中的实际文件展开。1.MODULE.bazelBzlmod 依赖与工具链声明根目录 MODULE.bazel 声明了整个仓库的 Bazel 模块模块名为codex承担三类职责1外部模块依赖。关键依赖包括rules_rs 0.0.96新一代 Rust 构建规则见 MODULE.bazel#L93、llvm 0.8.11hermetic LLVM见 MODULE.bazel#L5、apple_support、aws-lc等。2上游模块打补丁。由于 hermetic LLVM 需要一些尚未上游化的定制例如 V8 所需的 custom libc、Windows gnullvm 运行时仓库通过single_version_overridepatches对llvm、abseil-cpp、rules_cc、bzip2等模块打补丁补丁文件集中在 patches/ 目录下如 patches/llvm_rusty_v8_custom_libcxx.patch。对rules_rust本身也打了三个补丁build-script 工具 runfiles、Windows/MSVC 直接链接参数、Windows process wrapper见 MODULE.bazel#L103-L117。3工具链注册。包括macOS SDK 归档下载与 framework 白名单llvm//extensions:osx.bzl见 MODULE.bazel#L31-L78默认 Rust 工具链edition 2024、version 1.95.0MODULE.bazel#L190-L197一个独立的 nightly 工具链nightly/2025-09-18dev_components True专门服务于需要rustc_private的 argument-comment-lintMODULE.bazel#L123-L131Windows 双 ABI 支持MSVC 与 gnullvm 两套repository_setMODULE.bazel#L135-L188。本地 Bazel 版本由 .bazelversion 钉在9.0.0。2.rules_rs的crate.from_cargo(...)从 Cargo 元数据导入第三方 crateMODULE.bazel#L209-L228 展示了原文提到的核心机制crate use_extension(rules_rs//rs:extensions.bzl, crate) crate.from_cargo( cargo_lock //codex-rs:Cargo.lock, cargo_toml //codex-rs:Cargo.toml, platform_triples [ aarch64-unknown-linux-gnu, aarch64-unknown-linux-musl, aarch64-apple-darwin, aarch64-pc-windows-msvc, aarch64-pc-windows-gnullvm, x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, x86_64-apple-darwin, x86_64-pc-windows-msvc, x86_64-pc-windows-gnullvm, ], )crate.from_cargo直接解析 Cargo 工作区的Cargo.toml与Cargo.lock为每个第三方 crate 生成 Bazel 目标并统一暴露在crates仓库下。platform_triples列表同时列出了 9 种目标 triple含 Linux musl、macOS、Windows MSVC 与 gnullvm这正是跨平台产物能力的来源——同一次依赖解析覆盖了所有交叉编译目标。注释中还解释了为何同时保留 MSVC 与 gnullvm 两个 Windows tripleV8 实验仍在消费仅以 MSVC 命名发布的 release 资产。对于需要特殊照顾的上游 crate仓库用crate.annotation做定点修正例如blake3在 Windows gnullvm 上强制启用purefeature因为该工具链无法可靠地生成其 x86 原生汇编MODULE.bazel#L249-L255zstd-sys、ring打补丁修正 MSVC 头文件搜索路径MODULE.bazel#L256-L270aws-lc-sys/aws-lc-rs关闭 build script改用预生成 bindgen 产物MODULE.bazel#L271-L284。这就是原文Evolving the setup一节所说上游 crate 可能需要 patch 或crate.annotation才能在 Bazel 沙箱中构建的具体形态。3.defs.bzl的codex_rust_crate与 Cargo 约定对齐的宏根目录 defs.bzl 提供codex_rust_crate宏defs.bzl#L181封装rust_library、rust_binary、rust_test让 Bazel 目标与 Cargo 的目录约定一一对应。原文说它提供了对大多数一方 crate 合理的默认值但某些情况下需要微调。从宏的参数列表defs.bazel#L181-L206可以看到它的覆盖面参数作用crate_name/crate_features/crate_edition对应Cargo.toml中的名称、feature、edition。宏文档特别提示 feature 会在整个工作区以单一配置编译列表内全部启用应慎用build_script_data暴露给build.rs运行时使用的数据文件compile_data/lib_data_extra库目标的编译期数据 / 运行期数据rustc_flags_extra/rustc_env追加 rustc 参数与环境变量宏默认注入BAZEL_PACKAGE包名见 defs.bazel#L282-L284integration_test_args/unit_test_args/*_timeout集成/单元测试参数与超时test_shard_counts按测试名映射的分片数启用 Bazel 原生分片并标记 flaky三次重试test_tags传给单元 集成测试目标典型用途是no-sandboxextra_binaries/extra_binaries_non_windows把别的 crate 的二进制暴露为测试数据与CARGO_BIN_EXE_*环境变量run_tests_with_wine_exec为每个集成测试生成 Wine 执行变体在 Linux 上跑交叉编译的 Windows exec-server宏内部的工作方式均可在源码中验证构建脚本若存在build.rs生成name-build-script目标cargo_build_script规则defs.bazel#L297-L305库src/**/*.rs非空时生成rust_libraryproc-macro crate 用rust_proc_macro并同步生成单元测试目标defs.bazel#L309-L371二进制按Cargo.toml解析出的binaries表逐一生成rust_binary并导出CARGO_BIN_EXE_name环境变量供集成测试使用——完整复刻了 Cargo 的行为defs.bazel#L376-L391集成测试tests/*.rs每个文件生成一个测试目标源码注释defs.bazel#L497-L513明确列出四种生成形态非分片原生测试、分片原生测试拆成 manual 的rust_test 外层workspace_root_test、Windows 交叉测试、Wine 执行测试。其中workspace_root_testdefs.bazel#L142-L179是一个自研规则通过 workspace_root_test_launcher.sh.tpl / workspace_root_test_launcher.bat.tpl 生成跨平台启动器它在运行时解析出真实的仓库根目录、cd进去并把 runfiles 路径改写为绝对路径。这是为了让insta快照测试看到 Cargo 风格的相对路径配合INSTA_WORKSPACE_ROOT/INSTA_SNAPSHOT_PATH环境变量defs.bazel#L260-L266同时兼容仓库使用--noenable_runfilesmanifest-only runfiles的策略。另一个细节测试目标的rustc_flags中统一加入了--remap-path-prefix../codex-rs和--remap-path-prefixcodex-rsdefs.bazel#L526-L532因为 Bazel 曾对file!()宏产生两种不同的路径前缀剥掉后 insta 快照元数据才与 Cargo 构建一致。4. 每个 crate 的BUILD.bazel各 crate 目录下的BUILD.bazel通常只是调用codex_rust_crate并做少量调整。最简单的形态见 codex-rs/code-mode-host/BUILD.bazelload(//:defs.bzl, codex_rust_crate) codex_rust_crate( name code-mode-host, crate_name codex_code_mode_host, )当 crate 需要额外的编译期/运行期数据、特殊环境变量或测试定制时再按宏的参数列表补充。本地运行 Bazeljustfile 入口仓库根目录 justfile 暴露了常用入口该文件的工作目录为codex-rsjust bazel-test just bazel-clippy这两个 recipe 的实际展开justfile#L158-L164# bazel-test bazel test --test_tag_filters-argument-comment-lint //... --keep_going # bazel-clippy bazel_targets$(scripts/list-bazel-clippy-targets.sh) bazel build --configclippy -- ${bazel_targets}即测试全仓库目标并排除 nightly-only 的 argument-comment-lint 标签clippy 通过--configclippy用 rules_rust 的 Clippy aspect 对目标做检查。此外还有几个直接可用的 recipejust bazel-codexbazel run //codex-rs/cli:codex在 Bazel 构建产物上运行 CLIjustfile#L128-L135just bazel-lock-update/just bazel-lock-check见下文演进一节。一个重要的边界事实原文也强调了普通的本地bazel与just调用全部在本地执行BuildBuddy 缓存、构建事件上报BES、远程下载与远程执行都是 opt-in 配置不选--configbuildbuddy-*就不会接触任何远程服务。BuildBuddy远程缓存与远程执行codex-rs 的 CI 与内部构建通过 BuildBuddy 做共享缓存和远程构建/测试。要提速需要两件事提供 API key并选择一个配置。API key 配置按 BuildBuddy 的认证文档创建 key 后加入~/.bazelrc# Local machine only; this file contains a BuildBuddy credential. common --remote_headerx-buildbuddy-api-keyyour-buildbuddy-api-key把凭据放在工作区外可以降低误提交的概率。如果不同项目需要不同的 key放到%workspace%/user.bazelrc——仓库的 .bazelrc 末尾以try-import %workspace%/user.bazelrc可选导入该文件见 .bazelrc#L225且 .gitignore 已将user.bazelrc排除在版本控制之外。切记不要提交或分享含凭据的文件。选择远程构建配置外部用户应使用buildbuddy-generic-rbe或buildbuddy-genericOpenAI 内部用户默认buildbuddy-openai-rbe。把配置写入%workspace%/user.bazelrccommon --configbuildbuddy-openai-rbe这组配置在 .bazelrc 中有明确定义文件注释说明这些配置只有在用户显式选择时才会接触 BuildBuddybuildbuddy-genericcache/BES/下载均指向remote.buildbuddy.io无远程执行buildbuddy-generic-rbe在上一项基础上叠加--configremote使用remote.buildbuddy.io远程执行器buildbuddy-openai/buildbuddy-openai-rbe同样的两级结构但指向openai.buildbuddy.io。--configremote本体设置--strategyremote、--extra_execution_platforms//:rbe并把并发提到--jobs800。而//:rbe平台由 rbe.bzl 生成其container-imageexec property 钉死了含 git/python3/dotslash 等测试依赖的 Ubuntu 镜像按主机架构选 x86_64 或 aarch64 镜像及 sha256保证远程执行环境一致。各配置的完整对照表原文表格调用/配置需要 keyCache/BES构建执行测试执行bazel ...否无本地本地bazel ... --configbuildbuddy-generic是remote.buildbuddy.io本地本地bazel ... --configbuildbuddy-generic-rbe是remote.buildbuddy.io远程远程bazel ... --configbuildbuddy-openai是openai.buildbuddy.io本地本地bazel ... --configbuildbuddy-openai-rbe是openai.buildbuddy.io远程远程Cache/BES主机同时用于远程下载--experimental_remote_downloader。CI 侧租户选择由统一 wrapper 完成GitHub Actions 通过 .github/scripts/run_bazel_with_buildbuddy.py 路由所有 Bazel 构建与输出解析命令更高层的辅助脚本如 .github/scripts/run-bazel-ci.sh、.github/scripts/rusty_v8_bazel.py都把远程配置选择委托给它。wrapper 的设计要点原文描述代码可印证它读取 GitHub Actions 的仓库与事件载荷来决定租户而不是让每个 workflow 文件复制租户选择逻辑它归一化 Bazel 启动选项让同一 job 内的所有 Bazel 调用复用同一个 server 和内存中的分析缓存见脚本中startup_args函数.github/scripts/run_bazel_with_buildbuddy.py#L23-L33加载阶段的bazel query目标发现命令在本地运行因为它只枚举 label不需要远程缓存或执行没有 API key 时wrapper 会剥离远程 CI 配置、退回本地运行pull request 事件载荷缺失或畸形时fail closed到 generic 主机只有在 GitHub Actions 中、且是受信运行openai/codex仓库内的 push/dispatch/同仓 PR才选择 OpenAI 主机fork 的 PR 一律本地运行。CI 各配置与执行位置的对应关系原文表格CI 配置远程配置构建执行测试执行ci-linux*-rbe远程主机远程主机ci-v8*-rbe远程主机远程主机ci-macos*-rbe远程主机本地ci-windows-cross*-rbe远程主机本地ci-windows非 RBE本地本地无 key 的 CI 回退无本地本地这些ci-*配置同样定义在 .bazelrc 中并各有明确注释ci-linux可全量远程构建/测试覆盖 x86 与 arm runnerci-macos构建远程化、测试留在本地--strategyTestRunnerdarwin-sandbox,localci-windows-cross用 Linux 远程执行构建 Windows gnullvm 二进制、测试留在 Windows runner 以保留 Bazel 分片与 flaky 重试并强制 V8 的mksnapshot在本地执行因为 Windows 快照必须由 Windows 的 mksnapshot 二进制生成。wrapper 源码中也维护了哪些 CI 配置需要远程构建执行的映射ci-linux、ci-macos、ci-v8、ci-windows-cross见 .github/scripts/run_bazel_with_buildbuddy.py#L13-L18。若想在本地验证 generic 远程配置BUILDBUDDY_API_KEY... GITHUB_REPOSITORYmy-fork/codex \ ./.github/scripts/run_bazel_with_buildbuddy.py \ build --configci-linux //codex-rs/cli:codex演进构建体系改依赖、加 crate 的标准流程更新依赖后刷新 Bzlmod 锁文件改动Cargo.toml/Cargo.lock后在仓库根目录运行just bazel-lock-update它执行bazel mod deps --lockfile_modeupdatejustfile#L146-L147按需更新 MODULE.bazel.lock。要把锁文件变更和 Cargo 锁文件一起提交。本地验证锁文件对齐与 CI 相同检查just bazel-lock-check该 recipe 指向 scripts/check-module-bazel-lock.sh脚本内部调用同一个 BuildBuddy wrapper 执行bazel mod deps --lockfile_modeerror失败时会明确提示运行just bazel-lock-update并提交锁文件。如果某个上游 crate 无法在 Bazel 沙箱中构建、或需要做交叉编译适配正确姿势是给它打 patch 或在MODULE.bazel中加crate.annotation前文blake3/zstd-sys/ring即是现成范例而不是改 crate 源码。新增 crate / binary 的三步流程像往常一样把 crate 加入 Cargo 工作区创建BUILD.bazel并调用codex_rust_crate参考相邻 crate如 codex-rs/code-mode-host/BUILD.bazel如果依赖需要特殊处理编译期/运行期数据、集成测试附加二进制、环境变量等调整codex_rust_crate参数。原文特别提到一个常见定制把test_tags [no-sandbox]加给测试目标让测试在无沙箱模式下运行。文档建议尽量避免因为它绕过了沙箱隔离典型必要场景是测试本身使用 Seatbelt——Bazel 沙箱在 macOS 上也是 Seatbelt 实现而 Seatbelt 不能嵌套。为进一步限制影响面可以把这类测试隔离到独立 crate。顺带一提Bazel 侧的 lint 与测试基础设施just bazel-clippy使用的--configclippy会启用rust_clippy_aspect且因为 rules_rust 不读取 Cargo 的 lint 级别.bazelrc 里手工维护了一份与codex-rs/Cargo.toml[workspace.lints.clippy]对齐的 deny 列表测试环境默认RUST_MIN_STACK83886088 MiB因为 Rust libtest 在 Windows 上以 std-spawned 线程跑测试体默认 2 MiB 栈对大型 async 测试 future 不够仓库采用--noenable_runfilesmanifest-only runfiles策略这也是workspace_root_test启动器存在的直接原因之一。参考与延伸阅读原文给出的外部参考为 Bazel 官方文档Bazel 概览与 Bzlmod 模块系统、rules_rust和rules_rs两个规则项目的仓库此处不再重复外链可分别在对应官方渠道检索。仓库内的深入阅读路径文档本身codex-rs/docs/bazel.md模块与工具链声明MODULE.bazel、MODULE.bazel.lock宏实现defs.bzlcodex_rust_crate于 L181 起workspace_root_test规则于 L142 起平台定义含//:rbe、Windows gnullvm/MSVC 平台BUILD.bazel、rbe.bzl全局 Bazel 配置与 BuildBuddy/CI 配置.bazelrcCI wrapper 及其租户选择逻辑.github/scripts/run_bazel_with_buildbuddy.py上游补丁集patches/小结codex-rs 的 Bazel 体系本质上是Cargo 管声明、Bazel 管执行的双轨制——crate.from_cargo消除依赖清单的双写codex_rust_crate消除构建目标的重复描述MODULE.bazelpatches/保证工具链与上游 crate 的可复现性BuildBuddy 各--config则以 opt-in 方式提供从纯缓存到全远程执行的分级加速。本地开发用just bazel-test/just bazel-clippy即可起步新增依赖后记住just bazel-lock-update并提交锁文件就能跟上这套仍在演进中的构建体系。【免费下载链接】openinterpreterA coding agent for open models like Kimi K3 and GLM 5.3项目地址: https://gitcode.com/GitHub_Trending/op/openinterpreter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考