4. 开发环境搭建
Android BSP 版本迁移的第一步,不是改代码,而是把一套可复现的构建环境搭起来。环境不稳,后续所有编译报错、镜像异常、驱动不生效都会被误判为代码问题。本节围绕源码获取、编译环境配置、repo 工具使用和常见环境问题排查四条主线,给出可直接落地的操作路径。
一、核心原理:BSP 构建环境的三层依赖
Android BSP 的构建环境可以理解为三层依赖的叠加:主机工具链层(JDK、Python、GCC、make、git、curl 等)、源码管理层(repo + manifest + 多个 git 仓库)、目标平台层(交叉编译器、BSP 私有仓库、厂商闭源包)。三层中任意一层版本错位,都会在编译阶段以“找不到符号”“无法解析依赖”“权限拒绝”等形式暴露出来。
因此环境搭建的核心原则是:版本锁定、路径隔离、可重复。不要依赖“我机器上能编过”,而要让 manifest 和脚本决定环境,而不是让开发者的个人习惯决定环境。
二、源码获取:repo init 与 sync 的正确姿势
Android 源码由数百个 git 仓库组成,必须通过 repo 工具统一管理。典型流程如下:
# 1. 安装 repo 引导脚本
mkdir -p ~/bin
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH
# 2. 初始化 manifest(以 Android 13 + 厂商 BSP 为例)
repo init -u https://git.company.com/manifest.git \
-b android-13.0.0_r1 \
-m bsp-release.xml \
--repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo
# 3. 同步源码(-j 并发数建议为 CPU 核数的 1~2 倍)
repo sync -c -j8 --no-tags --force-sync
# 4. 查看当前 manifest 与分支状态
repo manifest -r -o pinned-manifest.xml
repo info
其中 -c 表示只拉取当前分支,--no-tags 减少冗余对象,--force-sync 用于覆盖本地被修改的仓库。量产交付时,建议用 repo manifest -r 生成 pinned manifest,把每个仓库的 commit id 固定下来,作为可追溯的版本基线。
三、编译环境配置:从 envsetup 到 lunch
源码同步完成后,进入编译环境配置阶段。Android 的构建系统通过 envsetup.sh 注入大量 shell 函数,再通过 lunch 选择目标产品。
source build/envsetup.sh
lunch bsp_device-userdebug
make -j$(nproc) 2>&1 | tee build.log
常见目标组合包括 user、userdebug、eng 三种变体。量产版本通常使用 user,调试阶段使用 userdebug。若 BSP 提供 bsp_device 之外的 lunch 目标,应以厂商文档为准,不要随意套用 AOSP 默认目标。
source build/envsetup.sh 和 lunch 写入独立的 env.sh,每次编译前 source 一次,避免不同终端会话之间环境变量互相污染。
四、常见环境问题排查清单
| 现象 | 可能原因 | 排查命令 / 处理 |
|---|---|---|
| repo sync 卡住或超时 | 网络代理、镜像源不可达 | repo sync -j1 --fail-fast 定位单仓库;检查 ~/.gitconfig 代理 |
| fatal: unable to checkout working tree | 本地仓库被修改或磁盘满 | repo forall -c 'git reset --hard';df -h 检查空间 |
| Unsupported Java version | JDK 版本与分支不匹配 | Android 13 需 JDK 11;update-alternatives --config java |
| ninja: error: unknown target | lunch 目标错误或未 source | 重新 source build/envsetup.sh && lunch |
| Permission denied (publickey) | SSH key 未配置或未加入 ssh-agent | ssh-add ~/.ssh/id_rsa;ssh -T git@git.company.com |
| Out of memory during build | 并发过高或内存不足 | 降低 -j 值;建议 16GB 内存配 -j4 |
五、案例与复盘:一次典型的“编译通过但镜像异常”
某项目在迁移到 Android 13 后,本地编译成功,但刷机后无法进入系统。排查发现:开发者使用了旧版 local_manifest.xml 覆盖了 kernel 仓库,导致 kernel 与 vendor 的 DTB 不匹配。复盘结论是:local_manifest 必须纳入版本管理,并在 CI 中固定使用 pinned manifest,禁止开发者本地随意覆盖关键仓库。
综上,开发环境搭建不是一次性动作,而是版本迁移与量产交付的基线工程。把源码获取、环境配置、repo 使用和问题排查固化为脚本与清单,才能让后续的驱动适配、系统裁剪和量产验证建立在可靠基础之上。