4. 理解Android.bp文件结构
任务目标
阅读并解析一个典型的 Android.bp 文件,理解其声明式语法:模块类型如何定义构建产物、属性如何控制编译行为,以及这些声明如何映射到实际产物(可执行文件、静态库、默认模块)。
核心概念
Android.bp 使用类似 JSON 的语法(Blueprint),每个模块以 模块类型 开头,后跟 模块名 和 属性块。模块类型决定构建系统如何编译该模块(如 cc_binary 生成可执行文件),属性则提供源文件、依赖、编译选项等具体指令。Soong 构建系统解析该文件后生成 Ninja 构建规则。
典型文件解析
以下是一个包含三种常见模块类型的 Android.bp 示例,覆盖了可执行文件、静态库和默认配置模块:
// Android.bp - 典型模块结构示例
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
// 默认模块:为多个目标模块提供共享属性
cc_defaults {
name: "my_defaults",
cflags: ["-Wall", "-Werror"],
compile_multilib: "64",
}
// 静态库模块:生成 libmymath.a
cc_library_static {
name: "libmymath",
srcs: ["math_utils.cpp"],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
}
// 可执行文件模块:生成 mytool 二进制
cc_binary {
name: "mytool",
srcs: ["main.cpp"],
shared_libs: ["liblog"],
static_libs: ["libmymath"],
defaults: ["my_defaults"],
}
模块类型与属性说明
| 模块类型 | 作用 | 关键属性 |
|---|---|---|
cc_defaults | 定义一组默认属性,供其他模块通过 defaults 引用,避免重复配置 | name, cflags, compile_multilib |
cc_library_static | 编译为静态库(.a),链接时被整体打包进最终二进制 | name, srcs, export_include_dirs |
cc_binary | 编译为可执行文件,可直接在设备/主机运行 | name, srcs, shared_libs, static_libs, defaults |
属性解析:
name:模块唯一标识,构建产物文件名由此派生(如mytool生成mytool)。srcs:源文件列表,支持通配符(如*.cpp)。shared_libs:链接的动态库,运行时需要存在于目标系统。static_libs:链接的静态库,编译时直接合并入二进制。defaults:引用cc_defaults模块,继承其全部属性。export_include_dirs:将该目录暴露给依赖此库的其他模块。cflags:传递给 C/C++ 编译器的额外参数。
验证方法
在 AOSP 源码树中创建包含上述文件及对应源文件(main.cpp、math_utils.cpp、include/math_utils.h)的目录,执行以下命令验证解析正确性:
source build/envsetup.sh
lunch <target> # 例如 aosp_arm64-userdebug
m mytool # 触发构建 mytool 及其依赖
通过条件:构建成功且无语法错误;在输出目录中找到 mytool 可执行文件和 libmymath.a 静态库。若修改 cflags 添加 -Werror 后故意引入编译警告,构建应失败,证明 defaults 属性已正确生效。