安卓bp文件编译学习

Android.bp 文件编写

一、核心概念:从 Make 到 Soong

背景

  • Android.mk: 用于 Android 7.0 (Nougat) 之前,基于 GNU Make。
  • Android.bp : 用于 Android 7.0 及之后,旨在取代 Android.mk,基于 Soong 构建系统。
  • 目的 : 解决 Make 构建系统在大型项目中的缓慢、易错、难以扩展和测试的问题。

Soong 构建系统

  • 定义 : Soong 是专为 Android 构建设计的新系统,利用 Kati (Make 克隆工具) 和 Ninja (构建系统组件) 来加速构建过程。
  • 优点: 提供更好的并发处理能力和灵活性。

二、Android.bp 文件格式与语法

基本结构

  • 模块化 : 文件由模块组成,每个模块以模块类型 开头,后跟一组 name: "value" 格式的属性。

  • 示例 :

    bp 复制代码
    cc_binary {
        name: "gzip",
        srcs: ["src/test/minigzip.c"],
        shared_libs: ["libz"],
        stl: "none",
    }
  • 强制属性 : 每个模块必须name 属性,且该值在所有 Android.bp 文件中必须唯一。

数据类型

属性是强类型的,支持以下类型:

  • 布尔值 : truefalse
  • 整数 : int
  • 字符串 : "string"
  • 字符串列表 : ["string1", "string2"]
  • 映射 : {key1: "value1", key2: ["value2"]}
    • 值可以是任何类型,包括嵌套映射。
    • 列表和映射的最后一个值后可以有一个终止逗号。

常用语法元素

  1. Glob 模式 : 用于匹配文件(如 srcs 属性)。

    • *: 普通通配符,如 *.java
    • **: 匹配零个或多个路径元素,如 java/**/*.java 匹配 java/Main.javajava/com/android/Main.java
  2. 变量: 支持顶级变量赋值。

    bp 复制代码
    gzip_srcs = ["src/test/minigzip.c"],
    cc_binary {
        name: "gzip",
        srcs: gzip_srcs, // 使用变量
        // ...
    }
  3. 注释 : 支持 C 风格多行 /* */ 和 C++ 风格单行 // 注释。

  4. 运算符 : 使用 + 运算符来附加字符串、字符串列表和映射。对整数求和。附加映射会合并键,并附加重复键的值。

  5. 条件语句 (限制) : Android.bp 本身不支持条件语句 (如 if)。复杂条件逻辑在 Soong 的 Go 语言层处理。在 bp 文件中,通常使用映射属性来实现条件选择。

    bp 复制代码
    cc_library {
        srcs: ["generic.cpp"],
        arch: {
            arm: { srcs: ["arm.cpp"], },
            x86: { srcs: ["x86.cpp"], },
        },
    }

三、关键机制与模块类型

1. 默认模块 (xx_defaults)

  • 作用: 定义一组可被其他模块继承的通用属性,避免重复书写,提高可维护性。

  • 类型 : cc_defaults, java_defaults, doc_defaults, stubs_defaults 等。

  • 用法 : 通过 defaults: [":default_module_name"] 继承。

  • 示例 :

    bp 复制代码
    cc_defaults {
        name: "gzip_defaults",
        shared_libs: ["libz"],
        stl: "none",
    }
    
    cc_binary {
        name: "gzip",
        defaults: ["gzip_defaults"], // 继承上面的属性
        srcs: ["src/test/minigzip.c"], // 然后添加自己特有的属性
    }

2. 依赖管理

  • 引入第三方 JAR :

    bp 复制代码
    java_import {
        name: "CarServicelib.jar", // 模块名
        jars: ["libs/CarServicelib.jar"], // JAR文件路径
    }
    
    android_app {
        // ...
        static_libs: [ "CarServicelib.jar" ], // 依赖上面定义的模块
    }
  • 引入 AndroidX 库 :

    bp 复制代码
    android_app {
        // ...
        static_libs: [
            "androidx.cardview_cardview",
            "androidx.recyclerview_recyclerview",
            "androidx-constraintlayout_constraintlayout"
        ],
    }

四、常用模块属性详解

以下是一些在构建 Android 应用和库时极其常用的属性:

属性 适用模块类型 说明 示例
name 全部 模块的唯一标识符,强制属性。 name: "MyApp"
srcs cc_*, java_*, android_app 源文件列表。可使用 glob 模式。 srcs: ["src/**/*.java"]
resource_dirs android_app 资源文件目录(res, assets 等)。 resource_dirs: ["res"]
static_libs android_app, java_library 依赖的静态库(包括引入的库如 AndroidX)。 static_libs: ["androidx.appcompat_appcompat"]
shared_libs cc_*, android_app 依赖的共享(动态)库 shared_libs: ["liblog"]
cflags/cppflags cc_* C/C++ 编译器标志 cflags: ["-Wall", "-Werror"]
javacflags java_* Java 编译器标志 javacflags: ["-Xlint:unchecked"]
certificate android_app 指定签名证书 certificate: "platform" (系统签名)
privileged android_app 标记为特权应用(需要签名和配置)。 privileged: true
platform_apis android_app 使用系统隐藏 API(而非 SDK)。 platform_apis: true
product_specific android_app APK 将被安装到 product 分区 product_specific: true
dex_preopt android_app 控制 DEX 预优化,影响启动速度。 dex_preopt: { enabled: false }
defaults 全部 继承一个默认模块的配置。 defaults: ["my_defaults"]

五、模块编译实例

1. 编译可执行程序 (C/C++)

bp 复制代码
cc_binary {
    name: "my_native_tool", // 生成的可执行文件名称
    srcs: ["src/main.c", "src/utils.c"],
    shared_libs: ["liblog", "libcutils"], // 依赖的动态库
    cflags: ["-Wall", "-Werror"],
    vendor: true, // 可选,标识为 vendor 模块
}

2. 编译无源码 APK (预编译)

bp 复制代码
android_app {
    name: "PrebuiltApp",
    srcs: ["app/PrebuiltApp.apk"], // 直接指向预编译的APK文件
    certificate: "platform",       // 指定签名方式
    privileged: true,             // 如果是特权应用
    product_specific: true,       // 指定安装分区
    // 通常不需要 resource_dirs 和 static_libs
}

3. 编译有源码 APK

bp 复制代码
android_app {
    name: "CarDialerApp",           // 生成的APK名称
    srcs: ["src/**/*.java"],         // Java源代码
    resource_dirs: ["res"],          // 资源目录
    platform_apis: true,            // 使用系统隐藏API
    certificate: "platform",        // 系统平台签名

    // 依赖的静态库(包括AndroidX和自己项目的库)
    static_libs: [
        "androidx.recyclerview_recyclerview",
        "androidx.cardview_cardview",
        "car-ui-lib",
        "my-common-library", // 假设的自定义库
    ],

    // 覆盖系统中已有的同名应用
    overrides: ["Dialer"],
}
相关推荐
阿巴斯甜16 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker17 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952718 小时前
Andorid Google 登录接入文档
android
黄林晴19 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android