Android.bp语法和使用,源码编译比平台低版本的sdk编译apk

一、 Android.bp 文件是什么?

Android.bp 文件首先是 Android 系统的一种编译配置文件,是用来代替原来的 Android.mk
文件的。在 Android7.0 以前,Android 都是使用 make 来组织各模块的编译,对应的编译
配置文件就是 Android.mk。

在 Android7.0 开始,Google 引入了 ninja 和 kati 来编译,为啥引入 ninja?因为随着 Android 越来越庞大,module 越来越多,编译时间也越来越久,而使用 ninja 在编译的并发处理上较 make 有很大的提升。Ninja 的配置文件就是Android.bp,Android 系统使用 Blueprint 和 Soong 工具来解析 Android.bp 转换生成 ninja文件。为了兼容老的 mk 配置文件,Android 当初也开发了 Kati 工具来转换 mk 文件生成ninja,目前 Android Q 里边,还是支持 Android.mk 方式的。相信在将来的版本中,会彻底让 mk 文件废弃,同时 Kati 也就淘汰了,只保留 bp 配置方式,所以我们要提前学习
bp。

这里涉及到Ninja, kati, Soong, bp概念,接下来分别简单介绍一下。

1.1 Ninja

ninja是一个编译框架,会根据相应的ninja格式的配置文件进行编译,但是ninja文件一般不会手动修改,而是通过将Android.bp文件转换成ninja格文件来编译。

1.2 Android.bp

Android.bp的出现就是为了替换Android.mk文件。bp跟mk文件不同,它是纯粹的配置,没有分支、循环等流程控制,不能做算数逻辑运算。如果需要控制逻辑,那么只能通过Go语言编写。

1.3 Soong

Soong类似于之前的Makefile编译系统的核心,负责提供Android.bp语义解析,并将之转换成Ninja文件。Soong还会编译生成一个androidmk命令,用于将Android.mk文件转换为Android.bp文件,不过这个转换功能仅限于没有分支、循环等流程控制的Android.mk才有效。

1.4 Blueprint

Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong负责Android编译而设计的工具,而Blueprint只是解析文件格式,Soong解析内容的具体含义。Blueprint和Soong都是由Golang写的项目,从Android 7.0,prebuilts/go/目录下新增Golang所需的运行环境,在编译时使用。

1.5 Kati

kati是专为Android开发的一个基于Golang和C++的工具,主要功能是把Android中的Android.mk文件转换成Ninja文件。代码路径是build/kati/,编译后的产物是ckati。

在这里插入图片描述

二、 语法对应规则

我们可能已经习惯了Android.mk 中的语法,现在要变更为 Android.bp, 为了便于理解,可以找到源码,查看Android.mk 与 Android.bp 语法对应规则:

源码位置: /build/soong/androidmk/cmd/androidmk/android.go 中, 这里我只粘贴一部分,完整代码请查看源文件。

var moduleTypes = map[string]string{
   
	"BUILD_JAVA_LIBRARY":             "java_library_installable", // will be rewritten to java_library by bpfix
	"BUILD_STATIC_JAVA_LIBRARY":      "java_library",
	"BUILD_HOST_JAVA_LIBRARY":        "java_library_host",
	"BUILD_HOST_DALVIK_JAVA_LIBRARY": "java_library_host_dalvik",
	"BUILD_PACKAGE":                  "android_app",
}
 
var prebuiltTypes = map[string]string{
   
	"SHARED_LIBRARIES": "cc_prebuilt_library_shared",
	"STATIC_LIBRARIES": "cc_prebuilt_library_static",
	"EXECUTABLES":      "cc_prebuilt_binary",
	"JAVA_LIBRARIES":   "java_import",
	"ETC":              "prebuilt_etc",
}

三、如何把Android.mk 文件转换成 Android.bp

  1. 在工程源码中:

      1.   source
<think>嗯,用户现在问的是关于android.bp文件的详解。之前他们问过关于在cc_binary中使用prebuilt_etc的问题,现在可能需要更全面的信息。首先,我需要确认用户的需求:他们可能正在学习Android构建系统,或者在实际开发中遇到了构建配置的问题,需要详细了解android.bp的结构用法。 用户可能已经了解了一些模块的基本用法,但想要更系统的知识,比如模块类型、语法规则、常用模块等。我需要从基础开始,逐步展开,确保结构清晰,便于他们理解。 接下来,我需要回顾android.bp的相关知识,确保信息准确。android.bp是Soong构建系统的配置文件,取代了原来的Makefile系统。它使用类似Go语言的语法,结构简洁,基于模块化设计。每个模块都有类型,如cc_binary、prebuilt_etc等,后跟属性键值对。 需要涵盖的内容包括: 1. 文件结构:语法规则、模块定义、属性类型等。 2. 常用模块类型,比如cc_binary、java_library等。 3. 变量与函数,如字符串操作、列表操作。 4. 条件编译依赖管理,如何根据产品配置调整构建。 5. 高级用法,比如命名空间、覆盖机制。 6. 与Makefile的交互,如KatiSoong的协同工作。 7. 最佳实践,比如模块命名、路径处理等注意事项。 同时,要考虑到用户可能的实际应用场景,比如他们可能需要配置一个包含多个依赖的项目,或者处理不同构建变体。因此,举例说明实际配置片段会很有帮助,比如展示一个cc_binary模块如何定义,或者如何添加静态库依赖。 还要注意用户可能的误区,比如嵌套模块定义(如之前的问题中提到的错误尝试),或者路径处理的问题,需要提醒他们避免常见错误。 另外,可能需要对比Android.bpAndroid.mk的区别,帮助从旧系统迁移的用户理解变化,但用户的问题没有直接提到这点,所以可能不需要深入,但简要提及可以增强理解。 最后,总结部分要强调关键点,比如模块化、语法简洁性,以及正确使用依赖管理条件编译的重要性。确保用户能有一个全面的认识,并能在实际开发中应用这些知识。</think>以下是关于 `Android.bp` 文件的详细解析,基于其设计逻辑实际使用场景整理: --- ### 一、核心概念 `Android.bp` 是 Android 构建系统(**Soong**)的配置文件,替代传统的 `Android.mk`,特点是: - **语法简洁**:类似 Go 语言,无复杂条件判断(原生不支持 `if-else`,需通过 `bazel` 风格条件) - **模块化设计**:每个模块独立定义,通过 `name` 字段唯一标识 - **静态声明**:无副作用(如 shell 命令),所有操作基于声明式规则 --- ### 二、文件结构解析 #### 1. **基础语法规则** - **模块定义**:以 `模块类型 { ... }` 格式声明 - **属性赋值**:键值对形式,如 `name: "foo"`,值类型包括字符串、列表、布尔值等 - **注释**:使用 `//` 单行注释 **示例**: ```python // 定义一个二进制程序 cc_binary { name: "my_daemon", // 模块名称(必须唯一) srcs: ["src/main.cpp"], // 源文件列表 shared_libs: ["liblog"],// 依赖的动态库 cflags: ["-Wall"], // 编译选项 } ``` #### 2. **数据类型** | 类型 | 示例 | 说明 | |------------|-------------------------------|--------------------------| | 字符串 | `name: "app"` | 双引号包裹 | | 列表 | `srcs: ["a.cpp", "b.cpp"]` | 方括号包裹,逗号分隔 | | 布尔值 | `enabled: true` | `true`/`false` | | 字典 | `product_variables: { ... }` | 嵌套键值对 | --- ### 三、常用模块类型 #### 1. **C/C++ 相关** - `cc_binary`: 编译生成可执行文件 - `cc_library`: 静态库/动态库 - `cc_prebuilt_library`: 预编译库 ```python cc_library { name: "libdemo", srcs: ["lib/*.cpp"], export_include_dirs: ["include"], // 对外暴露头文件路径 static: true, // 生成静态库(默认动态库) } ``` #### 2. **Java/Kotlin 相关** - `java_library`: Java 库(生成 `.jar`) - `android_app`: APK 应用 ```python android_app { name: "MyApp", srcs: ["src/**/*.java"], resource_dirs: ["res"], certificate: "platform", // 使用系统签名 } ``` #### 3. **文件与配置** - `prebuilt_etc`: 部署文件到 `/system/etc` - `filegroup`: 文件分组(用于跨模块引用) ```python prebuilt_etc { name: "my_config", src: "configs/demo.conf", sub_dir: "demo", // 安装到 /system/etc/demo/ owner: "root", mode: "0644", } ``` --- ### 四、变量与函数 #### 1. **字符串操作** - **拼接**:`"prefix_" + var` - **路径通配符**:`srcs: ["src/**/*.cpp"]`(递归匹配子目录) #### 2. **列表操作** - **合并列表**:`srcs: ["a.cpp"] + glob(["src/*.cpp"])` - **条件过滤**:通过 `enabled` 控制模块是否生效 #### 3. **全局变量** - `${config}` 命名空间下的变量(如 `${config.MyProductVar}`) - 通过 `bazel` 风格条件选择配置: ```python cc_binary { name: "demo", srcs: ["main.cpp"] + select({ "//conditions:debug": ["debug_log.cpp"], "//conditions:release": [], }), } ``` --- ### 五、依赖管理 #### 1. **静态依赖** - `static_libs`: 静态链接库 - `shared_libs`: 动态链接库 - `header_libs`: 头文件依赖(如 `libc_headers`) #### 2. **运行时依赖** - `data`: 打包到镜像的附加文件(如配置文件、资源) - `required`: 强制模块共存(如某服务依赖特定 HAL 接口) #### 3. **跨模块引用** - 通过 `name` 直接引用: ```python cc_binary { name: "daemon", shared_libs: ["libdemo"], // 引用名为 libdemo 的库 data: [":my_config"], // 引用 prebuilt_etc 模块 } ``` --- ### 六、条件编译与产品适配 #### 1. **产品级变量** 通过 `product_variables` 实现差异化配置: ```python cc_library { name: "libfeature", srcs: ["default.cpp"], product_variables: { platform_sdk_version: { min_version: ["29"]: { srcs: ["sdk29.cpp"] }, }, }, } ``` #### 2. **目标架构过滤** 使用 `target` 字段限制架构: ```python cc_library { name: "libarm", target: { android: { arch: ["arm64"] } }, // 仅 ARM64 架构生效 } ``` --- ### 七、高级用法 #### 1. **命名空间(Namespace)** 解决模块名冲突: ```python soong_namespace { // 声明在文件顶部 imports: ["other_namespace"], } ``` #### 2. **模块覆盖(Override)** 替换现有模块定义: ```python override_cc_binary { name: "original_module", new_property: "value", } ``` --- ### 八、与 Makefile 的交互 - **Kati 兼容性**:通过 `Android.bp` 生成 `ninja` 文件时,部分配置仍需 `Android.mk`(如 `LOCAL_MODULE_TAGS`) - **混合构建**:在过渡阶段,可通过 `blueprint` 工具将 `Android.mk` 转换为 `Android.bp` --- ### 九、调试与验证 #### 1. **构建命令** ```bash m <module_name> # 编译模块 mma # 快速编译当前目录模块 ``` #### 2. **查看依赖树** ```bash bpfmt -dumptree Android.bp # 格式化并显示模块结构 ``` --- ### 十、最佳实践 1. **模块命名**:清晰且唯一(如 `libdemo`、`demo_service`) 2. **路径处理**:优先使用 `glob()` 函数匹配文件,避免硬编码 3. **权限控制**:对 `prebuilt_etc` 等文件显式声明 `owner` `mode` 4. **条件精简**:减少复杂条件逻辑,优先通过产品变量控制 --- ### 总结 `Android.bp` 是 Android 构建系统的核心配置工具,其设计强调 **模块化** **声明式** 的简洁性。理解其模块类型、依赖管理条件编译机制,可高效定制系统镜像应用程序构建流程。对于复杂场景,建议结合官方文档([Soong](https://source.android.com/docs/setup/build))实际工程实践深入学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值