1. AOSP源码同步的痛点与优化思路
第一次同步AOSP源码的经历就像在沙漠里找水——明明知道绿洲就在那里,但就是走不到。我清楚地记得第一次尝试同步android-13.0.0_r82分支时,连续失败了7次,每次都是在不同进度条位置报错退出。最崩溃的是第5次,已经下载了80GB数据后突然遇到网络中断,一切又要重头开始。
为什么AOSP同步这么困难?根本原因在于:
- 代码仓库体积爆炸式增长:Android 13单个版本源码已超过200GB(含.git元数据)
- 跨国网络稳定性问题:默认源服务器位于海外,连接经常中断
- Git设计局限性:传统clone会下载全部历史记录,而AOSP历史提交超过500万次
去年Google官方论坛就有开发者抱怨:"同步android-14.0.0_r29时下载了900GB数据!"(来源:AOSP downloads just got much bigger - Google Groups)。这促使我研究出一套组合优化方案:
# 清华大学镜像源 + 月度打包文件 + 深度限制 curl -OC - https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar tar -xvf aosp-latest.tar -C aosp/ cd aosp repo init --partial-clone --depth=1 -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-13.0.0_r82 repo sync -c -j8这个方案相比传统方式有三个关键改进:
- 镜像源选择:国内镜像速度提升10-20倍
- 初始数据包:月度tar包减少约60%下载量
- 同步参数:--partial-clone和--depth=1避免下载无用历史
2. 镜像源选择的艺术
很多开发者不知道,AOSP官方其实维护着全球镜像列表。但选择不当的镜像可能导致同步失败。我测试过多个主流镜像,这里分享实测数据:
| 镜像源 | 平均速度 | 稳定性 | 更新频率 |
|---|---|---|---|
| 谷歌官方(android.googlesource.com) | 200KB/s | ★★☆ | 实时 |
| 清华大学(tuna) | 8MB/s | ★★★ | 每日 |
| 中科大(ustc) | 6MB/s | ★★★ | 每日 |
| 腾讯云(cloud.tencent) | 5MB/s | ★★☆ | 每周 |
为什么推荐清华镜像?除了速度快,它有两个独特优势:
- 提供月度打包文件(aosp-latest.tar),节省初始下载时间
- 自动同步谷歌安全补丁,延迟不超过24小时
配置方法也很简单:
# 修改repo的默认URL export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo' # 或者永久修改 git config --global url.https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/.insteadof https://android.googlesource.com/注意:部分企业内网可能会拦截非官方源,同步前建议先测试curl是否能访问镜像站
3. 参数优化的三重境界
3.1 基础版:-c和-j参数
大多数教程只教到这一步:
repo sync -c -j8-c参数表示只同步当前分支,-j8是并行任务数。但实际使用中发现:
- 对android-13.0.0_r82这样的大分支,仍需下载约80GB数据
- 并行数过高可能导致服务器限流(建议根据CPU核心数调整)
3.2 进阶版:--depth=1浅克隆
这是Git的经典优化手段:
repo init --depth=1 -u [URL]效果立竿见影:
- 代码体积减少40%(仅保留最新快照)
- 同步时间缩短50%
但有两个致命缺陷:
- 无法查看历史提交记录
- 后续切换分支困难
3.3 终极版:--partial-clone智能过滤
Android 11开始支持的新特性:
repo init --partial-clone --clone-filter=blob:limit=10M -u [URL]这个方案的精妙之处在于:
- 立即下载小于10MB的文件(占日常开发的90%)
- 大文件(如内核镜像)按需下载
- 保留完整提交历史
实测数据:
| 方案 | 初始体积 | 完整体积 | 适用场景 |
|---|---|---|---|
| 传统clone | 200GB | 200GB | 需要完整历史 |
| --depth=1 | 80GB | 80GB | 仅编译 |
| --partial-clone | 60GB | 按需增长 | 平衡型开发 |
4. 疑难问题解决方案
4.1 Python版本冲突
AOSP要求Python 3.6+,但很多系统默认是2.7。遇到过最奇葩的错误:
File "/usr/bin/repo", line 51 def print(self, *args, **kwargs): ^ SyntaxError: invalid syntax完美解决方案:
# 查看已安装版本 ls -l /usr/bin/python* # 设置多版本共存 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 2 sudo update-alternatives --config python # 选择3.84.2 同步中断恢复
当遇到"error: Cannot checkout device/google/raviole-kernel"时:
- 定位问题项目:
cd .repo/projects/device/google/raviole-kernel- 删除异常目录:
rm -rf .repo/projects/device/google/raviole-kernel- 继续同步:
repo sync -c --fail-fast -j14.3 磁盘空间不足
Android源码编译需要至少300GB空间。如果同步中途报"No space left",可以:
- 清理.git临时文件:
find .repo -name "*.tmp" -exec rm -f {} \;- 使用稀疏检出(只同步必要模块):
repo sync -c platform/frameworks/base platform/packages/apps/Settings5. 实战:从零同步android-13.0.0_r82
完整操作流程(实测通过):
# 1. 准备环境(Ubuntu 20.04+) sudo apt install git python3 curl # 2. 通过镜像下载月度包(约60GB) mkdir ~/aosp && cd ~/aosp curl -OC - https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar tar -xvf aosp-latest.tar -C ./ # 3. 初始化仓库 repo init --partial-clone --no-use-superproject \ -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest \ -b android-13.0.0_r82 # 4. 开始同步(推荐tmux后台运行) tmux new -s sync repo sync -c -j$(nproc --ignore=2)如果一切顺利,3-5小时后你会看到:
Checking out: 100% (1145/1145), done in 4h12m38s repo sync has finished successfully.6. 高级技巧:增量同步与本地镜像
对于团队开发,可以建立本地镜像:
# 首次创建镜像(需要大容量存储) repo init --mirror -u [URL] repo sync -j10 # 开发者从本地同步 repo init --reference=/path/to/mirror -u [URL] repo sync这种方案带来两个好处:
- 后续同步速度提升10倍以上
- 统一代码版本,避免兼容性问题
最近在给公司搭建CI系统时,我用这个方案将同步时间从6小时压缩到20分钟。关键是定期更新镜像:
# 每周执行 cd /path/to/mirror repo sync -j107. 避坑指南
千万不要做的事:
- 直接sudo运行repo(会导致权限混乱)
- 在Windows WSL1中同步(文件系统性能极差)
- 使用--depth=1后切换分支(必现冲突)
推荐的做法:
- 使用ext4文件系统(NTFS性能损失30%)
- 为repo配置缓存:
git config --global http.postBuffer 1048576000 git config --global core.compression 9- 网络不稳定时添加重试参数:
repo sync -c -j8 --fetch-submodules --no-tags --prune --force-sync记得去年有个同事在同步时强制断电,导致.repo目录损坏。修复方法是:
find .repo -name "*.lock" -exec rm -f {} \; repo sync --force-sync