安卓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"],
}
相关推荐
严文文-Chris1 天前
【监督学习常用算法总结】
学习·算法
盐焗西兰花1 天前
鸿蒙学习实战之路 - 图片预览功能实现
学习·华为·harmonyos
Xudde.1 天前
friendly2靶机渗透
笔记·学习·安全·web安全·php
知识分享小能手1 天前
CentOS Stream 9入门学习教程,从入门到精通, CentOS Stream 9 命令行基础 —语法知识点与实战详解(4)
linux·学习·centos
码界奇点1 天前
Java Web学习 第15篇jQuery从入门到精通的万字深度解析
java·前端·学习·jquery
2501_915106321 天前
如何查看手机使用记录:Android和iOS设备全面指南
android·ios·智能手机·小程序·uni-app·iphone·webview
车载测试工程师1 天前
CAPL学习-ETH功能函数-通用函数
网络·学习·tcp/ip·capl·canoe
OAoffice1 天前
智能学习培训考试平台如何驱动未来组织:重塑人才发展格局
人工智能·学习·企业智能学习考试平台·学练考一体化平台
linly12191 天前
ERP学习笔记-频域分析之小波变换fieldtrip
笔记·学习
QiZhang | UESTC1 天前
学习日记day40
学习