Soong 构建系统

在 Android 7.0 发布之前,Android 仅使用GNU Make来描述和执行其构建规则。 Make 构建系统得到了广泛的支持和使用,但在 Android 规模上变得缓慢、容易出错、不可扩展且难以测试。 Soong 构建系统提供了 Android 构建所需的灵活性。

因此,平台开发者有望尽快从Make转向采用Soong。将问题发送至android-building Google Group 以获得支持。

宋是什么?

Android 7.0 (Nougat) 中引入了 Soong 构建系统来取代 Make。它利用Kati GNU Make 克隆工具和Ninja构建系统组件来加速 Android 的构建。

请参阅 Android 开源项目 (AOSP) 中的Android Make 构建系统描述以获取一般说明,并参阅 Android.mk 编写者的构建系统更改以了解从 Make 适应到 Soong 所需的修改。

请参阅词汇表中与构建相关的条目以了解关键术语的定义,并参阅 Soong 参考文件以了解完整的详细信息。

Make和宋比较

以下是 Make 配置与 Soong 在 Soong 配置(蓝图或.bp )文件中完成相同操作的比较。

举例说明

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux

LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src

LOCAL_SRC_FILES := $(call \
     all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)

宋例子

cc_library_shared {
     name: "libxmlrpc++",

     rtti: true,
     cppflags: [
           "-Wall",
           "-Werror",
           "-fexceptions",
     ],
     export_include_dirs: ["src"],
     srcs: ["src/**/*.cpp"],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

有关测试特定的 Soong 配置示例,请参阅简单构建配置

有关 Android.bp 文件中字段的说明,请参阅Android.bp 文件格式

特殊模块

一些特殊的模块组具有独特的特性。

默认模块

默认模块可用于在多个模块中重复相同的属性。例如:

cc_defaults {
    name: "gzip_defaults",
    shared_libs: ["libz"],
    stl: "none",
}

cc_binary {
    name: "gzip",
    defaults: ["gzip_defaults"],
    srcs: ["src/test/minigzip.c"],
}

预建模块

某些预构建的模块类型允许模块与其基于源的对应模块具有相同的名称。例如,当已经存在同名的cc_binary时,可能会有一个名为foocc_prebuilt_binary 。这使开发人员可以灵活地选择要包含在最终产品中的版本。如果构建配置包含两个版本,则预构建模块定义中的prefer标志值指示哪个版本具有优先级。请注意,某些预构建模块的名称不以prebuilt开头,例如android_app_import

命名空间模块

在 Android 完全从 Make 转换为 Soong 之前,Make 产品配置必须指定PRODUCT_SOONG_NAMESPACES值。它的值应该是以空格分隔的名称空间列表,Soong 将其导出到 Make 以由m命令构建。 Android 转换为 Soong 完成后,启用命名空间的详细信息可能会发生变化。

Soong 为不同目录中的模块提供了指定相同名称的能力,只要每个模块在单独的命名空间中声明即可。命名空间可以这样声明:

soong_namespace {
    imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}

请注意,命名空间没有 name 属性;它的路径会自动指定为其名称。

每个 Soong 模块都会根据其在树中的位置分配一个命名空间。每个 Soong 模块都被认为位于当前目录或最近祖先目录中Android.bp文件中的soong_namespace定义的命名空间中。如果没有找到这样的soong_namespace模块,则该模块被认为位于隐式根命名空间中。

下面是一个示例:Soong 尝试解析命名空间 N 中模块 M 声明的依赖项 D,该模块导入命名空间 I1、I2、I3…

  1. 然后,如果 D 是//namespace:module形式的完全限定名称,则仅在指定的命名空间中搜索指定的模块名称。
  2. 否则,Soong 首先查找在命名空间 N 中声明的名为 D 的模块。
  3. 如果该模块不存在,Soong 会在命名空间 I1、I2、I3… 中查找名为 D 的模块。
  4. 最后,Soong 查看根命名空间。