Android.bp文件编写(1)


前言

Android.bp文件是Android系统的一种编译配置文件,是用来代替原来的Android.mk文件的。在Android7.0以前,Android都是使用make来组织各模块的编译,对应的编译配置文件就是Android.mk。随着安卓模块的不断增加,编译时间越来越长,make编译系统被逐渐放弃,转而使用并发处理更好的ninja编译工具,而对应的配置文件便是Android.bp。

一、Soong 构建系统

在 Android 7.0 发布之前,Android 仅使用 GNU Make 描述和执行其 build 规则。Make 构建系统得到了广泛的支持和使用,但在 Android 层面变得缓慢、容易出错、无法扩展且难以测试。Soong 构建系统正好提供了 Android build 所需的灵活性。

1.1 什么是 Soong?

Soong 构建系统是在 Android 7.0 (Nougat) 中引入的,旨在取代 Make。它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。


1.2 Make 和 Soong 比较

以下是 Make 配置与 Soong 在 Soong 配置(Blueprint 或 .bp)文件中完成相同操作的比较。

1.2.1 Make 示例

LOCAL_PATH := $(call my-dir)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux

LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src

LOCAL_SRC_FILES := $(call \
     all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)

1.2.2 Soong 示例

cc_library_shared {
     name: “libxmlrpc++,

     rtti: true,
     cppflags: [-Wall”,-Werror”,-fexceptions”,
     ],
     export_include_dirs: [“src”],
     srcs: [“src/**/*.cpp”],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

二、Android.bp 文件格式

根据设计,Android.bp 文件很简单。它们不包含任何条件语句,也不包含控制流语句;所有复杂问题都由用 Go 编写的构建逻辑处理。Android.bp 文件的语法和语义都尽可能与 Bazel BUILD 文件类似。

2.1 模块

Android.bp 文件中的模块以模块类型开头,后跟一组 name: “value”, 格式的属性:

cc_binary {
    name: "gzip",
    srcs: ["src/test/minigzip.c"],
    shared_libs: ["libz"],
    stl: "none",
}

每个模块都必须具有 name 属性,并且相应值在所有 name 文件中必须是唯一的,仅有两个例外情况是命名空间和预构建模块中的 Android.bp 属性值,这两个值可能会重复。
srcs 属性以字符串列表的形式指定用于构建模块的源文件。您可以使用模块引用语法 ":《module-name》"来引用生成源文件的其他模块的输出,如 genrule 或 filegroup。


2.2 类型

变量和属性是强类型,变量根据第一项赋值动态变化,属性由模块类型静态设置。支持的类型为:
布尔值(true 或 false)
整数 (int)
字符串 (“string”)
字符串列表 ([“string1”, “string2”])
映射 ({key1: “value1”, key2: [“value2”]})
映射可以包含任何类型的值,包括嵌套映射。列表和映射可能在最后一个值后面有终止逗号。


2.3 Glob

接受文件列表的属性(例如 srcs)也可以采用 glob 模式。glob 模式可以包含普通的 UNIX 通配符 *,例如 .java。glob 模式还可以包含单个 ** 通配符作为路径元素,与零个或多个路径元素匹配。例如,java/**/.java 同时匹配 java/Main.java 和 java/com/android/Main.java 模式。


2.4 变量

Android.bp 文件可能包含顶级变量赋值:

gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
    name: "gzip",
    srcs: gzip_srcs,
    shared_libs: ["libz"],
    stl: "none",
}

2.5 注释

Android.bp 文件可以包含 C 样式的多行 /* */ 注释以及 C++ 样式的单行 // 注释。


2.6 运算符

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


2.7 条件语句

Soong 不支持 Android.bp 文件中的条件语句。但是,编译规则中需要条件语句的复杂问题将在 Go(在这种语言中,您可以使用高级语言功能,并且可以跟踪条件语句引入的隐式依赖项)中处理。大多数条件语句都会转换为映射属性,其中选择了映射中的某个值并将其附加到顶级属性。

例如,要支持特定于架构的文件,请使用以下命令

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

2.8 默认模块

soong提供了一系列xx_defaults模块类型,例如:cc_defaults, java_defaults, doc_defaults, stubs_defaults等等。
xx_defaults的模块提供了一组可由其它模块继承的属性。其它模块可以通过defaults:[“<:default_module_name>”]来继承xx_defaults类型模块中定义的属性。xxx_defaults类型的模块可以被多个模块继承,减少我们在bp中书写重复的属性。

cc_defaults {
    name: "gzip_defaults",
    shared_libs: ["libz"],
    stl: "none",
}

cc_binary {
    name: "gzip",
    defaults: ["gzip_defaults"],
    srcs: ["src/test/minigzip.c"],
}

2.9 引入第三方jar

在实际开发中,我们经常需要在app中引入第三方的jar,在Android.bp中,可以按照下面的方式引入。在项目的根目录新建 libs文件夹,放入要导入的jar包,比如 CarServicelib.jar,然后在Android.bp中引入该jar

java_import {
  name: "CarServicelib.jar",
  jars: ["libs/CarServicelib.jar"],
}
android_app {
    // 省去其它属性
    // 引入AndroidX库下的lib
    static_libs: [
        "CarServicelib.jar"
    ],
}

2.10 引入AndroidX库

开发过程如果想要引入AndroidX的类库可以参考下面的方式编写。

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

三、源码示例

参考系统中已有模块的是如何编写的

源码路径 packages\apps\Car\Dialer\Android.bp

android_app {
   name: "CarDialerApp",  // 应用名称

   srcs: ["src/**/*.java"],  // Java源代码文件路径

   resource_dirs: ["res"],  // 资源文件路径

   platform_apis: true,  // 使用平台API

   required: ["privapp_whitelist_com.android.car.dialer"],  // 必需的特权应用白名单

   overrides: ["Dialer"],  // 覆盖项

   libs: ["android.car"],  // 库依赖

   static_libs: [  // 静态库依赖
       "androidx.recyclerview_recyclerview",
       "androidx.lifecycle_lifecycle-extensions",
       "androidx.preference_preference",
       "androidx-constraintlayout_constraintlayout",
       "androidx.legacy_legacy-support-v4",
       "androidx.cardview_cardview",
       "car-apps-common",
       "car-arch-common",
       "car-telephony-common",
       "car-theme-lib",
       "car-ui-lib",
       "car-uxr-client-lib",
       "androidx-constraintlayout_constraintlayout-solver",
       "guava",
       "glide-prebuilt",
       "libphonenumber",
       "androidx.sqlite_sqlite-framework",
       "androidx.sqlite_sqlite",
       "androidx.room_room-runtime",
   ],

   plugins: ["androidx.room_room-compiler-plugin"],  // 使用的插件

   optimize: {
       enabled: false,  // 是否启用代码优化
   },

   privileged: true,  // 是否具有特权

   dex_preopt: {
       enabled: false,  // 是否启用dex预优化 是否预先生成dex文件,默认为true。
                        // 该属性会影响应用的首次启动速度及Android系统的启动速度
   },

   product_variables: {
       pdk: {
           enabled: false,  // 是否启用PDK
       },
   },
}
}

四、模块示例及类型

Android.bp 文件中的模块以模块类型开头,然后是一组格式属性:name: value,在一点上Android.bp的语法结构与JSON的语法结构相似,都是以键值对的形式编写。下面是一个简单示例:

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

android_app{} 表示该模块用于构建一个apk

name: “TestApp”,如果指定了 android_app 模块类型(在代码块的开头),就需要设定该模块的 name 。此设置会为模块命名,生成的 APK 将与模块名称相同,不过带有 .apk 后缀。例如,在本例中,生成的 APK 将命名为 TestApp.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: “platform”, certificate 用于指定APK的签名方式。如果不指定,默认使用testkey签名。与LOCAL_CERTIFICATE作用相同。
Android中共有四中签名方式:
testkey:普通APK,默认使用该签名。
platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
shared:该APK需要和home/contacts进程共享数据。
media:该APK是media/download系统中的一环

五、模块编译实例

1 Android.bp编译之可执行程序
2 Android.bp编译之无源码apk
3 Android.bp编译之有源码apk

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值