4. 开发环境搭建

Android Automotive 的量产集成工作,第一步不是改代码,而是把一套可复现、可增量、可回滚的构建环境搭起来。AOSP 源码体量巨大(完整同步后通常 200GB 以上,含 .repo 与 out 目录可达 400GB),Repo 管理着数百个 Git 仓库,编译一次全量镜像在 32 核机器上也要 1~3 小时。环境搭建的质量,直接决定了后续集成、调试与出包的效率。

一、核心原理:Repo 是 AOSP 的“多仓编排层”

AOSP 并不是一个 Git 仓库,而是由 repo 工具基于一份 manifest(清单)文件编排的数百个 Git 仓库集合。manifest 用 XML 描述每个仓库的 name、path、revision,并支持 remote、default、project、include 等标签。执行 repo init 时,repo 会把 manifest 仓库克隆到 .repo/manifests,再按清单把各子仓库同步到工作区。

理解这一点非常关键:切换 Android 版本、切换芯片厂商 BSP、切换项目分支,本质都是切换 manifest 分支或替换 manifest 文件,而不是在单个仓库里 checkout。量产项目通常使用芯片厂商(Qualcomm、MTK、NXP 等)提供的 manifest,叠加车厂自己的 local_manifest.xml 做增量覆盖。

AOSP 环境搭建与构建链路 ① 主机环境 Ubuntu 20.04/22.04 LTS ≥ 32 核 / 64GB 内存 SSD ≥ 1TB(ext4) openjdk-11-jdk python3 / git / curl adb / fastboot / ccache USB 权限 udev 规则 ② Repo 同步 repo init -u <manifest> -b <branch> -m <xml> repo sync -c -j8 --no-tags --force-sync local_manifest 增量覆盖 repo manifest -r 锁定版本 repo forall -c 批量操作 ③ 编译配置 source build/envsetup.sh lunch <product>-<variant> make -j32 / m export USE_CCACHE=1 ccache -M 100G out/target/product/<dev> img / super.img / ota ④ 模拟器调试环境 emulator -avd <name> -writable-system sdkmanager / avdmanager 管理镜像 adb root && adb remount adb push 替换 APK / 配置 logcat / dumpsys car_service 适合 UI 与 CarService 快速验证 ⑤ 真车 / 开发板调试环境 fastboot flashall -w 刷机 adb over USB / Wi-Fi(tcpip 5555) CAN / LIN 总线抓包(candump) Vehicle HAL 属性读写验证 串口 console + dmesg 内核日志 整车电源、点火、休眠唤醒测试

二、方法流程:从零到可编译镜像

  1. 安装依赖与 repo 工具:安装 git-core gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig,再把 repo 放到 ~/bin 并加入 PATH。
  2. 初始化 manifest:使用芯片厂商或车厂提供的 manifest 地址与分支。
  3. 同步源码:首次同步建议 -c 只拉当前分支,-j 并发数不超过 CPU 核数,避免磁盘 IO 打满。
  4. 配置编译环境:source build/envsetup.sh 后 lunch 选择目标产品与变体(userdebug 用于调试,user 用于量产)。
  5. 编译与产物确认:m -j32 或 make -j32,产物在 out/target/product/<device>/。
  6. 刷机与调试:模拟器用 emulator,真车/开发板用 fastboot flashall -w。
# 1. 初始化并同步
mkdir -p ~/aosp && cd ~/aosp
repo init -u https://example.com/manifest.git -b auto-r0 -m auto.xml
repo sync -c -j8 --no-tags --force-sync

# 2. 增量覆盖车厂仓库
mkdir -p .repo/local_manifests
cat > .repo/local_manifests/car.xml <<'EOF'
<manifest>
  <project name="vendor/car/apps" path="vendor/car/apps" revision="main"/>
</manifest>
EOF
repo sync -c -j8

# 3. 编译
source build/envsetup.sh
lunch auto_car-userdebug
export USE_CCACHE=1
ccache -M 100G
m -j32

# 4. 刷机
adb reboot bootloader
fastboot flashall -w

三、案例场景:一次典型的“同步失败”排查

某项目在 repo sync 时反复报 error: Cannot checkout ... : ManifestInvalidRevisionError。排查路径是:先看 repo manifest -r 输出的锁定版本,确认 revision 是否指向了不存在的 tag;再检查 local_manifests 是否覆盖了同名 project 导致 revision 冲突;最后确认 manifest 仓库分支是否被上游 force push。解决方式是删除冲突的 local manifest 条目,或把 revision 改为明确的 commit hash。这类问题在量产分支合并期非常常见。

建议在首次同步成功后立即执行 repo manifest -r -o manifest-lock.xml,把每个仓库的 commit 固化下来。后续任何一次构建都可以用这份锁定清单复现,避免“昨天能编、今天编不过”。

四、误区与复盘

常见误区后果正确做法
用 NTFS/网络盘存放源码权限、大小写、软链接异常,编译随机失败使用本地 ext4 SSD
repo sync 不加 -c拉取全部分支,磁盘与时间翻倍加 -c 只同步当前分支
不设 ccache 直接全量编译每次 1~3 小时,迭代极慢开启 ccache 并设置 100G 上限
userdebug 镜像直接当量产包含 root、调试接口,安全不合规量产用 user 变体并签名
只依赖模拟器验证Vehicle HAL、CAN、电源行为无法覆盖模拟器做 UI 验证,真车做系统验证
真车调试前务必确认整车处于安全状态:车辆驻车、手刹拉起、12V 电源稳定。刷写 super.img 或 boot.img 失败可能导致车机无法启动,量产阶段应保留可回滚的出厂镜像与恢复流程。

环境搭建完成后,建议做一次“端到端冒烟”:从干净目录 repo init 到 fastboot flashall 完整跑一遍,记录耗时与产物校验值。这套流程一旦固化,后续所有集成工作都建立在可复现的基线之上,这才是量产工程真正需要的开发环境。