第4章:AOSP源码下载与编译

好,咱们进入正题。这一章要聊的是AOSP源码的下载和编译。说实话,这是每个做车载座舱系统的人,都绕不开的第一道坎。

我记得刚入行那会儿,第一次下载AOSP,看着终端里滚动的日志,心里还挺激动。结果编译的时候,整整折腾了两天——环境配不对,内存不够,磁盘空间爆了。嗯,这些坑我今天都帮你踩过了。

4.1 Repo工具:Android源码的管家

Repo是什么?说白了,它是一个脚本工具,帮我们管理几百个Git仓库。AOSP不是单个仓库,而是由数百个Git仓库组成的。你想想看,一个个手动clone,那得疯掉。

Repo就是干这个的。它基于Git,但比Git更懂Android。

安装Repo

我个人习惯把Repo放在 ~/bin 目录下。这样干净,也好管理。

mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

注意,这里有个坑。我曾经遇到过网络问题,Google的地址有时候连不上。你可以试试用清华的镜像:

export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
小提示:~/bin 加到PATH里,这样随时都能用repo命令。

Repo的常用命令

你只需要记住几个核心命令就行:

  • repo init — 初始化,选择分支
  • repo sync — 同步代码,下载所有仓库
  • repo start — 创建本地分支,方便修改
  • repo status — 查看仓库状态

我刚开始用的时候,经常忘记 repo sync 后面可以加 -j4 参数。这个参数能并行下载,快很多。比如:

repo sync -j4

如果你的机器性能好,可以试试 -j8 甚至 -j16。但别太贪心,网络带宽才是瓶颈。

4.2 源码分支选择:选对版本少踩坑

分支选择这事,我吃过亏。早期做项目时,选了一个太新的分支,结果很多第三方库不兼容,折腾了半个月才搞定。

对于车载座舱系统,我建议你优先考虑 Android 12Android 13 的稳定分支。为什么?

  • Android 12 开始,Google 正式推出了 Automotive 分支
  • 社区支持好,文档多
  • 硬件兼容性经过验证

具体怎么选?看分支命名:

分支名 说明 适用场景
android-12.0.0_r32 Android 12 稳定版 车载项目首选
android-13.0.0_r41 Android 13 稳定版 新项目推荐
android-14.0.0_r15 Android 14 预览版 尝鲜或预研
注意: 不要选 master 分支。那是开发中的代码,随时可能编译不过。我曾经手贱试过一次,编译到一半报错,查了半天发现是刚提交的bug。

4.3 编译环境配置:别让环境卡住你

环境配置这块,我建议你用 Ubuntu 20.04 LTS。这是目前最稳的选择。我之前试过Ubuntu 22.04,有些依赖包需要手动处理,麻烦。

必备软件包

直接跑这个命令,把基础依赖装好:

sudo apt-get update
sudo apt-get install -y git-core gnupg flex bison build-essential \
  zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
  libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev \
  lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig

嗯,这里要注意。不同Ubuntu版本,包名可能略有差异。比如 libncurses5 在22.04上可能叫 libncurses5-dev。遇到报错就搜一下,别硬扛。

Java环境

Android 12 及以上,需要 OpenJDK 11。别用Oracle JDK,我试过,会有兼容性问题。

sudo apt-get install openjdk-11-jdk

装完后检查一下版本:

java -version

输出应该是 openjdk version "11.0.x"

磁盘空间

这个我必须强调。AOSP源码下载下来大概 30GB,编译后占用 150GB-200GB。我建议你至少准备 300GB 的空闲空间。

我曾经在只有120GB的笔记本上编译,编译到一半磁盘满了,整个环境崩了。那种感觉,不想再体验第二次。

4.4 编译命令:make与m/mm/mmm

终于到编译环节了。这部分我多说几句,因为命令虽简单,但用错了很浪费时间。

初始化编译环境

每次编译前,先跑这个:

source build/envsetup.sh

这个脚本会设置一堆环境变量。我习惯把它加到 .bashrc 里,省得每次手动敲。

选择编译目标

lunch

跑完 lunch 后,会列出所有可选的编译目标。对于车载系统,我们选 aosp_car_x86_64-userdebug。为什么是 userdebug?因为它既有 user 的稳定性,又有 debug 的调试能力。

核心命令对比:

  • make — 全量编译,编译整个系统。第一次编译必须用这个。
  • m — 从源码根目录编译,可以指定模块。比如 m frameworks/base
  • mm — 编译当前目录下的模块。你在某个模块目录里,直接 mm 就行。
  • mmm — 编译指定路径的模块。比如 mmm packages/apps/Settings

我个人的工作流是这样的:

  1. 第一次编译,用 make -j8,全量编译。去喝杯咖啡,大概1-2小时。
  2. 修改代码后,用 mmm 只编译改动的模块。比如改了SystemUI,就 mmm frameworks/base/packages/SystemUI
  3. m 编译依赖较多的模块,比如 m services

这里有个技巧。编译时加 -j 参数,指定并行任务数。一般设为 CPU核心数 × 2。比如8核CPU,用 -j16。但别超过物理内存能承受的范围,否则会OOM。

避坑指南: 我曾经在编译SystemUI时,直接用了 make,结果等了40分钟。其实用 mmm 只需要3分钟。记住:只编译你改动的部分,别每次都全量编译。

编译输出

编译完成后,镜像文件在 out/target/product/<设备名>/ 目录下。比如:

out/target/product/car_x86_64/
├── system.img
├── vendor.img
├── boot.img
└── ...

这些就是你要烧录到车机上的镜像文件。

小结

这一章的内容,说白了就是三件事:下载源码、配环境、编译。每一步都有坑,但只要你按我说的来,基本不会出大问题。

下一章,我们会聊Android系统的启动流程。嗯,那才是真正有意思的部分。