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 属性已正确生效。

Android.bp 模块解析流程 Android.bp cc_defaults { name: "my_defaults" } cc_library_static { name: "libmymath" } Soong 解析器 读取模块类型 校验属性合法性 应用 defaults 继承 生成 Ninja 规则 构建产物 cc_binary → mytool cc_library_static → libmymath.a cc_defaults → 属性模板 (不直接产生文件) 属性 → 构建行为映射 srcs 指定编译的源文件 → 决定编译单元 shared_libs / static_libs 声明链接依赖 → 控制链接阶段 defaults 引用默认模块 → 属性继承复用 模块类型决定“构建什么”,属性决定“怎么构建” cc_binary → 可执行文件 | cc_library_static → .a 静态库 | cc_defaults → 属性模板