
1. AOSP编译环境搭建的血泪史第一次接触AOSP编译是在2016年当时为了给老旧的Nexus 5定制ROM我在Ubuntu 14.04上折腾了整整三天。现在回想起来那些看似简单的环境准备步骤里藏着无数暗坑。先说最基础的——磁盘空间官方文档说至少150GB但实际编译完Android 13的完整镜像后我的500GB SSD直接被吃掉370GB。这还没算上ccache缓存如果你打算长期做编译开发建议直接上1TB NVMe。重要提示永远不要在Windows的WSL里编译AOSP我见过至少五个同事因为文件系统性能问题导致编译失败NTFS的权限问题更是灾难性的。Java版本是另一个深坑。Android 7.0需要OpenJDK 8Android 8.0-9.0需要OpenJDK 910.0之后又换回OpenJDK 8。去年编译Android 12时我因为没注意文档里的小字说明用了默认的OpenJDK 11结果在编译art模块时遇到诡异的字节码错误。正确的做法是用sudo update-alternatives --config java切换版本后一定要执行make clobber清理之前的编译产物。2. 源码下载的玄学问题repo sync命令看起来简单但在国内网络环境下简直是噩梦。最稳的方案是repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest --depth1 repo sync -j4 --no-tags --no-clone-bundle这个组合拳里--depth1只拉取最新commit节省40%下载量-j4控制并发数避免被封IP清华镜像源比谷歌官方源快20倍不止但即使这样我还是遇到过几次.git目录损坏的情况。后来发现是SSD写入量过大导致的现在我会先在机械硬盘上完成初始同步再用rsync迁移到SSDrsync -av --delete ~/aosp-source/ /mnt/ssd/aosp/3. lunch菜单的隐藏关卡执行lunch时新手常犯的错误是直接选aosp_arm-eng。其实这里面有讲究userdebug版本比eng更接近出厂状态且能adb root带_car后缀的是车载系统专用配置aosp_x86_64比arm版本编译快3倍适合快速验证去年给Pixel 3编译时我发现官方文档里没有列出blueline-userdebugPixel 3代号最后是在device/google/crosshatch目录下找到的device配置。这里有个技巧先git grep PRODUCT_NAME -w device/查找设备代号再去看对应目录下的AndroidProducts.mk文件。4. make过程中的性能调优我的主力编译机是AMD Ryzen 9 5950X 64GB内存经过多次测试得出这些经验值export USE_CCACHE1 export CCACHE_EXEC/usr/bin/ccache ccache -M 50G # 不宜过大否则影响IO性能 make -j32 # 核心数×1.5是最佳值但要注意首次编译绝对不要加-j参数否则出错时日志会混乱ninja: build stopped: subcommand failed错误通常是因为内存不足此时要降低并行度遇到卡死时用Ctrl-\发送SIGQUIT比CtrlC更能保留现场信息5. 高频错误解决方案实录5.1 Java堆溢出Out of memory error: Java heap space解决方法是在prebuilts/sdk/tools/jack-admin文件中修改JACK_SERVER_VM_ARGUMENTS-Dfile.encodingUTF-8 -XX:TieredCompilation -Xmx4g然后执行./prebuilts/sdk/tools/jack-admin kill-server ./prebuilts/sdk/tools/jack-admin start-server5.2 文件权限问题error: unable to read system/sepolicy/prebuilts/api/33.0/private/property.te这通常发生在切换分支后执行repo forall -c git reset --hard HEAD repo sync -l5.3 模块编译失败ninja: error: unknown target MODULE_NAME先用m MODULE_NAME单独编译该模块如果还失败尝试export SOONG_ALLOW_MISSING_DEPENDENCIEStrue6. 增量编译的黑暗技巧开发阶段最痛苦的就是全量编译耗时这几个技巧能节省90%时间只编译特定模块mmm frameworks/base快速推送更改到设备adb sync adb shell am restart使用fastbuild目标仅Android 10make nothing BUILD_FASTtrue终极加速方案——RAM磁盘sudo mount -t tmpfs -o size100G tmpfs out/7. 自定义ROM的进阶操作当需要修改系统签名时必须同步更新四个地方的密钥build/target/product/security/下的platform、shared等密钥device/common/security/下的releasekeybootable/recovery/下的recovery密钥external/avb/下的avb密钥修改后要重新生成vbmeta.imgavbtool make_vbmeta_image --output vbmeta.img --key rsa2048.pem --algorithm SHA256_RSA20488. 调试技巧从logcat到内核崩溃查看启动阶段的隐藏日志adb logcat -b all -d | grep -E init|zygote动态调整内核日志级别echo 8 /proc/sys/kernel/printk捕获native崩溃tombstoned --max-tombstones109. 性能分析工具链生成perfetto跟踪文件adb shell perfetto --txt -c /data/misc/perfetto-configs/android_camera.pbtxt -o /data/misc/perfetto-traces/camera_trace.perfetto-trace使用simpleperf分析CPU热点simpleperf record -p $(pidof surfaceflinger) -g --duration 10内存泄漏检测MALLOC_DEBUGbacktrace adb shell setprop wrap.com.android.systemui LIBC_DEBUG_MALLOC_OPTIONSbacktrace10. 终极避坑指南遇到ninja: build stopped: subcommand failed时先看out/error.log末尾尝试make clean-[MODULE]终极方案rm -rf out/.lock网络问题导致repo sync中断while ! repo sync; do echo Retrying...; sleep 10; done磁盘空间不足的应急处理find out/ -name *.so -size 10M -delete快速清理编译产物保留ccachefind out/ -type f -exec rm {} 最后分享一个冷知识AOSP编译过程中会生成约420万个临时文件所以inode数量也要检查df -i