第2章 开发环境搭建:AOSP源码下载、编译环境配置、模拟器与真机调试环境搭建

说实话,搭建Android Automotive的开发环境,是我当年入行时踩坑最多的环节。那时候我刚从嵌入式Linux转过来,以为不就是个编译环境嘛,结果被AOSP的源码体积和编译依赖狠狠教育了一顿。今天我把这些经验掰开揉碎了讲给你听,希望能帮你少走弯路。

2.1 硬件与操作系统选型

先聊聊硬件。AOSP编译对机器要求不低,我个人的建议是:

  • CPU:至少8核,16核以上更佳。编译时能开满线程,时间能省一半。
  • 内存:32GB起步,64GB是舒适区。我试过16GB机器编译Android 13,swap疯狂读写,最后直接卡死。
  • 磁盘:SSD是必须的,NVMe最好。源码加编译产物轻松超过200GB,建议准备500GB以上空间。
  • 操作系统:Ubuntu 20.04 LTS 或 22.04 LTS。我曾在Ubuntu 18.04上折腾过,有些依赖包版本太老,得手动编译,太痛苦了。
注意:千万别用Windows或macOS直接编译AOSP。虽然可以搞虚拟机或Docker,但性能损失很大。我见过有人用MacBook Pro M1跑AOSP,编译一次要6小时……嗯,还是老老实实用Linux吧。

2.2 AOSP源码下载

源码下载是第一步,也是最容易出幺蛾子的地方。AOSP用的是repo工具来管理多个Git仓库,说白了就是Google帮你封装了一层git操作。

2.2.1 安装repo工具

# 创建bin目录并加入PATH
mkdir -p ~/bin
export PATH=~/bin:$PATH

# 下载repo工具
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

这里有个坑:repo脚本会从Google服务器拉取最新版本。如果你在墙内,记得设置代理或者用国内镜像。我曾经因为没配代理,卡在「Downloading Repo source from googleapis.com」这一步整整一下午。

2.2.2 初始化并同步源码

以Android 13 (T) 的Automotive分支为例:

# 创建工作目录
mkdir android-13-automotive
cd android-13-automotive

# 初始化repo,指定manifest分支
repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r30

# 同步源码(这一步最耗时)
repo sync -j8 -c --no-tags

说说参数:-j8表示8个线程并行下载,你可以根据CPU核心数调整。-c只下载当前分支,--no-tags跳过标签,能省不少流量和时间。我第一次同步时没加这两个参数,结果下了80GB的tag数据,气得我直接删了重来。

小技巧:如果网络不稳定,可以分多次同步。先执行repo sync -j4,中断后重新执行,repo会自动断点续传。我经常在晚上睡觉前跑同步,第二天早上起来基本就好了。

2.3 编译环境配置

源码下完了,接下来配置编译环境。Android的编译系统基于Soong(以前是Make),依赖一堆系统库和工具链。

2.3.1 安装依赖包

Ubuntu 20.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

嗯,这里要注意:不同Android版本依赖包可能有差异。比如Android 12之后需要Python 3.8+,而Android 11及以前还需要Python 2.7。我建议你直接看源码里的build/soong/cc/config/global.go,里面有详细的依赖检查逻辑。

2.3.2 配置Java环境

Android 13要求OpenJDK 11。我习惯用update-alternatives管理多个Java版本:

sudo apt-get install openjdk-11-jdk
sudo update-alternatives --config java

验证一下:java -version,输出应该是OpenJDK 11。我之前有一次忘了切版本,用Java 8编译Android 13,编译到一半报错,排查了半小时才发现是Java版本不对。

2.3.3 初始化编译环境

每次打开新终端,都要先执行:

source build/envsetup.sh

这个脚本会加载一堆函数,比如lunchmmmmmm等。说白了就是帮你把编译工具链和路径配好。

2.4 编译Automotive系统镜像

环境配好了,开始编译。Automotive有专门的product配置:

# 选择编译目标
lunch aosp_car_x86_64-userdebug

# 开始编译(-j后面跟CPU核心数的2倍)
make -j16

这里解释一下lunch的参数:aosp_car_x86_64是Automotive的x86_64模拟器版本,userdebug表示带root权限的调试版本。如果你要编译真机镜像,比如针对某个硬件平台,需要选对应的device配置。

第一次编译时间很长,我16核的机器大概需要2小时。编译完成后,镜像文件在out/target/product/generic_x86_64/目录下。

核心文件:
  • system.img - 系统分区镜像
  • vendor.img - 厂商分区镜像
  • ramdisk.img - 内核启动ramdisk
  • userdata.img - 用户数据分区

2.5 模拟器调试环境搭建

编译完镜像,用模拟器跑起来看看效果。Android Automotive的模拟器跟手机版不太一样,它模拟的是车载中控屏幕。

# 启动模拟器
emulator -avd AutomotiveAVD -wipe-data -no-snapshot -gpu host

参数说明:-wipe-data清除用户数据,-no-snapshot禁用快照加速,-gpu host使用宿主机GPU加速。我第一次跑模拟器时没加-gpu host,结果界面卡成PPT,后来才发现是软件渲染的问题。

如果你没有预先创建AVD,可以用emulator -list-avds查看已有的,或者通过Android Studio的AVD Manager创建。我个人习惯直接用命令行创建:

# 创建Automotive AVD
avdmanager create avd -n AutomotiveAVD -k "system-images;android-33;google_apis;x86_64" -d "automotive_1024p_landscape"

2.6 真机调试环境搭建

模拟器终究是模拟器,很多车载硬件特性(比如CAN总线、GPS、车载以太网)模拟不了。真机调试才是常态。

2.6.1 刷机准备

以某款基于高通SA8155的开发板为例:

# 进入fastboot模式
adb reboot bootloader

# 刷入编译好的镜像
fastboot flash system system.img
fastboot flash vendor vendor.img
fastboot flash boot boot.img
fastboot reboot

这里有个关键点:不同硬件平台的刷机方式差异很大。有的需要烧录工具(比如QFil),有的直接fastboot就行。我建议你拿到开发板后,先找供应商要一份刷机指南,别自己瞎试——我曾经把一块开发板刷成砖,折腾了两天才救回来。

2.6.2 ADB调试与日志抓取

刷完机,用adb连接:

# 查看设备是否识别
adb devices

# 抓取系统日志
adb logcat -b all > logcat.txt

# 抓取内核日志
adb shell dmesg > dmesg.txt

# 抓取ANR/tombstone信息
adb shell ls /data/tombstones/

调试车载系统时,我经常用adb shell dumpsys来查看系统服务状态。比如检查车载网络服务:

adb shell dumpsys car_network_service
调试技巧:真机调试时,建议开启adb over TCP/IP,这样不用一直插着USB线。执行adb tcpip 5555,然后adb connect <设备IP>:5555。我在调试车载中控时,经常把开发板固定在测试台架上,用无线adb远程操作,方便多了。

2.7 常见问题与避坑指南

最后,分享几个我实际项目中遇到的坑:

  • 磁盘空间不足:编译过程中out/目录会膨胀到100GB以上。我建议用df -h定期检查,或者挂载一个独立的大分区给out/
  • 编译报错:缺少xxx库:别慌,先看错误日志。大部分情况是依赖包没装全,对照build/soong/cc/config/global.go里的检查列表补装就行。
  • 模拟器启动黑屏:检查GPU加速是否开启,或者试试-no-window参数。我遇到过是因为显卡驱动太老,升级后就好了。
  • 真机adb连不上:先确认USB调试已开启,再检查驱动。Linux下通常不需要额外驱动,Windows需要安装Google USB Driver。

嗯,环境搭建这部分就讲到这里。说白了,这步就是个体力活,但基础打好了,后面移植和优化才能顺风顺水。下一章我们聊聊Android Automotive的系统架构,那才是真正有意思的部分。