宋構建系統

在 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檔案很簡單。它們不包含條件或控制流語句;所有複雜性都由 Go 編寫的建構邏輯處理。如果可能, Android.bp檔案的語法和語意與Bazel BUILD 檔案類似。

模組

Android.bp檔案中的模組以模組類型開頭,後面跟著一組屬性name: "value",格式為:

cc_binary {
    name: "gzip",
    srcs: ["src/test/minigzip.c"],
    shared_libs: ["libz"],
    stl: "none",
}

每個模組都必須有一個name屬性,且該值在所有Android.bp檔案中必須是唯一的,命名空間和預先建置模組中的name屬性值除外,這些值可能會重複。

srcs屬性指定用於建立模組的來源文件,作為字串清單。您可以使用模組引用語法":<module-name>"來引用產生原始檔案的其他模組的輸出,例如genrulefilegroup

有關有效模組類型及其屬性的列表,請參閱Soong Modules Reference

類型

變數和屬性是強類型的,變數根據第一次賦值動態設置,屬性由模組類型靜態設定。支援的類型有:

  • 布林值( truefalse
  • 整數 ( int )
  • 字串( "string"
  • 字串清單 ( ["string1", "string2"] )
  • 地圖 ( {key1: "value1", key2: ["value2"]}

映射可以包含任何類型的值,包括巢狀映射。列表和映射的最後一個值後面可能有逗號。

格洛布斯

採用檔案清單的屬性(例如srcs )也可以採用 glob 模式。 Glob 模式可以包含普通的 UNIX 通配符* ,例如*.java 。 Glob 模式還可以包含單一**通配符作為路徑元素,它會符合零個或多個路徑元素。例如, java/**/*.java符合java/Main.javajava/com/android/Main.java模式。

變數

Android.bp檔案可能包含頂級變數賦值:

gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
    name: "gzip",
    srcs: gzip_srcs,
    shared_libs: ["libz"],
    stl: "none",
}

變數的作用域為聲明它們的檔案的其餘部分以及任何子藍圖檔案。變數是不可變的,但有一個例外:可以使用+=賦值將它們附加到後面,但只能在引用它們之前進行。

評論

Android.bp檔案可以包含 C 風格的多行/* */和 C++ 風格的單行//註解。

營運商

可以使用 + 運算子附加字串、字串清單和映射。可以使用+運算子對整數求和。附加映射會產生兩個映射中鍵的並集,從而附加兩個映射中存在的任何鍵的值。

條件句

Soong 不支援Android.bp檔案中的條件。相反,需要條件的建置規則的複雜性在 Go 中處理,可以使用高階語言功能,並且可以追蹤條件引入的隱式依賴關係。大多數條件都會轉換為映射屬性,其中選擇映射中的值之一並將其附加到頂級屬性。

例如,要支援特定於體系結構的文件:

cc_library {
    ...
    srcs: ["generic.cpp"],
    arch: {
        arm: {
            srcs: ["arm.cpp"],
        },
        x86: {
            srcs: ["x86.cpp"],
        },
    },
}

格式化程式

Soong 包含一個藍圖檔案的規範格式化程序,類似於gofmt 。若要遞歸地重新格式化目前目錄中的所有Android.bp文件,請執行:

bpfmt -w .

規範格式包括四空格縮排、多元素列表的每個元素後面的換行以及列表和映射中的尾隨逗號。

特殊模組

一些特殊的模組組具有獨特的特性。

預設模組

預設模組可用於在多個模組中重複相同的屬性。例如:

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 查看根命名空間。