1. 概述
1.1 什么是 Android.bp
Android.bp 是 Android 操作系统源码编译系统中使用的配置文件 。它的名字是 "Blueprint" 的缩写。你可以把它理解为一个模块的"建造说明书"。它用一种简洁的格式,清晰地描述了一个模块(比如一个 C++ 库、一个 Java 库、一个 APK 等)的源代码在哪里、它叫什么名字、它依赖哪些其他模块,以及如何被编译。
1.2 设计目标
- 简单性: 使用声明式语法,避免复杂的条件判断
- 性能: 并行处理,增量构建
- 可维护性: 清晰的模块依赖关系
- 可扩展性: 支持自定义模块类型
2. 基本语法
2.1 文件结构
bash
# 注释以 # 开头
module_type {
name: "module_name",
property1: "value1",
property2: ["value2", "value3"],
property3: true,
}
2.2 基本规则
- 使用 JSON-like 语法,但末尾不需要逗号
- 字符串使用双引号
- 布尔值:true/false
- 列表:["item1", "item2"]
- 每行一个属性,缩进使用 4 个空格
3. 常用模块类型
3.1 Java 库模块
bash
java_library {
name: "my-java-lib",
srcs: [
"src/**/*.java",
"src/*.java",
],
resource_dirs: ["res"],
static_libs: [
"dependency-lib1",
"dependency-lib2",
],
sdk_version: "current",
installable: false, # 不生成 APK
}
3.2 Android 应用模块
bash
android_app {
name: "MyApp",
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
manifest: "AndroidManifest.xml",
static_libs: [
"androidx.appcompat_appcompat",
"my-java-lib",
],
certificate: "platform", # 系统签名
privileged: true, # 特权应用
platform_apis: true, # 使用平台 API
}
3.3 原生代码模块
bash
# C/C++ 静态库
cc_library_static {
name: "my-static-lib",
srcs: ["src/**/*.cpp"],
cflags: ["-Wall", "-Werror"],
include_dirs: ["include"],
export_include_dirs: ["include"],
}
# C/C++ 动态库
cc_library_shared {
name: "my-shared-lib",
srcs: ["src/**/*.cpp"],
shared_libs: ["liblog"],
}
# 可执行文件
cc_binary {
name: "my-executable",
srcs: ["src/main.cpp"],
shared_libs: [
"liblog",
"libcutils",
],
}
3.4 预编译模块
bash
# 预编译静态库
cc_prebuilt_library_static {
name: "prebuilt-static",
srcs: ["libs/libprebuilt.a"],
export_include_dirs: ["include"],
}
# 预编译动态库
cc_prebuilt_library_shared {
name: "prebuilt-shared",
srcs: ["libs/libprebuilt.so"],
}
# 预编译可执行文件
cc_prebuilt_binary {
name: "prebuilt-binary",
srcs: ["bin/tool"],
}
4. 核心属性详解
4.1 通用属性
bash
module_type {
name: "string", # 模块名称(必需)
enabled: bool, # 是否启用构建
owner: "string", # 模块所有者
visibility: ["list"], # 可见性控制
defaults: ["list"], # 默认配置
}
4.2 源文件相关
bash
srcs: [
"file1.java",
"file2.cpp",
"dir/**/*.java", # 通配符匹配
],
exclude_srcs: ["test/**/*"], # 排除文件
4.3 依赖关系
bash
# Java 依赖
static_libs: ["lib1"], # 静态链接
libs: ["lib2"], # 动态链接
# 原生代码依赖
shared_libs: ["libc", "libm"],
static_libs: ["libutils"],
whole_static_libs: ["lib"], # 完整静态链接
# 运行时依赖
required: ["module"],
data: ["file"],
4.4 编译选项
bash
# C/C++ 编译选项
cflags: ["-O2", "-g"],
cppflags: ["-std=c++17"],
ldflags: ["-Wl,--as-needed"],
# Java 编译选项
javacflags: ["-Xlint:unchecked"],
dxflags: ["--core-library"],
5. 高级特性
5.1 条件编译
bash
# 根据产品配置选择源文件
target: {
android: {
srcs: ["android_src/**/*.java"],
},
host: {
srcs: ["host_src/**/*.java"],
},
},
# 根据架构选择配置
arch: {
arm: {
srcs: ["arm_specific.cpp"],
},
x86: {
srcs: ["x86_specific.cpp"],
},
},
5.2 默认配置
bash
# 定义默认配置
defaults = ["my_defaults"]
java_defaults {
name: "my_defaults",
sdk_version: "current",
min_sdk_version: "28",
static_libs: ["androidx.appcompat_appcompat"],
}
# 使用默认配置
android_app {
name: "MyApp",
defaults: ["my_defaults"],
srcs: ["src/**/*.java"],
}
5.3 可见性控制
bash
# 模块可见性配置
visibility = [
"//frameworks/base", # 特定路径
"//vendor/xxx/packages/apps", # 供应商路径
"//packages/apps/Launcher3", # 具体模块
"@my_namespace", # 命名空间
]
# 子目录包可见性
visibility = [":__subpackages__"]
6. 实用技巧和最佳实践
6.1 文件组织
bash
project/
├── Android.bp
├── src/
│ ├── main/
│ │ ├── java/
│ │ └── cpp/
│ └── test/
├── res/
├── assets/
└── jni/
6.2 模块命名规范
bash
# 好的命名
name: "framework-base-core",
name: "vendor-mycompany-system-app",
# 避免的命名
name: "lib1", # 不明确
name: "test_module", # 不符合规范
6.3 依赖管理
bash
# 明确的依赖关系
static_libs: [
"androidx-appcompat",
"framework-protos",
],
# 避免循环依赖
# 使用 shared_libs 替代 static_libs 打破循环
6.4 性能优化
bash
# 减少不必要的依赖
static_libs: ["only-necessary-libs"],
# 使用预编译库
cc_prebuilt_library_shared {
name: "optimized-lib",
srcs: ["prebuilt/liboptimized.so"],
}
7. 调试和问题排查
7.1 常用命令
bash
# 构建特定模块
m module_name
# 显示模块依赖
m --dump-module module_name
# 构建并安装
m module_name && adb install out/.../module_name.apk
# 清理构建
m clean
7.2 常见错误
bash
# 错误:缺少必需属性
# 解决:确保 name 属性存在
# 错误:依赖找不到
# 解决:检查依赖模块名称和可见性
# 错误:语法错误
# 解决:检查逗号、引号和大括号匹配
7.3 调试技巧
bash
// 临时添加调试信息
cc_binary {
name: "debug-tool",
srcs: ["src/*.cpp"],
cflags: [
"-DDEBUG",
"-g",
"-O0", // 禁用优化以便调试
],
}
8. 实际示例
8.1 完整的应用模块
bash
android_app {
name: "SystemSettings",
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
manifest: "AndroidManifest.xml",
static_libs: [
"androidx.preference_preference",
"androidx.recyclerview_recyclerview",
"SettingsLib",
],
platform_apis: true,
certificate: "platform",
privileged: true,
optimize: {
enabled: false,
},
dex_preopt: {
enabled: true,
},
visibility: [":__subpackages__"],
}
8.2 复杂的原生模块
bash
cc_library_shared {
name: "native-service",
srcs: [
"service.cpp",
"impl/*.cpp",
],
shared_libs: [
"libbinder",
"libutils",
"liblog",
"libcutils",
],
cflags: [
"-Wall",
"-Werror",
"-Wextra",
"-DLOG_TAG=\"NativeService\"",
],
export_include_dirs: ["include"],
// 不同架构配置
target: {
android: {
enabled: true,
cflags: ["-DANDROID"],
},
},
}
9. 迁移指南(Android.mk → Android.bp)
9.1 对应关系
| Android.mk | Android.bp |
|---|---|
| LOCAL_MODULE | name |
| LOCAL_SRC_FILES | srcs |
| LOCAL_STATIC_LIBRARIES | static_libs |
| LOCAL_SHARED_LIBRARIES | shared_libs |
| LOCAL_C_INCLUDES | local_include_dirs |
9.2 迁移工具
bash
# 使用 androidmk 工具自动转换
androidmk Android.mk > Android.bp
# 手动检查和调整转换结果