一、AOSP 编译系统的作用
AOSP 编译系统的目标是:
- 把 Android 源码(C/C++/Java/资源文件)编译/打包成可运行的 Android 系统镜像(boot.img、system.img、vendor.img 等)。
- 提供模块化的编译机制,支持单独构建某个模块(
mmm
/mmma
),而不用全编。
二、编译系统核心组件
1. Make + Soong + Ninja
- 早期的 AOSP(Android 7 以前):主要依赖 GNU Make,模块描述文件是
Android.mk
。 - Android 7+ 引入 Soong:
- 使用
Android.bp
(类似 JSON/Blueprint 格式)来描述模块。 - Soong 负责解析
Android.bp
,生成 Ninja 构建文件。 - Ninja 作为底层编译执行器,速度快、并行能力强。
- 使用
- 目前(Android 11+):核心以 Soong+Ninja 为主,仍兼容部分
Android.mk
。
2. 环境脚本
build/envsetup.sh
提供了一些 shell function(如lunch
,mmm
,mm
,croot
),本质上是构建环境的入口。lunch
指定编译目标设备和构建类型,例如:lunch aosp_x86_64-eng
这里
aosp_x86_64
是设备/平台,eng
是构建类型。构建类型:
eng
:工程开发版,几乎没有限制,带调试工具,默认生成调试符号。userdebug
:接近实际发布版,但有 root 和调试开关。user
:正式用户版,去掉 root、调试符号、严格安全限制。
3. 常用命令
make -jN
完整编译整个系统,生成所有镜像。mmm path/to/module
单独编译某个模块,结果会放到out/...
。mm
在当前目录编译模块。m
等同于在顶层执行make
。
三、模块化描述方式
1. Android.mk (Makefile 风格)
例子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libfoo
LOCAL_SRC_FILES := foo.c
LOCAL_CFLAGS := -g
include $(BUILD_SHARED_LIBRARY)
2. Android.bp (Soong/Blueprint 风格)
例子:
cc_library {
name: "libfoo",
srcs: ["foo.c"],
cflags: ["-g"],
}
- Soong 会把
.bp
文件解析成.ninja
,交给 Ninja 编译。
四、编译输出目录
所有产物都放在 out/target/product/<device_name>/
下,例如:
system.img
vendor.img
odm.img
boot.img
system/lib64/*.so
五、调试/strip 控制
默认情况下 eng 版本已经会带 -g。但是 如果模块未特别指定,build system 仍可能在安装时 strip。 为了要确保,可以在模块的 Android.mk 或 Android.bp 加强:
Android.mk 中:
# 强制带调试信息
LOCAL_CFLAGS += -g
# 禁止 strip
LOCAL_STRIP_MODULE := false
LOCAL_STRIP_MODULE := false
是关键,可以防止 build system strip 模块。
Android.bp 中的等效写法:
cc_library {
name: "test",
srcs: ["test.c"],
cflags: ["-g", "-O0",]
strip: {
none: true,
},
}
六、构建系统的演进
- Android 1.x ~ 6.x:Make-based (
Android.mk
) - Android 7.0 (Nougat):引入 Soong (
Android.bp
) - Android 9.0:更大规模迁移到 Soong
- Android 11+:几乎全部核心模块都基于 Soong,Make 仅保留兼容和某些第三方驱动/项目。
🏗 AOSP 编译系统架构图
+------------------------------------------------------------+
| AOSP Source Tree |
| (Java, C/C++, Kotlin, Resources, Android.bp/Android.mk 等) |
+----------------------------+-------------------------------+
|
v
+------------------------------------------------------------+
| build/envsetup.sh (环境配置脚本) |
| - 定义 m/mma/mmm/lunch/croot 等函数 |
| - 设置编译环境变量 |
+------------------------------------------------------------+
|
v
+------------------------------------------------------------+
| lunch <target> (<device>-eng/userdebug/user) |
| - 确定设备 (device) 与构建类型 (eng/userdebug/user) |
| - 设置相关环境 (TARGET_PRODUCT, TARGET_BUILD_VARIANT 等) |
+------------------------------------------------------------+
|
v
+----------------------------+-------------------------------+
| 模块定义层 Module definition |
|------------------------------------------------------------|
| Android.mk (Make) | Android.bp (Soong/Blueprint)|
| - LOCAL_MODULE | - cc_library, android_app |
| - LOCAL_SRC_FILES | - srcs, deps, cflags |
| - LOCAL_CFLAGS | - strip, sdk_version |
| … | … |
+----------------------------+-------------------------------+
|
v
+------------------------------------------------------------+
| Soong (用 Go 写的构建系统解析器) |
| - 读取 Android.bp |
| - (部分 Android.mk 通过 "soong.mk" 转换加入) |
| - 生成 Ninja 构建规则 (`.ninja` 文件) |
+------------------------------------------------------------+
|
v
+------------------------------------------------------------+
| Ninja (轻量高速的构建执行器) |
| - 根据 Soong 生成的 ninja.build 文件 |
| - 调用 clang/gcc/javac/aapt/aidl/protoc/dex2oat 等工具 |
+------------------------------------------------------------+
|
v
+------------------------------------------------------------+
| out/target/product/<device>/ |
| - system.img (系统分区镜像) |
| - vendor.img (厂商分区镜像) |
| - boot.img (内核+ramdisk) |
| - recovery.img (恢复模式镜像) |
| - userdata.img (数据分区) |
| - system/lib(64)/*.so (编译产出库文件) |
+------------------------------------------------------------+
✅ 总结:
AOSP 编译系统是一个 多层次的构建框架,从顶层环境配置(envsetup.sh
、lunch
),到模块定义(Android.mk
/Android.bp
),最终通过 Soong → Ninja 构建输出系统镜像。
它既要满足 完整系统构建 的需求,也支持 局部模块增量编译,因此开发效率较高。