第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 12 或 Android 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。
我个人的工作流是这样的:
- 第一次编译,用
make -j8,全量编译。去喝杯咖啡,大概1-2小时。 - 修改代码后,用
mmm只编译改动的模块。比如改了SystemUI,就mmm frameworks/base/packages/SystemUI。 - 用
m编译依赖较多的模块,比如m services。
这里有个技巧。编译时加 -j 参数,指定并行任务数。一般设为 CPU核心数 × 2。比如8核CPU,用 -j16。但别超过物理内存能承受的范围,否则会OOM。
make,结果等了40分钟。其实用 mmm 只需要3分钟。记住:只编译你改动的部分,别每次都全量编译。
编译输出
编译完成后,镜像文件在 out/target/product/<设备名>/ 目录下。比如:
out/target/product/car_x86_64/
├── system.img
├── vendor.img
├── boot.img
└── ...
这些就是你要烧录到车机上的镜像文件。
小结
这一章的内容,说白了就是三件事:下载源码、配环境、编译。每一步都有坑,但只要你按我说的来,基本不会出大问题。
下一章,我们会聊Android系统的启动流程。嗯,那才是真正有意思的部分。