從 Make 轉換為 Soong

在 Android 7.0 發布前,Android 會專門使用 GNU Make 來描述及執行建構規則。Make 建構系統廣泛受到支援和使用,但在 Android 的規模下,它變得速度緩慢、容易出錯、無法擴充且難以測試。Song 建構系統可提供 Android 版本所需的彈性。

因此,平台開發人員應盡快從 Make 切換並採用 Soong。將問題傳送至 android-building Google 網路論壇,即可獲得支援。

什麼是 Soong?

Soong 建構系統在 Android 7.0 (Nougat) 中推出,用於取代 Make。它會利用 Kati GNU Make 複本工具和 Ninja 建構系統元件,加快 Android 的建構作業。

請參閱 Android 開放原始碼計畫 (AOSP) 中的 Android Make Build 系統說明,查看一般操作說明Android.mk Writers 的建構系統變更,瞭解從 Make to Soong 調整內容需要的修改內容。

如需重要詞彙的定義,請參閱詞彙表中的建構相關項目;如需完整詳細資料,請參閱 Soong 參考檔案

品牌和型號比較

以下是 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)

Soong 範例

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"],
}

請注意,命名空間沒有名稱屬性,其路徑會自動指派為名稱。

系統會根據 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 會在根命名空間中尋找。