关于android:Androidbp快速入门

60次阅读

共计 5268 个字符,预计需要花费 14 分钟才能阅读完成。

一、Soong 编译系统

在 Android 7.0 公布之前,Android 仅应用 GNU Make 形容和执行其构建规定。在 Android 零碎级编译中,Make 构建零碎失去了宽泛的反对和应用,但它有一些毛病:编译迟缓、容易出错、无奈扩大且难以测试,而 Soong 构建零碎正好提供了 Android build 所需的灵活性。

Soong 构建零碎是在 Android 7.0 (Nougat) 中引入的,旨在取代 Make。它利用 Kati GNU Make 克隆工具和 Ninja 构建零碎组件来减速 Android 的构建,Soong 的编译流程图如下。

Soong 编译系统下,本来打算输出是.bp 文件,输入是.ninja 文件,然而因为零碎中的.mk 文件还没有被齐全打消掉,因而提供 kati 和 ckati 工具将.mk/Makefile 文件转换为.ninja 文件。.ninja 成为编译系统的汇编文件,是不须要人为去批改的,相当于配置文件来调用 gcc、java、clang 等编译器去编译。

Soong 编译系统的设计思维是打消.mk 文件中的 if/else 等逻辑,使.bp 文件只是一个简略的编译逻辑,这些简单的抉择配置逻辑应该放在更高层,比方应用更好调试的 Python 来编写。

二、Android.bp

Android.bp 的呈现就是为了替换 Android.mk 文件。bp 跟 mk 文件不同,它是纯正的配置,没有分支、循环等流程管制,不能做算数逻辑运算。如果须要管制逻辑,那么能够应用 Android.mk 或者 Go 语言进行编写。

2.1 示例

Android.bp 文件中的模块以模块类型结尾,而后是一组格局属性:name: value,在一点上 Android.bp 的语法结构与 JSON 的语法结构类似,都是以键值对的模式编写,比方。

android_app {
    name: "Provision",
    srcs: ["**/*.java"],
    platform_apis: true,
    product_specific: true,
    certificate: "platform",
} 

每个模块都必须具备 name 属性,并且相应值在所有 name 文件中必须是惟一的,仅有两个例外情况是命名空间和预构建模块中的 Android.bp 属性值,这两个值可能会反复。
srcs 属性以字符串列表的模式指定用于构建模块的源文件。能够应用模块援用语法 “:<module-name>” 来援用生成源文件的其余模块的输入,如 genrule 或 filegroup。

android_app{}

下面代码的意思是,该模块用于构建一个 apk。如果要给模块指定一个名字,能够应用上面的形式。

name: "Provision",

如果指定了 android_app 模块类型(在代码块的结尾),就须要设定该模块的 name。此设置会为模块命名,生成的 APK 将与模块名称雷同,不过带有 .apk 后缀。例如,在本例中,生成的 APK 将命名为 Provision.apk

 srcs: ["**/*.java"],

下面代码的 srcs 用于指定以后的模块编译的源码地位,* 示意通配符。

platform_apis: true,

设置该标记后会应用 sdk 的 hide 的 api 來编译。编译的 APK 中应用了零碎级 API,必须设定该值。和 Android.mk 中的 LOCAL_PRIVATE_PLATFORM_APIS 的作用雷同。

product_specific: true,

设置该标记后,生成的 apk 会被装置在 Android 零碎的 product 分区,和 Android.mk 中 LOCAL_PRODUCT_MODULE 作用雷同。

certificate 用于指定 APK 的签名形式。如果不指定,默认应用 testkey 签名。与 LOCAL_CERTIFICATE 作用雷同。Android 中共有四中签名形式:

  • testkey:一般 apk,默认应用该签名。
  • platform:该 apk 实现一些零碎的外围性能。通过对系统中存在的文件夹的拜访测试,这种形式编译进去的 apk 所在过程的 UID 为 system。
  • shared:该 apk 须要和 home/contacts 过程共享数据。
  • media:该 apk 是 media/download 零碎中的一环。

2.2 常见模块类型

在 Android.bp 中,咱们会基于模块类型来构建咱们所须要的货色,罕用的有以下几种类型:

  • cc_library_shared:编译成动静库,相似于 Android.mk 中的 BUILD_SHARED_LIBRARY。
  • cc_binary:编译成可执行文件,相似于 Android.mk 中的 BUILD_EXECUTABLE。
  • name:编译出的模块的名称,相似于 Android.mk 中的 LOCAL_MODULE。
  • srcs:源文件,相似于 Android.mk 中的 LOCAL_SRC_FILES。
  • local_include_dirs:指定门路查找头文件,相似于 Android.mk 中的 LOCAL_C_INCLUDES。
  • shared_libs:编译所依赖的动静库,相似于 Android.mk 中的 LOCAL_SHARED_LIBRARIES。
  • static_libs:编译所依赖的动态库,相似于 Android.mk 中的 LOCAL_STATIC_LIBRARIES。
  • cflags:编译 Flag,相似于 Android.mk 中的 LOCAL_CFLAGS。

android_app

用于构建 Android 应用程序安装包,是 Android 零碎利用开发中罕用的模块类型,与 Android.mk 中的 BUILD_PACKAGE 作用雷同。

java_library

java_library 用于将源代码构建并链接到设施的.jar 文件中。默认状况下,java_library 只有一个变量,它生成一个蕴含依据设施疏导类门路编译的.class 文件的.jar 包。生成的 jar 不适宜间接装置在设施上,通常会用作另一个模块的 static_libs 依赖项。

如果指定 installable:true 将生成一个蕴含 classes.dex 文件的.jar 文件,适宜在设施上装置。指定含 host_supported:true 将产生两个变量,一个依据 device 的 bootclasspath 编译,另一个依据 host 的 bootclasspath 编译。

android_library

android_library 将源代码与 android 资源文件一起构建并链接到设施的“.jar”文件中。android_library 有一个独自的变体,它生成一个蕴含依据 device 的 bootclasspath 编译的.class 文件的.jar 文件,以及一个蕴含应用 aapt2 编译的 android 资源的.package-res.apk 文件。生成的 apk 文件不能间接装置在设施上,但能够用作 android_app 模块的 static_libs 依赖项。

2.3 设置变量

在 bp 中能够通过 = 号来设定一个全局变量。

src_path = ["**/*.java"]
android_app {
    name: "Provision",
    srcs: src_path,
    platform_apis: true,
    product_specific: true,
    certificate: "platform",
}

三、根底语法

3.1 数据类型

Android.bp 中变量和属性是强类型,变量依据第一项赋值动态变化,属性由模块类型动态设置,反对的类型为:

  • 布尔值(true 或 false)
  • 整数(int)
  • 字符串(”string”)
  • 字符串列表 ([“string1”, “string2”])
  • 映射 ({key1: “value1”, key2: [“value2”]})

3.2 条件语句

Soong 不反对 Android.bp 文件中的条件语句。编译规定中如果须要解决条件语句,那么须要在 Go 中进行解决。大多数条件语句都会转换为映射属性,其中抉择了映射中的某个值并将其附加到顶级属性。

例如,要反对特定的架构文件,能够应用以下命令:

cc_library {
  ...
  srcs: ["generic.cpp"],
  arch: {
    arm: {srcs: ["arm.cpp"],
    },
    x86: {srcs: ["x86.cpp"],
    },
  },
}

3.3 运算符

能够应用 + 运算符附加字符串、字符串列表和映射。能够应用 + 运算符对整数求和。附加映射会生成两个映射中键的并集,并附加在两个映射中都存在的所有键的值。

3.4 示例

Android.bp 位于 Android 10 : packages/apps/Car/Notification 目录下,参考示例如下:

// 构建可执行程序
android_app {
    // 设定可执行的程序的名称,编译后会生成一个 CarNotification.apk
    name: "CarNotification",
    // 指定 java 源码的地位
    srcs: ["src/**/*.java"],
    // 指定资源文件的地位
    resource_dirs: ["res"],
    // 容许应用零碎 hide api
    platform_apis: true,
    // 设定 apk 签名为 platform
    certificate: "platform",
    // 设定 apk 装置门路为 priv-app
    privileged: true,
    // 是否启用代码优化,android_app 中默认为 true,java_library 中默认为 false
    optimize: {enabled: false,},
    // 是否事后生成 dex 文件,默认为 true。该属性会影响利用的首次启动速度以及 Android 零碎的启动速度
    dex_preopt: {enabled: false,},
    // 引入 java 动态库
    static_libs: [
        "androidx.cardview_cardview",
        "androidx.recyclerview_recyclerview",
        "androidx.palette_palette",
        "car-assist-client-lib",
        "android.car.userlib",
        "androidx-constraintlayout_constraintlayout"
    ],
    // 引入 java 库
    libs: ["android.car"],
    product_variables: {
        pdk: {enabled: false,},
    },
    // 设定依赖模块。如果装置了此模块,则要还须要装置的其余模块的名称
    required: ["privapp_whitelist_com.android.car.notification"]
}
// As Lib
android_library {
    name: "CarNotificationLib",
    srcs: ["src/**/*.java"],
    resource_dirs: ["res"],
    manifest: "AndroidManifest-withoutActivity.xml",
    platform_apis: true,
    optimize: {enabled: false,},
    dex_preopt: {enabled: false,},
    static_libs: [
        "androidx.cardview_cardview",
        "androidx.recyclerview_recyclerview",
        "androidx.palette_palette",
        "car-assist-client-lib",
        "android.car.userlib",
        "androidx-constraintlayout_constraintlayout"
    ],
    libs: ["android.car"],
    product_variables: {
        pdk: {enabled: false,},
    },
}

四、常见问题

4.1 引入第三方 jar

在理论开发中,常常须要在 app 中引入第三方的 jar。在 Android.bp 中,引入第三方的 jar 能够依照上面的形式。

首先,在我的项目的根目录新建 libs 文件夹,放入要导入的 jar 包,比方 CarServicelib.jar,而后在 Android.bp 中引入该 jar。

java_import {
  name: "CarServicelib.jar",
  jars: ["libs/CarServicelib.jar"],
}
android_app {
    // 省去其它属性
    static_libs: ["CarServicelib.jar"],
}

4.2 引入 AndroidX

开发过程中,如果想要引入 AndroidX 的类库,能够参考上面的形式进行引入。

android_app {
    // 省去其它属性
    // 引入 AndroidX 库下的 lib
    static_libs: [
        "androidx.cardview_cardview",
        "androidx.recyclerview_recyclerview",
        "androidx-constraintlayout_constraintlayout"
    ],
}

参考:
Soong 编译系统
Android 编译之 android.bp

正文完
 0