2. AOSP源码下载与编译:环境准备(Ubuntu)、Repo工具使用、源码下载策略、编译目标选择(lunch)、首次编译避坑
好,咱们正式开始动手了。这一章,我带你走一遍AOSP源码下载和编译的完整流程。说实话,这一步是很多新手的第一道坎,也是我当年踩坑最多的地方。别担心,我把那些坑都标记好了,你跟着走就行。
2.1 环境准备:Ubuntu系统配置
先说系统。AOSP官方推荐Ubuntu,我个人习惯用 Ubuntu 20.04 LTS 或 22.04 LTS。为什么?因为这两个版本的GCC、Python、Make等工具链跟AOSP的兼容性最好。你想想看,要是系统版本太新,某些库还没适配,编译到一半报错,那才叫崩溃。
硬件方面,我建议至少 16GB内存 + 500GB硬盘空间。我在项目中遇到过用8GB内存编译,结果swap分区狂转,一个编译任务跑了整整12小时。嗯,别省这个钱。
2.1.1 安装必要依赖包
打开终端,执行以下命令。这是我从官方文档里提炼出来的最小依赖集,少了任何一个都可能让你卡在某个奇怪的地方。
sudo apt update
sudo apt 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
python2。AOSP某些老版本脚本还依赖Python 2,虽然官方说在迁移,但实际项目中我遇到过因为缺Python 2导致repo init失败的案例。
2.1.2 配置Git与SSH
源码下载需要Git,建议先配好用户名和邮箱。这一步看似简单,但很多人忽略。我见过同事因为没配邮箱,导致提交记录全是乱码,后面追查问题非常痛苦。
git config --global user.name "你的名字"
git config --global user.email "你的邮箱@example.com"
另外,如果你需要访问私有仓库或Gerrit,建议配置SSH密钥。生成方式很简单:
ssh-keygen -t rsa -b 4096 -C "你的邮箱"
cat ~/.ssh/id_rsa.pub
把输出的公钥添加到你的Git托管平台(比如Gerrit或GitHub)的SSH Keys里。这一步不做,后面repo sync可能会频繁要求输入密码,非常烦人。
2.2 Repo工具使用:不只是下载器
Repo是Google为AOSP量身定做的多仓库管理工具。说白了,它就是一个Python脚本,帮你批量操作几百个Git仓库。我第一次用Repo时,觉得它就是个「高级版git clone」,后来才发现它远不止如此。
2.2.1 安装Repo
安装Repo很简单,但要注意版本。我建议用Google官方源,别用系统包管理器里的旧版本。
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=$PATH:~/bin
记得把 export PATH=$PATH:~/bin 加到你的 ~/.bashrc 或 ~/.zshrc 里,不然每次开新终端都要重新设置。
2.2.2 Repo init:选择分支
初始化一个AOSP工作目录,核心命令是 repo init。这里有个关键点:选择正确的分支。我刚开始做车载开发时,直接拉了master分支,结果编译出来的系统跟车机硬件不兼容,折腾了两天才发现是分支选错了。
对于车载系统,我建议选择稳定分支,比如 android-13.0.0_rXX 或 android-12.0.0_rXX。具体版本号可以去 AOSP官方构建号页面 查。
mkdir aosp-car
cd aosp-car
repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r41
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-13.0.0_r41。我在项目中一直用清华源,速度稳定,没出过问题。
2.3 源码下载策略:别傻等
repo sync 是下载源码的命令。但如果你直接执行 repo sync,可能会等到天荒地老。AOSP源码大概有30-50GB,包含几百个仓库。我分享几个实战策略。
2.3.1 断点续传与并行下载
网络不稳定时,repo sync 可能会中断。别慌,它支持断点续传。我一般这样写:
repo sync -c -j4 --no-tags
-c:只下载当前分支的代码,不下载所有分支的历史。省空间。-j4:4个并行任务。根据你的CPU核心数和网络带宽调整。我一般设为核心数的一半。--no-tags:不下载标签。能省不少时间。
如果中途断了,重新执行同样的命令就行。它会从断点继续,不会从头开始。
2.3.2 使用镜像仓库加速
如果你需要多次同步(比如团队多人开发),我建议先下载一个完整镜像,然后从镜像同步。这样第二次以后的速度会快很多。
# 第一次:下载镜像
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest --mirror
repo sync
# 第二次:从镜像创建工作目录
repo init -u /path/to/mirror/platform/manifest -b android-13.0.0_r41
repo sync
这个方法我在团队里推广过,效果很好。尤其是网络条件一般的环境,能节省大量时间。
2.4 编译目标选择(lunch)
源码下载完成后,进入编译环节。第一步是 source build/envsetup.sh,然后执行 lunch。这个命令会列出所有可用的编译目标。
对于车载系统,你通常会看到类似这样的选项:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_x86_64-eng
...
12. car_x86_64-userdebug
13. car_arm64-userdebug
这里我解释一下命名规则:设备名-编译类型。
- 设备名:比如
car_x86_64表示车载模拟器(x86_64架构),car_arm64表示真车机(ARM64架构)。 - 编译类型:
eng:工程版,带调试工具,适合开发。userdebug:用户调试版,有root权限,适合测试。user:用户版,无root,适合发布。
我个人建议,刚开始编译时选 car_x86_64-userdebug。为什么?因为模拟器启动快,调试方便。等你把流程跑通了,再切到真机目标。我在项目中第一次编译就选了真机目标,结果因为驱动没配好,编译出来的镜像刷进去黑屏,排查了很久才发现是lunch选错了。
source build/envsetup.sh
lunch car_x86_64-userdebug
2.5 首次编译避坑指南
好,终于到编译这一步了。执行 make -j8 或 m(如果已经source了envsetup.sh)。但别急着敲回车,先看看下面这些坑,我当年都踩过。
2.5.1 内存不足导致编译中断
编译AOSP非常吃内存。如果你只有8GB内存,建议加上 make -j4 而不是 -j8。我曾经在16GB的机器上开 -j16,结果系统直接OOM(内存溢出),编译进程被内核杀死。嗯,从那以后我学乖了,老老实实按内存大小来算并行数。
一个简单的经验公式:并行数 = 内存大小(GB) / 4。比如16GB内存,用 -j4 比较稳妥。
2.5.2 磁盘空间不足
编译过程中会产生大量中间文件。源码+编译产物,轻松超过100GB。我建议预留 200GB以上 的空间。如果你用SSD,注意别把根目录塞满,否则系统会变得非常卡顿。
检查磁盘空间的命令:
df -h
如果空间不够,可以设置 OUT_DIR 环境变量,把编译输出放到另一个分区:
export OUT_DIR=/path/to/large/disk/out
make -j4
2.5.3 Java版本不匹配
AOSP不同版本对Java版本有要求。Android 13需要OpenJDK 11,Android 12需要OpenJDK 9。如果你装错了版本,编译到一半会报类似 Unsupported class file major version 的错误。
检查Java版本:
java -version
如果版本不对,用 update-alternatives 切换:
sudo update-alternatives --config java
2.5.4 编译过程中的常见错误
这里列几个我遇到过的典型错误和解决方法:
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
ninja: build stopped: subcommand failed. |
某个模块编译失败 | 查看具体错误日志,通常是缺少依赖或语法错误 |
Out of memory: Killed process |
内存不足 | 减少并行数,或增加swap空间 |
No rule to make target |
缺少某个库或头文件 | 检查是否安装了所有依赖包 |
FAILED: setup-jack-server |
Jack服务器问题(老版本AOSP) | 设置 export ANDROID_JACK_VM_ARGS="-Xmx4g" |
2.5.5 首次编译成功后的验证
编译成功后,你会看到类似这样的输出:
#### build completed successfully (01:23:45) ####
这时候别急着庆祝。先验证一下编译产物是否完整。对于车载模拟器目标,产物在 out/target/product/car_x86_64/ 目录下。关键文件包括:
system.img:系统镜像vendor.img:厂商镜像ramdisk.img:内存盘镜像kernel:内核文件
你可以用模拟器启动测试:
emulator -show-kernel -memory 2048
如果模拟器能正常启动并进入桌面,恭喜你,环境搭建成功了!
好了,这一章的内容就到这里。环境搭建是基础中的基础,但也是最重要的。把这一步走稳了,后面的定制开发才能顺利进行。下一章,我们开始真正动手,修改车载系统的核心服务。