背景
随着项目规模扩大,Makefile的复杂性和编译效率问题越来越明显,比如依赖管理混乱、并行编译效率低等。所以Google从Android7.0开始,引入Soong来对AOSP进行构建编译,而Android.bp作为Soong的配置文件,采用声明式语法,极大简化了构建逻辑。
- Android7.0 引入ninja和kati
- Android8.0使用Android.bp替换Android.mk,正式引入soong
构建系统使用Kati将Android.mk转换为ninja格式的文件,然后也通过Blueprint+ Soong将Android.bp转换为ninja格式的文件,通过androidmk将Android.mk转换成Andorid.bp。
工具介绍
Ninja
ninja是一个高效的编译框架,处理并行任务更好,一般针对nanja文件的修改是通过修改Android.bp文件来转换修改的,所以我们在实际的过程中只需要关注Android.bp即可。
Android.bp
它的推出完全可以立即成为了替换Android.mk,它最为Soong的配置文件,可以简化配置构建逻辑,因为它不存在分支、循环等流程控制语法,不需要做过多的逻辑理解和编写。
Soong
Soong可以理解为类似Makfefile一样的系统编译核心,提供Android.bp的语法解释,转换生成Ninja文件用于支持编译。 Kati kati的核心功能是将传统的Mmakefile转换为niaja构建文件,作为默认构建工具链的一部分,与mm/mmm等命令集成,支持模块快速编译。
Blueprint
Blueprint是生成、解析Android.bp的工具,属于Soong的一部分。
Android.bp语法
Android.bp语法主要包括以下几部分:
- 模块
- 变量
- 注释
- 运算符
- 条件语句
模块
Android.bp可以支持的模块有很多,比如android_app、cc_binary、cc_binary_host、java_library等等,具体的可以参考build/soong/androidmk/cmd/androidmk/android.go文件中moduleTypes的定义。
示例:
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
变量
编译文件中也是可以声明一些变量的,不过他的作用域在声明它们的文件的其余部分,以及所有子 Blueprint 文件。变量一般不可变,如果要调整可以使用+=去累加赋值,或者附加到别处,需要注意和其他编程语言一样,一定要在使用前进行操作,否则无效。
支持类型:
- 布尔(Bool)
- 整型(Int)
- 字符串(String)
- 列表(List)
- 映射(Map)
- 结构体(Struct)
示例:
gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
name: "gzip",
srcs: gzip_srcs,
shared_libs: ["libz"],
stl: "none",
}
注释
Android.bp 文件可以包含 C 样式的多行 /* */ 注释以及 C++ 样式的单行 // 注释。
运算符
可以使用 + 运算符附加字符串、字符串列表和映射。可以使用 + 运算符对整数求和。附加映射会生成两个映射中键的并集,并附加在两个映射中都存在的所有键的值。
条件语句
Soong 不支持 Android.bp 文件中的条件语句。但是,编译规则中需要条件语句的复杂问题将在 Go中处理。大多数条件语句都会转换为映射属性,其中选择了映射中的某个值并将其附加到顶级属性。 例如,要支持特定于架构的文件,请使用以下命令:
cc_library {
...
srcs: ["generic.cpp"],
arch: {
arm: {
srcs: ["arm.cpp"],
},
x86: {
srcs: ["x86.cpp"],
},
},
}
编译APK示例
android_app {
// 模块名称
name: "MyApp",
// 源代码目录(根据实际情况修改)
srcs: ["src/**/*.java"],
// 资源文件目录
resource_dirs: ["res"],
// 清单文件路径
manifest: "AndroidManifest.xml",
// 使用AndroidX库需要添加
static_libs: [
"androidx.appcompat_appcompat",
"com.google.android.material_material",
"androidx-constraintlayout_constraintlayout",
],
// 平台签名(使用系统级签名时可启用)
// privileged: true,
// 使用平台签名(系统应用)
// certificate: "platform",
// 使用testkey签名(普通应用)
certificate: "PRESIGNED",
// 优化选项(启用代码混淆)
optimize: {
enabled: true,
// 混淆配置
proguard_flags_files: ["proguard.flags"],
},
// 最低SDK版本
sdk_version: "current",
min_sdk_version: "21",
target_sdk_version: "34",
// 包含JNI库时的配置(如果有本地代码)
// jni_libs: ["mynative"],
}
// 如果需要预构建依赖(例如aar文件)
/*
android_library_import {
name: "mylibrary",
aars: ["libs/mylibrary.aar"],
static_libs: ["androidx.appcompat_appcompat"],
}
*/
至此Android.bp的基础介绍就差不多了,更多的还是要看实际的运用,一般来讲在实际研发过程中,要配置的往往不太多,或者都是逐步增配的,所以复杂度整体来讲真的不高。
愿大家的程序永无bug~
愿大家的程序永无bug~
愿大家的程序永无bug~