Android.bp入门指南之浅析Android.bp语法

前言

在前面的章节初始Android.bp里面我们对Android.bp有了一个基本的认识,知道了它是干啥的。算了吗,还是再介绍一遍它吗!Android.bp是用来替换Android.mk的配置文件,它使用Blueprint框架来解析。Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义,最终转换成Ninja文件。Android.bp文件用类似JSON的简洁声明来描述需要构建的模块。介绍了一番是不是还是有点懵逼,没有关系,在这篇文章里面,我将介绍Android.bp文件的基本语法规则,然后附上实例加以说明。

注意:关于Android.bp的权威解释可以参见 android.bp权威文档,不过是全英文的。

重要的事情说三篇,Android.mk可以引用Android.bp中的模块,反之Android.bp不能引用Android.mk中的模块。

重要的事情说三篇,Android.mk可以引用Android.bp中的模块,反之Android.bp不能引用Android.mk中的模块。

重要的事情说三篇,Android.mk可以引用Android.bp中的模块,反之Android.bp不能引用Android.mk中的模块。

一. Android.bp语法初识

Android.bp是一门实战性的东西,光说不练没有啥用,说再多不如直接开练来得舒服。那就直接开始手撕实例了,让我们开战吗!

cc_library_shared {//编译成动态库,类似于Android.mk中的BUILD_SHARED_LIBRARY

name: "libbluetooth_jni",//编译出的模块的名称,类似于Android.mk中的LOCAL_MODULE

srcs: [ //源文件,类似于Android.mk中的LOCAL_SRC_FILES

"com_android_bluetooth_btservice_AdapterService.cpp",

"com_android_bluetooth_hfp.cpp",

"com_android_bluetooth_hfpclient.cpp",

"com_android_bluetooth_a2dp.cpp",

"com_android_bluetooth_a2dp_sink.cpp",

"com_android_bluetooth_avrcp.cpp",

"com_android_bluetooth_avrcp_controller.cpp",

"com_android_bluetooth_hid.cpp",

"com_android_bluetooth_hidd.cpp",

"com_android_bluetooth_hdp.cpp",

"com_android_bluetooth_pan.cpp",

"com_android_bluetooth_gatt.cpp",

"com_android_bluetooth_sdp.cpp",

],

include_dirs: [//用户指定的头文件查找路径,类似于Android.mk中的LOCAL_C_INCLUDES

"libnativehelper/include/nativehelper",

"system/bt/types",

],

shared_libs: [//编译所依赖的动态库,类似于Android.mk中的LOCAL_SHARED_LIBRARIES

"libandroid_runtime",

"libchrome",

"libnativehelper",

"libcutils",

"libutils",

"liblog",

"libhardware",

],

static_libs: [//编译所依赖的静态库,类似于Android.mk中的LOCAL_STATIC_LIBRARIES

"libbluetooth-types",

],

cflags: [///编译flag,类似于Android.mk中的LOCAL_CFLAGS

"-Wall",

"-Wextra",

"-Wno-unused-parameter",

],

}

1.1 模块

从前面的列子可以看出定义一个模块从模块的类型开始,模块有不同的类型,如前面例子中的cc_library_shared,当然类型还有很多种,譬如cc_binary android_app cc_library_static等等。模块包含一些属性格式为“property-name:property-value”,其中name属性必须指定,其属性值必须是全局唯一的。

其中默认模块可用于在多个模块中重复相同的属性,是不是用文字表达很模糊,好吗,上实例:

cc_defaults {////默认模块名称

name: "default_module",

shared_libs: ["libz"],

stl: "none",

}

cc_binary {

name: "test1",

defaults: ["default_module"],//引用默认模块名称

srcs: ["src/test/test.c"],

}

srcs 属性以字符串列表的形式指定用于编译模块的源文件。您可以使用模块引用语法 “:” 来引用生成源文件的其他模块的输出,如 genrule 或 filegroup。是不是感觉一头雾水,好吗,还是上实例说明:

~/ssd/qcom_64/msm8953-9$ cd frameworks/base/core/java/

~/ssd/qcom_64/msm8953-9/frameworks/base/core/java$ vi Android.bp

filegroup {

name: "IKeyAttestationApplicationIdProvider.aidl",

srcs: ["android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl"],

}

filegroup {

name: "IDropBoxManagerService.aidl",

srcs: ["com/android/internal/os/IDropBoxManagerService.aidl"],

~/ssd/qcom_64/msm8953-9/frameworks/base/core$ cd ..

~/ssd/qcom_64/msm8953-9/frameworks/base$ vi libs/services/Android.bp

cc_library_shared {

name: "libservices",

srcs: [

":IDropBoxManagerService.aidl",

"src/os/DropBoxManager.cpp",

"src/os/StatsDimensionsValue.cpp",

"src/os/StatsLogEventWrapper.cpp",

],

shared_libs: [

"libbinder",

"liblog",

"libcutils",

"libutils",

],

3afcbda9cf8729914baa1ac6548bad2a.png

1.2 变量

我们知道Android.mk中可以定义变量,当然作为新编译系统中替代Android.mk的Android.bp也是一定存在,更加何况Android.mk还可以一定条件的转换成Android.bp。

变量范围限定为声明它们的文件的其余部分,可以使用 “=” 号赋值, 但是不能使用 “:=” 赋值。变量是不可变的,但有一个例外它们可以附上+= 赋值,但仅在变量被引用之前。

error: packages/apps/Bluetooth/jni/Android.bp:2:15: expected "=" or "+=" or "{" or "(", found ":"

ninja: error: rebuilding 'out/soong/.minibootstrap/build.ninja': subcommand failed

10:28:15 soong failed with: exit status 1

下面我们看一下正确使用变量的列子:

gzip_srcs = ["src/minigzip.c"],

cc_binary {

name: "gzip",

srcs: gzip_srcs,

shared_libs: ["libz"],

stl: "none",

}

1.3 注释

我们知道Android.mk中可以进行注释,当然Android.bp里面也可以,Android.mk中使用"#"然后添加注释,Android.bp使用单行注释//和多行注释/* */两种方式。

1.4类型

具体支持以下几种类型:

Bool(true or false)

Integers(int)

Strings("string")

Listsof strings (["string1", "string2"])

Maps({key1: "value1", key2: ["value2"]})

1.5 操作符

String类型、字符串列表类型和Map类型支持操作符“+”。

1.6 支持模块类型

Android.bp可以支持android_app、cc_binary、cc_binary_host等多种类型,具体定义在Android源码的build/soong/androidmk/cmd/androidmk/android.go可以查看,具体如下:

var moduleTypes = map[string]string{

"BUILD_SHARED_LIBRARY": "cc_library_shared",

"BUILD_STATIC_LIBRARY": "cc_library_static",

"BUILD_HOST_SHARED_LIBRARY": "cc_library_host_shared",

"BUILD_HOST_STATIC_LIBRARY": "cc_library_host_static",

"BUILD_HEADER_LIBRARY": "cc_library_headers",

"BUILD_EXECUTABLE": "cc_binary",

"BUILD_HOST_EXECUTABLE": "cc_binary_host",

"BUILD_NATIVE_TEST": "cc_test",

"BUILD_HOST_NATIVE_TEST": "cc_test_host",

"BUILD_NATIVE_BENCHMARK": "cc_benchmark",

"BUILD_HOST_NATIVE_BENCHMARK": "cc_benchmark_host",

"BUILD_JAVA_LIBRARY": "java_library",

"BUILD_STATIC_JAVA_LIBRARY": "java_library_static",

"BUILD_HOST_JAVA_LIBRARY": "java_library_host",

"BUILD_HOST_DALVIK_JAVA_LIBRARY": "java_library_host_dalvik",

"BUILD_PACKAGE": "android_app",

}

1.7 支持预编译类型

Android.bp可以支持多种预编译类型,具体定义在Android源码的build/soong/androidmk/cmd/androidmk/android.go可以查看,如下图所示:

var prebuiltTypes = map[string]string{

"SHARED_LIBRARIES": "cc_prebuilt_library_shared",

"STATIC_LIBRARIES": "cc_prebuilt_library_static",

"EXECUTABLES": "cc_prebuilt_binary",

"JAVA_LIBRARIES": "prebuilt_java_library",

}

1.8 条件式编译

system/core/libusbhost$ cat Android.bp

cc_library {

name: "libusbhost",

vendor_available: true,

vndk: {

enabled: true,

},

host_supported: true,

srcs: ["usbhost.c"],

cflags: ["-Werror"],

export_include_dirs: ["include"],

target: {

android: { //编译Android上运行的程序

cflags: [

"-g",

"-DUSE_LIBLOG",

],

shared_libs: ["liblog"],

},

darwin: { //编译darwin上运行的程序

enabled: false,

},

},

}

结语

修行至此,恭喜读者你已经对Android.bp语法有一定了解了,行走江湖是有可能的了,还需多多磨练才行,在后续篇章中让我们一起学习。

写在最后

各位读者看官朋友们,Android.bp入门指南之浅析Android.bp语法,希望能吸引你,激发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。

本文分享 CSDN - IT先森。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

更多推荐