Android 构建系统与增量编译
1. 概述
1.1 功能简介
本文档介绍 RK3576 平台 Android 14 SDK 的构建系统原理与增量编译方法,涵盖 Soong/Ninja 构建流程、模块化编译(mm/mmm)、增量编译技巧、编译产物管理等内容,帮助开发者在日常开发中高效构建系统镜像。
1.2 应用场景
- 修改系统应用或框架代码后进行单模块快速编译
- 只修改内核或驱动后重新打包镜像
- 理解 Android 构建系统的执行流程
- 优化编译速度与磁盘占用
1.3 前置条件
- 已完成 SDK 源码同步与编译环境初始化(详见 Android_SDK编译)
- 已确认 lunch 目标为 RK3576 对应项(以实际 SDK 为准)
2. 构建系统原理
2.1 构建工具链
RK Android 14 SDK 使用以下构建工具链:
| 工具 | 作用 |
|---|---|
| Soong | Android 新一代构建系统(替代 Make) |
| Ninja | 底层构建执行引擎 |
| Kati | 将 Make 文件转换为 Ninja 文件 |
| Blueprint | Soong 的构建文件解析器 |
| Make | 兼容传统 Android.mk 构建 |
2.2 构建流程
build.sh
→ envsetup(环境变量、lunch)
→ Soong 解析 Android.bp
→ Kati 解析 Android.mk
→ 生成 build.ninja
→ Ninja 并行执行构建任务
→ 生成各分区镜像2.3 构建文件类型
| 文件类型 | 语法 | 说明 |
|---|---|---|
Android.bp | Blueprint | 新式构建文件(推荐) |
Android.mk | Make | 传统构建文件(兼容) |
BoardConfig.mk | Make | 板级配置(分区、GKI 等) |
3. 增量编译方法
3.1 单模块编译
参考说明:以下命令基于 RK Android 通用编译流程。
# 初始化环境
cd ~/rk3576_android_sdk
source build/envsetup.sh
lunch rk3576_u-userdebug # 以实际 SDK 目标名为准
# 进入模块目录后编译单个模块
cd frameworks/base
mm
# 在任意目录编译指定模块
mmm frameworks/base3.2 编译系统应用
# 编译 Settings 应用
mmm packages/apps/Settings
# 编译 Launcher3
mmm packages/apps/Launcher3
# 编译 Camera
mmm packages/apps/Camera23.3 编译内核模块(KO)
待板上验证:RK3576 Android 默认启用 GKI,板级驱动以 KO 模块方式编译(以实际 SDK 为准)。
# 编译内核及模块
./build.sh -K
# 单独编译指定驱动模块
cd kernel
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- M=drivers/gpu/drm/rockchip3.4 重新打包镜像
# 增量编译 Android 并打包
./build.sh -A -p
# 更新 boot 分区(内核改动后)
./build.sh -K -p3.5 ccache 加速
export USE_CCACHE=1
export CCACHE_MAXSIZE=50G
ccache -M 50G
# 查看命中率
ccache -s4. 编译产物管理
4.1 产物目录
| 目录 | 说明 |
|---|---|
out/target/product/rk3576_u/ | 系统镜像中间产物 |
rockdev/Image-rk3576_u/ | 最终分区镜像 |
out/host/ | 宿主机工具 |
out/soong/ | Soong 构建缓存 |
4.2 清理操作
# 清理输出目录(全量重编)
make clean
# 清理 Soong 缓存
rm -rf out/soong
# 清理单模块产物
mm --clean4.3 构建缓存
out/目录缓存编译中间文件,不要随意删除(会导致全量重编)- 修改
BoardConfig.mk后需要清理相关缓存 - 修改
Android.bp后 Soong 会自动增量重编受影响模块
5. 常见问题
5.1 增量编译不生效
现象: 修改代码后重新编译,产物没有变化。
解决方案:
# 强制重新编译该模块
mm --force-rebuild
# 或清理模块产物
rm -rf out/target/product/rk3576_u/obj/APPS/模块名_intermediates5.2 编译报错但无明显原因
解决方案:
# 清理后重编
rm -rf out/soong
./build.sh -A
# 查看详细日志
./build.sh -A 2>&1 | tee build.log5.3 模块间依赖冲突
现象: 提示 Circular dependency 或 Missing dependency。
解决方案:
- 检查 Android.bp 中
deps/libs声明 - 确认模块名与依赖名拼写一致
- 参考同平台其他模块的依赖写法
6. 相关文档
- Android_SDK编译 — 完整编译流程
- Android系统定制 — lunch 目标与产品配置
- Android HAL开发 — 模块编译与 GKI
- 常见编译错误 — 编译问题排查
