第2章 开发环境准备:AOSP源码下载、编译环境搭建、模拟器与真机调试配置
2.1 环境准备概述
Framework 层自定义 Service 的开发无法脱离完整的 AOSP 编译环境。本章从零搭建一套可反复使用的构建与调试基础设施。整个流程分为三条主线:源码下载(获得原始代码树)、编译环境构建(安装工具链、配置构建参数)、目标运行环境(模拟器与真机)。下图展示总体工作流。
2.2 硬件与软件前提
编译 AOSP 对机器资源要求较高。下表列出推荐的最低与建议配置。
| 项目 | 最低要求 | 建议配置 |
|---|---|---|
| CPU | 4 核 x86_64 | 8 核或更多 |
| 内存 | 8 GB | 16 GB 或更大 |
| 磁盘剩余空间 | 100 GB(源码 + 编译) | 300 GB 以上(SSD) |
| 操作系统 | Ubuntu 18.04+ / macOS 12+ | Ubuntu 22.04 LTS |
| 文件系统 | 大小写敏感(Linux 默认满足,macOS 需创建大小写敏感卷) | 大小写敏感 + 开启 casefold |
| Python | 3.8+ | 3.11 |
| Git | 2.25+ | 2.40+ |
| JDK | 11(aliyun 镜像或 OpenJDK) | 17(Unbundled 模块需要) |
大小写敏感文件系统:AOSP 构建系统依赖文件名大小写差异(例如
Readme.txt 与 readme.txt)。macOS 默认是大小写不敏感,必须新建一个大小写敏感的磁盘映像(Disk Utility → APFS Case-sensitive)并在其内操作。2.3 AOSP 源码下载
2.3.1 安装 Repo 工具
Google 使用 repo 管理 AOSP 的数百个 Git 仓库。安装方法如下:
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=$PATH:~/bin
2.3.2 同步源码
创建专用目录并初始化 manifest。以 android-14.0.0_r15 标签为例:
mkdir ~/aosp && cd ~/aosp
repo init -u https://android.googlesource.com/platform/manifest \
-b android-14.0.0_r15
repo sync -c -j8
-c只下载当前分支(节省带宽)。-j8并行拉取任务数,可依据 CPU 核心数调整。- 国内用户可替换仓库地址为清华源或中科大源:将
https://android.googlesource.com换为https://mirrors.tuna.tsinghua.edu.cn/git/AOSP。
2.3.3 常见问题
网络中断:若同步中途断连,重新执行
repo sync 会断点续传,但可能因 GIT 对象损坏报错。此时先执行 repo sync --no-repo-verify -l 锁定当前已下载的仓库,再逐仓库修复。# 查看 manifest 分支
repo info -o | grep -E "Manifest branch"
# 切换分支(谨慎操作,会丢弃未提交修改)
repo init -b android-13.0.0_r30
repo sync -c -j8
2.4 编译环境搭建
2.4.1 安装系统依赖(Ubuntu 22.04)
sudo apt update
sudo apt install git-core gnupg flex bison build-essential zip curl zlib1g-dev \
libc6-dev-i386 libncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev \
libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3 python3-pip \
openjdk-11-jdk
不同 Android 版本依赖略有差异,具体查阅 source.android.com/setup/build/initializing。
2.4.2 初始化构建环境
每次打开新终端都要执行以下命令设置环境变量与函数。
cd ~/aosp
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
lunch会加载对应产品的BoardConfig.mk、product.mk等。userdebug版本保留 Root 与调试权限,适合 Framework 开发。
常用 target 速查:
| lunch 名称 | 说明 |
|---|---|
aosp_cf_x86_64_phone-userdebug | Cuttlefish 模拟器(x86_64) |
aosp_pixel6-userdebug | Pixel 6 真机 |
aosp_oriole-userdebug | Pixel 6(代号 oriole) |
sdk_phone_x86_64-userdebug | 低配 emulator(不支持一些硬件加速) |
2.4.3 执行编译
m -j$(nproc) 2>&1 | tee build.log
m是 AOSP 封装的make命令,自动定位build/make。$(nproc)获取 CPU 核心数。- 使用
ccache加速重复编译:export USE_CCACHE=1 && ccache -M 50G。
增量编译:首次全编译需要 2–3 小时。后续修改 Framework 代码后,只需运行
m 或 mm(在模块目录下),会触发依赖重建,通常 1–3 分钟完成。2.5 模拟器调试配置
2.5.1 编译模拟器系统镜像
确保已经 lunch aosp_cf_x86_64_phone-userdebug 并执行 m 成功。模拟器镜像在 out/target/product/vsoc_x86_64/ 目录下。
2.5.2 启动 Cuttlefish 模拟器
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-userdebug
cvd start --daemon
如果使用传统 emulator(非 Cuttlefish),需先编译 sdk_phone_x86_64 target,然后运行:
emulator -writable-system -no-snapshot -show-kernel
2.5.3 连接 ADB 与查看日志
adb devices # 确认设备在线
adb root # 获得 root shell
adb logcat -v threadtime *:V # 输出所有日志
adb logcat -s "MyService" # 过滤指定 Tag
2.6 真机调试配置
2.6.1 解锁 Bootloader
各厂商解锁方式不同,Pixel 设备步骤:
# 开启开发者选项 → OEM 解锁 → 启用 USB 调试
adb reboot bootloader
fastboot flashing unlock
# 按音量键选择 Unlock the bootloader,按电源键确认
fastboot reboot
2.6.2 刷入自定义镜像
编译产出在 out/target/product/<device>/ 下,常用命令:
fastboot flash boot out/target/product/oriole/boot.img
fastboot flash system out/target/product/oriole/system.img
fastboot flash vendor out/target/product/oriole/vendor.img
fastboot reboot
刷机风险:确保当前系统与编译目标完全匹配(同一 Android 版本和 kernel 分支)。刷错镜像可能导致变砖,需提前备份
/data 分区。2.6.3 启用 Root 调试
adb root # 若失败,尝试 adb shell 后执行 su
adb remount # 将 system 分区重新挂载为可写(仅 userdebug 或 eng 版本)
2.7 调试要点与日志
- 日志级别:Framework Service 常使用
Log.d/Log.i/Log.e。过滤 Tag 为服务类名。 - 断点调试:修改代码后执行
m services(只编译 Services 模块),然后adb sync或重新刷入system.img。 - 堆栈抓取:
adb shell dumpsys activity services查看所有运行中的 Service。 - GDB/LLDB:需要编译带有 debug 符号的版本(
eng版本默认包含)。在模拟器中可通过gdbclient脚本附加到进程。
2.8 常见错误与解决方案
| 错误现象 | 原因 | 解决 |
|---|---|---|
fatal: unable to access '...' | 网络不通或 DNS 异常 | 换国内镜像源;配置 git config --global http.proxy |
Out of memory: Killed process | 物理内存不足,内核 OOM Killer | 减少 -j 并发数,增大 Swap,或使用 m -j4 |
Jack server not running(老版本) | Jack 编译服务未启动 | 升级 Android 版本至 9.0+(改用 Jack 后的 Soong) |
Cannot find module with tag 'something' | lunch target 不对应或 product 配置缺失 | 检查 device/ 和 product/ 目录;重新 lunch 正确 target |
emulator: ERROR: x86 emulation currently requires hardware acceleration! | 未安装 KVM(Linux)或 HAXM(macOS/Windows) | sudo apt install qemu-kvm;macOS 安装 Intel HAXM |
fastboot: error: cannot load 'boot.img' | 镜像路径错误 | 确认 lunch target 后进入 out/target/product/<device>/ 检查文件 |
2.9 性能与稳定性优化
- ccache:设置缓存上限,推荐 50 GB:
ccache -M 50G。第二次全编译可减少 40% 以上时间。 - ninja 并行度:通过
m -jN避免系统过载。若使用ninja直接调用,可设置SNIPPET_NINJA_JOBS=8。 - 使用 RAM 盘:将编译中间产物放到 tmpfs(内存盘),大幅降低 I/O 延迟。示例:
sudo mkdir /mnt/rambuild
sudo mount -t tmpfs -o size=64G,mode=0755 tmpfs /mnt/rambuild
mkdir -p /mnt/rambuild/out
ln -sf /mnt/rambuild/out ~/aosp/out # 符号链接替换 out 目录
- 增量编译习惯:只修改 Framework 层代码时使用
m services或m frameworks/base,避免全量make。 - 清理 stale 产物:若出现诡异编译错误,执行
make clean或rm -rf out后再全量编译。