2. Android系统编译环境搭建:Ubuntu环境配置、Repo与Git工具使用、源码下载与分支选择、编译命令与输出产物
说实话,搭建编译环境这件事,看着简单,但坑是真不少。我见过太多同事卡在这一步,折腾一两天都跑不起来。今天我就把我在几个车载项目里积累的经验,一次性说清楚。
2.1 Ubuntu 环境配置:别小看这一步
我个人的习惯是直接用 Ubuntu 20.04 LTS,64 位版本。为什么?因为 AOSP 官方对 20.04 的支持最成熟,踩过的坑最少。你想想看,要是用个太新的版本,说不定某个依赖库还没适配,折腾半天发现是系统版本的问题,多冤。
推荐配置清单:
- 系统:Ubuntu 20.04 LTS (amd64)
- 内存:至少 16GB(我建议 32GB,编译速度快很多)
- 磁盘:至少 250GB 空闲空间(源码 + 编译产物,轻松吃掉 150GB+)
- CPU:8 核以上,编译时间能缩短一半
装好系统后,第一件事就是装依赖。别偷懒,直接跑官方脚本。我在项目里见过有人手动一个个装,结果漏了某个 32 位库,编译到一半报错,白白浪费两小时。
# 安装必要工具链
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
# 安装 JDK(Android 12 以上需要 JDK 11)
sudo apt-get install -y openjdk-11-jdk
# 安装 Python(AOSP 需要 Python 3.8+)
sudo apt-get install -y python3 python3-pip
我的小技巧: 装完依赖后,跑一下 sudo apt-get build-dep 把编译基础包也装上。另外,记得把磁盘格式化成 ext4,我之前用 NTFS 踩过权限的坑。
2.2 Repo 与 Git 工具:Android 源码管理的灵魂
Repo 是什么?说白了,它就是 Google 为 AOSP 量身定做的「超级 Git 管理器」。AOSP 有几百个 Git 仓库,你不可能一个个去 clone。Repo 帮你一条命令搞定。
安装 Repo 很简单,但要注意版本。我曾经用过一个旧版 Repo,sync 的时候老是报错,后来发现是 Repo 版本太老,不兼容新的 manifest 格式。
# 安装 Repo
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
# 加到 PATH
echo 'export PATH=$PATH:~/bin' >> ~/.bashrc
source ~/.bashrc
# 验证安装
repo --version
Git 的基本操作我就不多说了,但有几个点要特别提醒:
- 分支命名规范: 我建议用
project/feature/描述的格式,比如carlink/ota/v1.0,这样一看就明白是哪个项目的什么功能。 - 提交信息: 别写「fix bug」这种废话。写清楚「修复 OTA 升级包校验失败时回滚逻辑异常」,以后你自己回头看都省心。
- cherry-pick 要谨慎: 我在一个项目里 cherry-pick 了一个提交,结果没注意依赖,导致编译失败。后来我养成了习惯:cherry-pick 后一定先编译一次再提交。
避坑指南: 我曾经在 repo sync 时网络断了,结果本地仓库状态混乱。后来我学会了用 repo sync --force-sync --no-tags,强制同步且不拉取 tag,速度快很多,也避免了 tag 冲突。
2.3 源码下载与分支选择:选对分支,少走弯路
下载 AOSP 源码,核心就两步:repo init 和 repo sync。但分支选择是个技术活。
# 初始化 repo,指定 Android 12 分支
repo init -u https://android.googlesource.com/platform/manifest -b android-12.0.0_r32
# 同步源码(-j 参数指定并行数,根据 CPU 核数调整)
repo sync -j16 -c --no-tags
分支怎么选?我一般遵循这个原则:
| 场景 | 推荐分支 | 说明 |
|---|---|---|
| 车载项目开发 | android-12.0.0_r32 或更高 | Android 12 开始,车载功能趋于稳定 |
| 学习研究 | android-13.0.0_rXX | 最新特性,但要注意厂商适配进度 |
| 厂商定制 | 厂商提供的 release 分支 | 比如高通、MTK 的 BSP 分支 |
下载时间取决于你的网速。我见过最快的,千兆光纤下 40 分钟搞定。慢的时候,一整天都下不完。建议用国内镜像,速度能快 3-5 倍。
国内镜像加速: 把 repo init 的 URL 换成 https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest,速度飞起。
2.4 编译命令与输出产物:从源码到镜像
源码下好了,终于可以编译了。Android 的编译系统经历过从 Android.mk 到 Soong(Blueprint)的演变。现在主流是用 soong,但很多老项目还在用 make。我建议新项目直接用 soong,效率高很多。
编译的基本流程:
# 1. 设置环境变量
source build/envsetup.sh
# 2. 选择编译目标
lunch aosp_car_x86_64-userdebug
# 3. 开始编译(-j 参数根据 CPU 核数调整)
make -j16 2>&1 | tee build.log
lunch 命令的选择很关键。车载系统一般用 aosp_car_x86_64-userdebug 或 aosp_car_arm64-userdebug。userdebug 版本保留了 root 权限和调试工具,适合开发阶段。
编译完成后,产物都在 out/target/product/ 目录下。以 aosp_car_x86_64 为例:
| 文件/目录 | 说明 |
|---|---|
| system.img | 系统镜像,包含 Android 框架和核心应用 |
| vendor.img | 厂商镜像,包含硬件驱动和 HAL 层 |
| boot.img | 内核和 ramdisk,启动时加载 |
| userdata.img | 用户数据分区镜像 |
| super.img | Android 10 之后的动态分区镜像,包含 system、vendor 等 |
| otapackage/ | OTA 升级包,我们做 OTA 开发最关心的目录 |
重点提醒: OTA 升级包在 out/target/product/xxx/obj/PACKAGING/target_files_intermediates/ 目录下,文件名是 xxx-target_files-eng.xxx.zip。这个 zip 包是生成 OTA 增量包的基础,千万别删。
编译过程中,我建议用 tee build.log 把日志保存下来。为什么?因为编译错误有时候一闪而过,你盯着屏幕也未必能看清。有了日志,直接搜索 error: 关键字,定位问题快得多。
避坑指南: 我曾经在编译时加了 -j32(32 个并行任务),结果内存爆了,系统直接卡死。后来我学乖了,-j 参数不要超过 CPU 核数的 1.5 倍。比如 8 核 CPU,用 -j12 最稳妥。
嗯,到这里,编译环境就搭好了。你可能会问:「第一次编译要多久?」以我的经验,8 核 CPU、32GB 内存的机器,第一次全编译大概 1.5 到 2 小时。之后增量编译就快多了,改几个文件的话,10 到 20 分钟就能搞定。
环境搭好只是第一步。接下来,我们就要真正进入 OTA 开发的实战了。记住,环境标准化了,后面才能少踩坑。