最近更新了Android Nougat源码,无意间发现Android的编译系统已经发生了巨大改变,到处是“Android.bp”文件,下面就来看一下这个bp文件到底是何方神圣。
首先从Soong说起,Soong是Android中对基于GNU make的编译系统的替代物,编译文件“Android.mk”被替换为“Android.bp”。bp文件的目的就是一切从简,格式类似于JSON,像mk文件的条件控制语句等这些复杂的东西都由Go来处理,bp文件是由Go语言来解析的,为“blueprint”框架,随后转为Ninja文件,这大概就是Google的Go兴起后转而使用Go来重构自己的编译系统。bp文件的语法、语义同Bazel,如下网址是Bazel的参考文档:
https://bazel.build/versions/master/docs/be/overview.html
Bazel是Google开源的自动化构建工具,意在替换复杂、臃肿的Makefile,这里不做详细介绍。下面介绍bp文件的常用规则。
定义一个模块从模块的类型开始,模块有不同的类型,如下例子中的“cc_binary”,模块包含一些属性,格式为“property-name: property-value”,其中name属性必须指定,其属性值必须是全局唯一的。
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
默认模块“cc_defaults”的用法如下(效果同上面的例子):
cc_defaults {
name: "gzip_defaults",
shared_libs: ["libz"],
stl: "none",
}
cc_binary {
name: "gzip",
defaults: ["gzip_defaults"],
srcs: ["src/test/minigzip.c"],
}
变量赋值使用“=”或“+=”,有其作用域,例子如下。
gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
name: "gzip",
srcs: gzip_srcs,
shared_libs: ["libz"],
stl: "none",
}
注释包括单行注释和多行注释,例子如下。
// single-line comment
/*
* multi-line comment
*/
变量和属性都有类型,变量的类型在其第一次赋值时而定,属性的类型由其模块类型而定,具体支持以下几种类型。
Bool类型:true
或false
String类型:"string"
字符串列表类型:["string1", "string2"]
Map类型:{key1: "value1", key2: "value2"}
String类型、字符串列表类型和Map类型支持操作符“+”。
bpfmt是一个bp文件的格式控制工具,包括4个空格的缩进、列表有多个元素时每个元素一行、列表和map的最后一个元素多一个冗余的逗号等等,如下例子用于递归格式化当前目录下的所有bp文件
bpfmt -w .
androidmk Android.mk > Android.bp
androidmk工具可以把mk文件转换为bp文件,但一些发杂的用法和自定义的规则需要手动转换。