安卓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"],
}
相关推荐
蓝桉~MLGT3 小时前
Python学习历程——Python面向对象编程详解
开发语言·python·学习
aramae3 小时前
MySQL数据库入门指南
android·数据库·经验分享·笔记·mysql
百锦再3 小时前
选择Rust的理由:从内存管理到抛弃抽象
android·java·开发语言·后端·python·rust·go
chenzhou__3 小时前
LinuxC语言文件i/o笔记(第十七天)
linux·c语言·笔记·学习
chenzhou__3 小时前
LinuxC语言文件i/o笔记(第十八天)
linux·c语言·笔记·学习
whatever who cares4 小时前
在Java/Android中,List的属性和方法
android·java
Nuyoah11klay4 小时前
华清远见25072班单片机高级学习day1
单片机·嵌入式硬件·学习
霜绛4 小时前
Unity:lua热更新(一)——AB包AssetBundle、Lua语法
笔记·学习·游戏·unity·lua
霜绛4 小时前
Unity:lua热更新(二)——Lua语法(续)
笔记·学习·unity·游戏引擎·lua