從 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 建構系統說明,以及Android.mk 編寫者專用的建構系統變更,瞭解從 Make 改用 Soong 所需的修改。

如要瞭解關鍵字詞的定義,請參閱術語表中的建構相關項目,並參閱 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 會在根命名空間中查詢。