深入理解 depot_tools:Chromium 源码开发全流程(fetch/gclient/git cl 使用详解与踩坑经验)
一、前言:为什么要了解 depot_tools?
对于浏览器开发工程师来说,无论是参与 Chromium / Chrome / 360 内核开发,还是想调试学习浏览器底层机制,“源码拉取 → 依赖同步 → 构建 → 提交” 是绕不开的几件大事。
这些工作在普通项目中可能只需要一个 git clone
就结束了,但在 Chromium 这类 超大规模多仓库项目 中却极其复杂——
主仓库超过 30GB
依赖仓库多达 数百个
每个仓库都有自己的 commit/branch
提交必须走 Gerrit、Hook、TryBot 等流程
为了彻底降低使用门槛,Google 官方推出了一套脚本工具,统称为 depot_tools,它几乎是 “Chromium 开发者的瑞士军刀”。
二、什么是 depot_tools?
depot_tools = 一整套脚本 + 执行工具的集合
它包含:
工具名 | 作用 |
---|---|
fetch | 一键拉取 Chromium/其他仓库源代码 |
gclient | 依赖管理与同步工具(解析 DEPS 文件) |
git cl | 提交/上传/下载 patch(与 Gerrit 交互) |
autoninja | 快速构建(调度 ninja) |
cipd | 包管理工具,用于下载编译工具链等二进制文件 |
... | 其它辅助脚本 |
☑️ depot_tools 不是安装软件,无需安装,只需要把它加入 PATH 即可。
三、fetch:第一次拉取源码的最佳工具
3.1 fetch 做了什么?
创建
.gclient
配置文件下载主仓库(如
chromium/src
)根据仓库内的
DEPS
文件自动拉取依赖仓库下载工具链(clang / python / node / gn 等)
也就是说,你只敲一个命令就能把 “整个 Chromium 开发环境” 搭好。
3.2 常用命令
# 拉取最新 chromium fetch chromium # 指定版本 fetch chromium --nohooks --revision 120.0.6112.4 # 拉取 v8 fetch v8 # 拉取 other-project fetch <项目名> [--options...]
⚠️ 常见误区 1:
很多人执行 fetch
后直接开始写代码,结果发现缺一堆依赖工具没下,比如 clang-format
、gn
、ninja
,原因是没执行 hooks。
gclient runhooks
这是必须的,通常建议:
fetch xxx --nohooks gclient sync gclient runhooks
3.3 fetch 常见踩坑
场景 | 原因 | 解决 |
---|---|---|
卡在 "Checking out bundle ..." | 网络访问 Google @国外服务器 | 配置科学网络或者使用国内镜像(GitMirrors、清华) |
报错 “Key ‘deps’ error” | depot_tools 太旧或 Python 版本不兼容 | 更新 depot_tools,确保使用 Python>=3.8 |
下载了 20% 就中断 | Git 超时或被 reset | 使用 --no-history 或者加 --depth=1 |
Node/clang 没有正确下载 | 没运行 hooks | gclient runhooks |
四、gclient:依赖管理的“大总管”
4.1 gclient 是什么?
它是一个 统一门面脚本,用于解析 Chromium 项目里的 DEPS
文件,把依赖仓库一个一个拉下来,确保版本一致。
不同于普通 Git 子模块,gclient
支持:
指定精确的 commit
递归依赖
patch / 变更同步
hook 脚本
4.2 日常高频指令整理
命令 | 作用 |
---|---|
gclient sync | 拉取主仓库和所有依赖 |
gclient sync --with_branch_heads | 拉取所有 branch |
gclient sync --revision src@xxx | 同步指定版本 |
gclient revert | 丢弃所有修改 |
gclient runhooks | 执行构建相关脚本 |
gclient status | 查看当前依赖状态 |
4.3 gclient sync 踩坑经验
一直卡在某个仓库,速度极慢
→ 说明该仓库走的是https://chromium.googlesource.com/...
,需要科学网络。暂时解决办法:修改
.gclient
中https://
→https://e.coding.net/...
镜像或者单独把那个仓库 clone 到
src/third_party/...
内再执行gclient sync
“solutions” 错误 / 重复
→.gclient
文件被手动修改错了
→ 最快办法:删除.gclient
文件,重新fetch
一次DEPS 更新之后编译失败
→ gclient 更新了依赖,但 build 目录中的 ninja 文件没更新
→ 解决:rm -rf out/Default gn gen out/Default autoninja -C out/Default chrome
五、git cl:用来提交 / 上传 / patch / 评审
和普通 Git 的区别在于:
普通 Git | git cl |
---|---|
git push | git cl upload (上传到 Gerrit) |
git apply | git cl patch <id>(从 Gerrit 拉 patch) |
git checkout | git cl issue <id>(切换到某个 changelist) |
无 | git cl try(触发 TryServer 编译) |
5.1 最小工作流
git new-branch myfix ... 修改代码 ... git add . && git commit -m "Fix xxx" git cl upload
此时会进入 Gerrit 评审界面,等 reviewer 给 LGTM.
5.2 高频场景踩坑合集
场景 | 问题原因 | 解决办法 |
---|---|---|
upload 时提示 “no issue found and upload denied” | 没有设置 Gerrit 账号 / 没通过身份认证 | git config --global user.email ... |
reviewer 看不到代码 | commit message 第 1 行不是英文简洁描述 | 调整 commit message 重新 upload |
触发 try 时报 “No try job matches” | 没有配置 .trybots | git cl try --bot <bot-name> |
patch 切换失败 “dirty tree” | 当前工作区存在未提交内容 | git stash / git cl discard |
patch 应用后出现冲突 | patch 版本落后于主仓库 | git rebase origin/main 再 upload |
六、工具之间的完整链路关系图
首次拉代码 ↓ fetch ↓ +----------------------+ | 创建 .gclient | | 拉主仓库 | | 生成 DEPS | +----------------------+ ↓ gclient sync ↓ ┌-------------------------┐ │ 依赖仓库1 (third_party) │ │ 依赖仓库2 │ │ ... │ └-------------------------┘ ↓ gclient runhooks ↓ gn / ninja ↓ (可选) git cl upload
七、小结 & 建议
建议 |
---|
✅ 第一次拉源码:fetch + gclient sync + runhooks |
✅ 每天更新代码:gclient sync |
✅ 修改/提交:git new-branch → commit → git cl upload |
✅ 不要手改 .gclient 和 DEPS ,除非你非常清楚它是干什么的 |
⚠️ 遇到“奇怪错误”第一件事情:更新 depot_tools |
⚠️ 编译失败优先怀疑:是不是没 runhooks / 没重新 gn |
✅ 如果你在中国大陆工作,强烈建议配置代理或镜像源 |