安卓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"],
}
相关推荐
我的xiaodoujiao2 分钟前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 41--自定义定制化展示 Allure 测试报告内容
python·学习·测试工具·pytest
码农客栈4 分钟前
小程序学习(十一)之uni-app和原生小程序开发区别
学习·小程序·uni-app
淦。。。。8 分钟前
题解:P14013 [POCamp 2023] 送钱 / The Generous Traveler
开发语言·c++·经验分享·学习·其他·娱乐·新浪微博
小裕哥略帅15 分钟前
PMP学习笔记--过程
笔记·学习
嵌入式-老费19 分钟前
Android开发(开发板的三种操作系统)
android
好奇龙猫24 分钟前
【人工智能学习-AI入试相关题目练习-第六次】
人工智能·学习
[H*]43 分钟前
鸿蒙跨端Flutter学习:InheritedWidget嵌套使用
学习·flutter
2501_941864961 小时前
科学记忆法提升学习效率
学习
好奇龙猫1 小时前
【日语学习-日语知识点小记-日本語体系構造-JLPT-N2前期阶段-第一阶段(4):单词语法】
学习
凛_Lin~~1 小时前
安卓网络框架——OkHttp源码解析(基于3.14.x)
android·网络·okhttp