2. 开发环境搭建:AOSP源码下载与编译、HIDL工具链安装、模拟器与真机调试环境配置
说实话,很多做HAL开发的朋友,最后卡住的地方不是代码逻辑,而是环境。我见过太多人花了两周配环境,结果编译不过,心态直接崩了。这一章,我把这些年踩过的坑、总结的经验,一次性给你讲清楚。
2.1 AOSP源码下载:别让网络成为你的瓶颈
AOSP源码有多大?完整拉下来,大概30-40GB。加上编译产物,轻松突破200GB。所以,第一件事——硬盘空间要留够。我个人习惯至少准备500GB的剩余空间。
2.1.1 环境准备
操作系统我推荐Ubuntu 18.04或20.04 LTS。为什么?因为Google官方测试最多的就是这两个版本。你非要用Arch Linux?也不是不行,但遇到问题别来找我诉苦。
硬件最低要求:
- CPU:4核以上(推荐8核)
- 内存:16GB以上(推荐32GB)
- 硬盘:500GB以上(推荐SSD)
- 网络:稳定的科学上网环境
2.1.2 下载步骤
先装必要的工具包:
sudo apt-get update
sudo apt-get install 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
然后配置Git和Repo工具:
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
接下来,选择一个分支。我个人建议用android-12.0.0_r32或android-13.0.0_r41,这两个版本HIDL支持最稳定。
mkdir aosp
cd aosp
repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r41
repo sync -j8 -c
我曾经遇到过:repo sync到一半网络断了,重新跑又得从头开始。后来我学乖了,用repo sync -j4 --fail-fast,配合--no-tags参数,能省不少时间。另外,建议用screen或tmux挂后台,别傻傻盯着终端。
2.2 AOSP编译:第一次编译,请做好心理准备
第一次编译AOSP,少则2小时,多则半天。为什么?因为要编译整个系统,包括内核、框架、应用。你想想看,几万个源文件,全量编译一次,CPU直接拉满。
2.2.1 初始化编译环境
source build/envsetup.sh
lunch aosp_x86_64-eng
这里解释一下lunch后面的参数:
| 参数 | 含义 | 适用场景 |
|---|---|---|
aosp_x86_64-eng |
x86_64模拟器,eng版本 | 模拟器调试,开发阶段 |
aosp_arm64-eng |
ARM64真机,eng版本 | 真机调试,开发阶段 |
aosp_x86_64-userdebug |
x86_64模拟器,userdebug版本 | 模拟器调试,接近发布 |
我个人习惯用eng版本开发,因为它默认开启了root和adb remount,省事。
2.2.2 开始编译
make -j$(nproc)
$(nproc)会自动获取你的CPU核心数。但注意,内存不够的话,并行太多会OOM。我建议内存32GB以下用-j4,32GB以上再用-j$(nproc)。
小技巧:编译时加上showcommands参数,能看到具体在编译哪个文件:make -j4 showcommands 2>&1 | tee build.log。这样万一编译挂了,能快速定位问题。
2.2.3 常见编译错误与解决
- Java版本不对:AOSP 12以上需要OpenJDK 11。用
update-alternatives切换。 - 内存不足:减少
-j参数,或者增加swap空间。 - 磁盘空间不足:用
make clobber清理,或者把out目录挂到单独的大分区。
我曾经遇到过:编译到99%挂了,原因是某个模块的依赖没更新。后来我养成习惯,每次修改HAL或HIDL代码后,只编译相关模块:make -j4 hidl-gen或make -j4 libhardware。全量编译只在最后集成时跑一次。
2.3 HIDL工具链安装:核心中的核心
HIDL开发离不开几个关键工具:hidl-gen、hidl2java、hidl2cpp。说白了,它们就是帮你把.hal文件翻译成C++或Java代码的翻译官。
2.3.1 工具链清单
| 工具 | 作用 | 源码位置 |
|---|---|---|
hidl-gen |
从.hal生成C++/Java代码 | system/tools/hidl/ |
hidl2java |
生成Java绑定 | system/tools/hidl2java/ |
hidl2cpp |
生成C++绑定 | system/tools/hidl2cpp/ |
hidl-impl |
生成服务端骨架代码 | system/tools/hidl-impl/ |
2.3.2 编译HIDL工具
在AOSP根目录下执行:
source build/envsetup.sh
lunch aosp_x86_64-eng
make hidl-gen hidl2java hidl2cpp hidl-impl -j4
编译完成后,工具会出现在out/host/linux-x86/bin/目录下。我建议把这个目录加到PATH里:
export PATH=$PATH:/path/to/aosp/out/host/linux-x86/bin
避坑指南:我曾经直接用了系统自带的hidl-gen,结果生成的代码接口对不上,编译报了一堆错。后来才发现,AOSP的hidl-gen版本必须和源码版本一致。所以,一定要用自己编译出来的工具。
2.3.3 验证工具是否正常
hidl-gen -L check
hidl-gen -L c++-impl -o . -r android.hardware:hardware/interfaces \
-r android.hidl:system/libhidl/transport android.hardware.light@2.0
如果能看到输出,说明工具链没问题。
2.4 模拟器与真机调试环境配置
环境搭好了,代码能编译了,接下来就是调试。调试环境分两种:模拟器和真机。我个人的经验是:前期用模拟器,后期上真机。
2.4.1 模拟器配置
编译完AOSP后,启动模拟器:
source build/envsetup.sh
lunch aosp_x86_64-eng
emulator -writable-system -show-kernel -memory 2048 -cores 4
参数说明:
-writable-system:允许修改system分区,方便push新的HAL服务-show-kernel:显示内核日志,调试驱动时很有用-memory:分配内存大小,建议2GB以上-cores:分配CPU核心数
模拟器调试流程:
- 编译HAL服务模块:
make -j4 your_hal_service - push到模拟器:
adb remount && adb push out/target/product/generic_x86_64/vendor/lib/hw/your_hal.so /vendor/lib/hw/ - 重启服务:
adb shell stop && adb shell start - 查看日志:
adb logcat -b all | grep your_hal
2.4.2 真机调试配置
真机调试比模拟器复杂一些,但更接近真实场景。你需要一台解锁了bootloader的设备,比如Pixel系列。
步骤:
- 解锁bootloader:
fastboot flashing unlock - 刷入编译好的系统:
fastboot flashall -w - 开启adb root:
adb root - 关闭SELinux(开发阶段):
adb shell setenforce 0
我曾经遇到过:真机上adb remount失败,提示remount of the / superblock failed: Permission denied。后来发现是动态分区的问题。解决办法是用adb disable-verity关闭dm-verity,然后重启再remount。记住,每次刷机后都要重新执行这一步。
2.4.3 调试工具推荐
| 工具 | 用途 | 命令示例 |
|---|---|---|
logcat |
查看系统日志 | adb logcat -b all -v threadtime |
dmesg |
查看内核日志 | adb shell dmesg -w |
lshal |
查看已注册的HAL服务 | adb shell lshal |
hwbinder |
查看binder调用 | adb shell lshal --debug |
strace |
跟踪系统调用 | adb shell strace -p [pid] |
2.5 本章知识体系总览
下面这张图,把整个开发环境搭建的流程串起来了。你跟着走,不会迷路。