第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上折腾过,有些依赖包版本太老,得手动编译,太痛苦了。
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
这个脚本会加载一堆函数,比如lunch、m、mm、mmm等。说白了就是帮你把编译工具链和路径配好。
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- 内核启动ramdiskuserdata.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 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的系统架构,那才是真正有意思的部分。