2. Android系统编译环境搭建:Ubuntu环境配置、Repo与Git工具使用、源码下载与分支选择、编译命令与输出产物

说实话,搭建编译环境这件事,看着简单,但坑是真不少。我见过太多同事卡在这一步,折腾一两天都跑不起来。今天我就把我在几个车载项目里积累的经验,一次性说清楚。

Android 编译环境搭建 · 知识体系 编译环境搭建 Ubuntu 环境配置 JDK / Python / 依赖库 磁盘分区 & 交换空间 Repo & Git 工具 Repo init / sync Git 分支管理 源码下载与分支 AOSP / 厂商分支 Tag 选择策略 编译 & 产物 lunch / make / m out/ 目录结构 核心目标:一次配好,长期复用 环境标准化 → 避免团队间「我机器能编你不能」的尴尬

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 initrepo 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-userdebugaosp_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 开发的实战了。记住,环境标准化了,后面才能少踩坑。


公众号:蓝海资料掘金营,微信 deep3321