3. AOSP源码下载与同步:Repo init与sync详解、源码目录结构分析、常见同步问题与解决

好,咱们进入第三个章节。源码下载,这是所有车机定制工作的第一步。说实话,这一步看着简单,但坑是真不少。我见过太多新手在这卡上好几天,甚至把硬盘搞崩了。今天我就把Repo这套工具掰开揉碎了讲清楚。

3.1 Repo是什么?为什么Google要用它?

AOSP有多大?完整下载下来,大概有50GB到80GB。这还只是代码,不算编译产物。更关键的是,它由几百个Git仓库组成——Android、内核、硬件驱动、工具链……每个都是独立的Git项目。

你想想看,如果一个个手动git clone,那得克隆到猴年马月?而且版本之间还有依赖关系,比如某个版本的Android必须配某个版本的内核。这就是Repo存在的意义。

Repo本质上是一个Python脚本,它帮我们管理这上百个Git仓库。它不替代Git,而是Git的“管家”。你告诉Repo“我要Android 12”,它就去读取对应的manifest文件,然后把所有仓库都拉到正确的版本上。

核心概念:Repo = Git的批处理工具 + 版本依赖管理器

3.2 Repo init:初始化你的工作区

下载源码的第一步,就是执行repo init。这个命令会创建一个.repo目录,里面存放了manifest文件和Repo工具本身。

# 基本用法
mkdir aosp-source
cd aosp-source
repo init -u https://android.googlesource.com/platform/manifest

# 指定分支(比如Android 12)
repo init -u https://android.googlesource.com/platform/manifest -b android-12.0.0_r32

# 使用镜像(国内用户强烈推荐)
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-12.0.0_r32

参数详解:

  • -u:manifest仓库的URL。这是Repo的“总纲”,里面定义了要下载哪些仓库、每个仓库的路径和版本。
  • -b:分支名。不指定的话,默认是master分支。做车机开发,我建议你锁定一个稳定分支,比如android-12.0.0_r32。
  • -m:指定manifest文件名。默认是default.xml,但有些厂商会提供自己的manifest文件。

我的习惯:每次init之前,我都会先看一眼manifest文件的内容。你可以用浏览器打开manifest仓库,看看里面定义了哪些项目。这样心里有数,知道这次下载会拉下来什么东西。

3.3 Repo sync:真正开始下载代码

init只是初始化,真正下载是在repo sync这一步。这个命令会读取.repo/manifest.xml,然后逐个仓库执行git clone或git fetch。

# 基本同步
repo sync

# 并行下载(加快速度)
repo sync -j8

# 强制同步(忽略本地修改)
repo sync -f

# 只同步当前分支
repo sync -c

常用参数:

  • -jN:并行任务数。我一般设成CPU核心数的两倍。比如8核CPU,就用-j16。但注意,网络带宽有限,设太大反而可能变慢。
  • -c:只同步当前分支。默认会同步所有分支的历史,加上-c可以省不少时间和磁盘空间。
  • -f:如果某个仓库同步失败,继续同步其他仓库。这个很有用,因为几百个仓库里难免有一两个网络超时。

注意:repo sync会覆盖你本地的未提交修改。如果你在某个仓库里改了东西但没提交,sync时会报错。这时候要么先提交,要么用repo sync -f强制覆盖。

3.4 源码目录结构分析

下载完成后,你会看到这样一个目录结构。我挑几个关键的说一下:

aosp-source/
├── art/                 # Android Runtime,ART虚拟机
├── bionic/              # C标准库实现
├── bootable/            # 启动引导相关
├── build/               # 编译系统核心(Soong、Makefile)
├── cts/                 # 兼容性测试套件
├── dalvik/              # Dalvik虚拟机(旧版)
├── developers/          # 开发者文档
├── development/         # 开发工具和示例
├── device/              # 设备相关配置(厂商定制在这里)
├── external/            # 第三方开源库
├── frameworks/          # Android框架层(核心)
│   ├── base/            # 基础框架(ActivityManager、WindowManager等)
│   ├── native/          # 原生服务(SurfaceFlinger、AudioFlinger等)
│   └── av/              # 音视频相关
├── hardware/            # 硬件抽象层(HAL)
├── kernel/              # Linux内核(车机定制重点)
├── libcore/             # Java核心库
├── packages/            # 应用包
│   ├── apps/            # 系统应用(Settings、Launcher等)
│   └── providers/       # 内容提供者
├── system/              # 系统核心组件
│   ├── core/            # 系统核心库
│   ├── media/           # 媒体相关
│   └── net/             # 网络相关
├── vendor/              # 厂商定制(驱动、预装应用)
└── prebuilts/           # 预编译工具链

车机开发重点关注:

  • device/:你的车机设备配置就在这里。比如屏幕分辨率、按键映射、系统属性等。
  • hardware/:HAL层,车机特有的硬件(如CAN总线、车载音频)驱动在这里实现。
  • vendor/:厂商私有的东西,比如车机预装的导航、音乐应用。
  • kernel/:内核,车机对实时性要求高,内核调优是重头戏。

我的经验:刚开始接触AOSP时,别想着把所有目录都看懂。先聚焦device/hardware/vendor/这三个目录。它们占了车机定制80%的工作量。

3.5 常见同步问题与解决

这部分我得多说几句。我在项目里遇到过各种奇葩问题,有些甚至让我怀疑人生。下面这几个是最常见的:

问题1:网络超时或断开

这是最普遍的。AOSP的服务器在国外,国内下载经常断。

解决方案:

  • 使用国内镜像,比如清华、中科大的AOSP镜像。
  • --no-tags参数,不下载标签信息,能省不少流量。
  • 写个脚本自动重试:
#!/bin/bash
while true; do
  repo sync -j8 -c --no-tags
  if [ $? -eq 0 ]; then
    echo "同步完成!"
    break
  fi
  echo "同步失败,5秒后重试..."
  sleep 5
done

问题2:磁盘空间不足

完整AOSP大概需要80GB,但编译后轻松超过200GB。我见过有人用128GB的SSD,结果同步到一半就满了。

解决方案:

  • 预留至少250GB空间。
  • 使用-c参数只同步当前分支。
  • 定期清理.repo目录中的临时文件。

问题3:Python版本不兼容

Repo是用Python写的,老版本Repo可能不支持Python 3。而新系统默认都是Python 3。

解决方案:

  • 更新Repo到最新版:curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
  • 或者指定Python版本:python3 ~/bin/repo init ...

问题4:manifest文件冲突

如果你修改了.repo/manifest.xml,下次sync时会报冲突。

解决方案:

  • 不要手动修改manifest文件。
  • 如果确实需要定制,用repo manifest -o my_manifest.xml导出后修改,然后用-m指定。

避坑指南:我曾经有一次在同步到90%时断网了,结果重新sync时发现之前下载的仓库全被删了。后来我才知道,repo sync默认是“原子操作”——要么全部成功,要么全部回滚。所以,建议你第一次同步时用repo sync -j4,别贪快。等全部下载完,后续增量同步再用高并行数。

3.6 小结

嗯,这一章内容不少。总结一下:

  • Repo init:初始化工作区,指定manifest和分支。
  • Repo sync:真正下载代码,注意并行数和网络环境。
  • 目录结构:重点关注device、hardware、vendor三个目录。
  • 常见问题:网络、磁盘、Python版本、manifest冲突——都有对应的解决办法。

下一章,我们会进入编译系统的核心——Soong和Blueprint。到时候你会看到,AOSP的编译系统比你想的要复杂得多,但也灵活得多。