十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

workerd 的 V8 版本升级全流程指南:从补丁 Rebase 到 Bazel 依赖同步

workerd 的 V8 版本升级全流程指南:从补丁 Rebase 到 Bazel 依赖同步 workerd 的 V8 版本升级全流程指南从补丁 Rebase 到 Bazel 依赖同步【免费下载链接】workerdThe JavaScript / Wasm runtime that powers Cloudflare Workers项目地址: https://gitcode.com/GitHub_Trending/wo/workerd导读workerdCloudflare Workers 的 JavaScript / Wasm 运行时深度内嵌 Google V8 引擎并在其上维护了一套用于支撑 Workers 平台特性的定制补丁。当 Chrome Beta 推进 V8 版本时workerd 需要把整套补丁迁移到新版本之上并同步更新 Bazel 构建配置中的版本号、完整性校验值与对齐依赖。本文以仓库中的官方升级文档 docs/v8-updates.md 为骨架结合 ci/v8_update.py 等源码实现完整讲解手动升级的 12 个步骤与半自动更新助手的使用方法。读完本文你将掌握 workerd 的 V8 升级机制、补丁再生成与依赖对齐的底层原理能够独立完成一次完整的 V8 版本升级。为什么 workerd 要单独维护 V8V8 是 workerd 的运行时核心但 workerd 并不直接使用上游原版 V8。仓库通过 Bazel 模块 build/deps/v8.MODULE.bazel 拉取 V8 官方源码 tarball并在其上叠加一组自定义补丁。该文件头部注释解释了关键约束googlesource 生成的 tarball 不具备确定性无法使用http_archive因此 V8 本体通过 GitHub 官方镜像以 tarball 方式引入而 zlibChromium fork、icuChromium fork、trace_event 等依赖仍必须走 git 协议。该文件的核心配置块如下当前仓库中的实际取值VERSION 15.3.76.11当前锁定使用的 V8 版本标签INTEGRITY sha256-zhD6KsBTOQwTXzj1uuZ5gVbYJENz9R38eAGOF0OCk0tarball 的 SHA-256 校验值Bazel 偏好格式PATCHES [...]依次列出 patches/v8 下按数字前缀命名的补丁文件当前为0001至0041共 41 个http_archive从https://github.com/v8/v8/archive/refs/tags/VERSION.tar.gz下载strip_prefix为v8-VERSION并按PATCHES列表逐个应用-p1补丁git_repository拉取llvm-libcChromium googlesource 镜像供 V8 使用local_path_override将perfetto_cfg、google_benchmark指向仓库内的build/perfetto、build/google-benchmark并通过workerd-v8间接引用 V8以便内部非开源仓库可以覆写 V8 的构建方式。这些补丁并非装饰品而是 workerd 平台能力的一部分。例如 0001-Allow-manually-setting-ValueDeserializer-format-vers.patch 为 V8 的ValueDeserializer增加了SetWireFormatVersion()方法允许 workerd 读取历史上缺失版本头的序列化数据时显式指定线格式版本0006-Implement-Promise-Context-Tagging.patch、0013-Implement-cross-request-context-promise-resolve-hand.patch等则与 Workers 的 Promise 上下文语义相关。正因为补丁与业务强耦合升级 V8 不是简单改一个版本号而是一次完整的补丁迁移工程。升级前的准备工作升级流程的第一步是确定目标版本。官方文档建议访问 Chromium Dashchromiumdash.appspot.com查看 Chrome Beta 渠道使用的 V8 版本——workerd 以 Chrome Beta 的 V8 为跟踪目标这与 ci/v8_nightly.py 中通过chromiumdash.appspot.com/fetch_releases?platformWin32channelbeta探测最新 Beta V8 版本号的逻辑一致latest_beta_v8()函数。随后需要在本机安装 Google 的depot_tools提供fetch、gclient等工具。安装方式见 depot_tools 官方教程的 Setting up 一节这里不再赘述。获取 V8 源码时官方文档特别强调mkdir v8 cd v8 fetch v8并提醒务必把 V8 副本放在 workerd 仓库之外否则仓库内的 V8 源码树可能干扰 Bazel 的依赖解析与//...通配构建。接下来把本地 V8 同步到 workerd 当前锁定的旧版本记为old_versioncd path_to_v8/v8 git checkout old_version gclient sync其中old_version就是从build/deps/v8.MODULE.bazel中读出的VERSION值。gclient sync会把 V8 的 DEPS 文件声明的所有子依赖icu、dragonbox、fast_float 等一并检出到与old_version匹配的版本。手动升级 V8 的 12 步流程这是官方文档的核心章节以下逐步展开。第 13 步确定目标版本并准备 V8 副本即上一节所述确认 Chrome Beta 的最新 V8 版本号、安装depot_tools、在仓库外fetch v8。第 4 步将本地 V8 同步到 workerd 当前版本从build/deps/v8.MODULE.bazel读取当前VERSION作为old_version然后git checkout old_version并gclient sync确保工作区与 workerd 的基线完全一致。第 5 步创建补丁分支并应用 workerd 补丁git checkout -b workerd-patches git am --keep-non-patch path_to_workerd/patches/v8/*--keep-non-patch是与第 7 步git format-patch的-k参数配套的它保留上游 V8 提交自带的主题前缀如[wasm]这样第 7 步重新生成的补丁能沿用既有的文件名前缀与编号便于PATCHES列表稳定维护。若git am中途失败可先用git am --abort回退并排查具体补丁。第 6 步将 workerd 补丁 Rebase 到新版本假设目标版本为new_version执行git rebase --onto new_version old_version由于 workerd 补丁基于旧版 V8 编写升级后上下文往往发生偏移rebase 过程中通常需要少量手工修补。官方文档建议在此阶段就完成带补丁的本地 V8 构建与测试参见 V8 官方 Testing 文档尽早暴露补丁与新版本的兼容问题而不是等回到 workerd 仓库再排查。这一步也是整个流程中风险最高的环节——补丁的语义尤其是涉及 Promise 上下文、序列化格式、内存分配等平台行为的改动必须由人来确认在新版本中依然成立。第 7 步重新生成补丁rebase 成功后用git format-patch从new_version基线导出补丁git format-patch --full-index --no-signature --no-stat --zero-commit new_version各参数含义--full-indexdiff 中输出完整的 blob 哈希保证补丁在任何克隆中都稳定可应用-k保留原始提交的 subject 前缀对应第 5 步的--keep-non-patch--no-signature去掉git format-patch默认追加的签名信息--no-stat省略 diffstat 统计缩小补丁体积--zero-commit将补丁头部的 commit 哈希置零避免暴露提交哈希差异。第 8 步替换仓库中的补丁删除 patches/v8 下原有的补丁文件把第 7 步在 V8 目录生成的补丁复制进来。ci/v8_update.py的finish_update()在自动流程中正是先清空旧补丁再用shutil.copy2复制新生成的补丁以保留时间戳等元数据。第 9 步更新v8.MODULE.bazel中的 VERSION / PATCHES / INTEGRITY在 build/deps/v8.MODULE.bazel 中将VERSION改为new_version根据新增/删除的补丁刷新PATCHES列表更新INTEGRITY。官方文档给出两种获取方式直接用新版本编译 workerd从 Bazel 报告的完整性不匹配错误中读出 Bazel 偏好格式的校验值或先下载https://github.com/v8/v8/archive/refs/tags/new_version.tar.gz再执行openssl dgst -sha256 -binary tarball_filename | openssl base64 -A得到的 base64 值前加上sha256-前缀即为INTEGRITY。ci/v8_update.py中的_tarball_integrity()函数用 Python 的hashlib.sha256加base64实现了完全相同的计算逻辑sha256- base64(...)两者结果一致可相互校验。第 10 步更新 V8 的依赖并重新生成deps.MODULE.bazelV8 的部分第三方依赖以独立 Bazel 依赖的形式由 workerd 管理记录在 build/deps/deps.jsonc 中。升级 V8 后需要把这些依赖的提交同步到新版本 V8 的DEPS文件所引用的提交可在本地 V8 副本的path_to_v8/DEPS中找到。文档明确指出当前需要跟踪的依赖包括perfetto、com_googlesource_chromium_icu和simdutf并给出了一个重要提醒V8 是通过 Chromium 间接依赖perfetto与simdutf的无法直接从 V8 的 DEPS 推断出 V8 对应的是 GitHub 上的哪个版本因此对这两个依赖采取直接升到 GitHub 最新版的安全策略即可。从 build/deps/deps.jsonc 的注释与 ci/v8_update.py 的V8_DEPENDENCIES映射可以确认更完整的依赖清单及其对齐方式依赖名deps.jsonc 中的 nameV8 内路径是否与 V8 提交严格对齐com_googlesource_chromium_icuthird_party/icu是freeze_commit对齐dragonboxthird_party/dragonbox/src是freeze_commit对齐fast_floatthird_party/fast_float/src是freeze_commit对齐fp16third_party/fp16/src是freeze_commit对齐highwaythird_party/highway/src是freeze_commit对齐perfettothird_party/perfetto否github_release取最新版simdutfthird_party/simdutf否github_release取最新版其中 icu、dragonbox、fast_float、fp16、highway 在deps.jsonc中都带注释我们想避免与 V8 产生版本偏差所以使用完全一致的版本并以freeze_commit锁定提交哈希。更新依赖后运行依赖更新脚本重新生成deps.MODULE.bazelpython3 build/deps/update-deps.py脚本也支持指定单个依赖名进行定向更新见下文助手章节。第 11 步运行 workerd 测试套件bazel test //...官方文档要求在提交前确认整个仓库的测试在升级后的 V8 下全部通过。若测试失败需要回到补丁层排查必要时调整补丁内容。第 12 步提交并推送评审将build/deps/v8.MODULE.bazel、build/deps/deps.jsonc、patches/v8/*.patch以及可能涉及的源码改动一并提交推送到远程分支进行代码评审。半自动更新助手ci/v8_update.py手动 12 步中有大量机械性工作创建分支、应用补丁、rebase、重新生成补丁、更新版本号与校验值ci/v8_update.py 将这些步骤自动化官方文档也特别提示该脚本尚未被充分测试若执行失败请回退到手动流程并仔细审查其改动。检查是否有可用更新check-updatepython3 ci/v8_update.py check-update脚本通过latest_beta_v8()访问 Chromium Dash 获取 Chrome Beta 的 V8 版本与 build/deps/v8.MODULE.bazel 中当前的VERSION比较有新版本时打印current_version - new_version并以退出码1结束已是最新时不打印任何内容并以退出码0结束加--machine-readable参数仅打印新版本号便于在脚本或 CI 中取用。执行更新update new_versionpython3 ci/v8_update.py update new_version从源码看prepare_update()的机械流程与手动步骤一一对应删除并重建临时目录/tmp/workerd-v8/v8常量CHECKOUT以--depth1浅克隆拉取old与target两个标签该脚本默认远程为https://github.com/v8/v8.git基于旧版本检出workerd-patches分支用git am --keep-non-patch --3way --committer-date-is-author-date依次应用patches/v8/*.patch执行git rebase --onto target old workerd-patches。若 rebase 顺利结束脚本会立即调用finish_update()完成补丁再生成与配置更新若 rebase 因冲突失败脚本打印提示并返回失败此时需要在临时检出中人工处理cd /tmp/workerd-v8/v8 git status # 解决冲突并把文件加入暂存区git add git rebase --continue重复此过程直到 rebase 完成。官方文档特别强调补丁冲突必须人工审查以确保 workerd 特有的行为序列化、Promise 上下文、内存管理等在新版本中仍然被保留而不是机械地解决行级冲突。收尾finish new_versionpython3 ci/v8_update.py finish new_versionfinish_update()在临时检出中执行git format-patch --full-index -k --no-signature --no-stat --zero-commit --output-directory ... new_version重新生成补丁然后清空patches/v8并用copy2复制新补丁最后更新build/deps/v8.MODULE.bazel 中的VERSION、INTEGRITY由_tarball_integrity()实时下载 tarball 计算与PATCHES列表build/deps/deps.jsonc 中 icu、dragonbox、fast_float、fp16、highway 的freeze_commit由_update_aligned_dependencies()从 V8 新版本的DEPS文件正则提取提交哈希写入。官方文档明确警告rebase 未完成前不要运行finish否则会用半成品状态重新生成补丁并覆写锁定配置。手动补完依赖更新与验证助手不会运行update-deps.py。文档要求手工对比新旧两个版本 V8 的DEPS文件检查dragonbox、fast_float、fp16、highway、perfetto、simdutf的提交是否有变化对每个发生变化的依赖定向执行依赖更新脚本python3 build/deps/update-deps.py dependency这一步会重新生成对应的deps.MODULE.bazel内容build/deps/update-deps.py 是仓库所有 Bazel 依赖的自动生成器输出文件头部带有 AUTOGENERATED DO NOT EDIT 警告。注意脚本目录下update-deps.py中TARGET_FILTER正是从命令行参数读取依赖名实现只更新某一个依赖的定向能力。随后完成手动流程的第 11、12 步运行bazel test //...验证全部测试审查生成的改动后提交推送。与 CI 夜间任务的关系ci/v8_update.py并非孤立存在。仓库中的 ci/v8_nightly.py 将其作为底层库复用导入prepare_update、finish_update、changed_dependencies、latest_beta_v8等实现探测 Chrome Beta 新 V8 → 自动 rebase 补丁 → 更新对齐依赖 → 构建//src/workerd/server:workerd→ 运行bazel test //...的夜间流水线ci/v8_nightly_shared.py 则提供共享的 git/subprocess/日志基础设施并在补丁冲突或构建失败时调用 AI 助手opencode在有限轮次内尝试修复。理解这套 CI 可以帮你判断当你手动执行ci/v8_update.py时走的正是与 CI 相同的代码路径只是没有自动化的 AI 修复环节。常见问题与注意事项V8 副本必须放在仓库外仓库内的 V8 源码树会干扰 Bazel 的依赖图与//...构建务必遵循文档建议。--keep-non-patch与-k必须成对使用前者在git am时保留 subject 前缀后者在git format-patch时保留同一前缀二者配合才能维持补丁文件名的稳定性。rebase 冲突是常态而非例外文档明确通常会有少量补丁编辑工作且ci/v8_nightly.py中补丁冲突默认需要 AI 辅助或人工审查切勿盲目--skip跳过错失补丁语义。INTEGRITY 必须与 tarball 严格对应可交叉验证——ci/v8_update.py的_tarball_integrity()与文档给出的openssl dgst -sha256 -binary ... | openssl base64 -A计算同一文件会得到相同结果。perfetto / simdutf 不要尝试从 V8 DEPS 反推 GitHub 版本二者经由 Chromium 间接依赖直接升级到最新版即可icu、dragonbox、fast_float、fp16、highway 则必须与 V8 的DEPS提交严格对齐避免版本偏差导致编译或行为不一致。助手脚本并非金标准官方文档承认ci/v8_update.py未经过充分测试失败时回退到手动 12 步流程并以bazel test //...的最终结果为准。通过上述流程workerd 得以始终跟进 Chrome Beta 的 V8 版本同时保证 41 个平台定制补丁持续生效。无论你是想手动完成一次升级还是希望借助ci/v8_update.py半自动推进本文对应的文档 docs/v8-updates.md 与源码 ci/v8_update.py 都是可以直接照做的权威参考。【免费下载链接】workerdThe JavaScript / Wasm runtime that powers Cloudflare Workers项目地址: https://gitcode.com/GitHub_Trending/wo/workerd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表