針對 32 位元和 64 位元架構進行建構

建構系統支援在同一個版本中,為兩個目標 CPU 架構 (32 位元和 64 位元) 建構二進位檔。這種兩個目標的版本稱為多重程式庫版本

針對內建靜態資料庫和共用程式庫,建構系統會設定規則,為這兩種架構建構二進位檔。產品設定 (PRODUCT_PACKAGES) 與依附元件圖表會決定要建構並安裝至系統映像檔的二進位檔。

對於可執行檔和應用程式,建構系統預設只會建構 64 位元版本,但您可以使用全域 BoardConfig.mk 變數或模組層級變數覆寫這項設定。

識別第二個 CPU 架構和 ABI

BoardConfig.mk 包含下列變數,可用於設定第二個 CPU 架構和應用程式二進位檔介面 (ABI):

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

如需使用這些變數的範例 makefile,請參閱 build/make/target/board/generic_arm64/BoardConfig.mk

在多重程式庫建構作業中,只要建構系統定義了 PRODUCT_PACKAGES 中的模組名稱,就會涵蓋 32 位元和 64 位元二進位檔。對於依附元件包含的程式庫,只有在其他 32 位元或 64 位元程式庫或可執行檔需要時,系統才會安裝 32 位元或 64 位元的程式庫。

不過,make 指令列上的模組名稱只涵蓋 64 位元版本。舉例來說,執行 lunch aosp_arm64-eng 後,make libc 只會建構 64 位元 libc。如要建構 32 位元 libc,您必須執行 make libc_32

在 Android.mk 中定義模組架構

您可以使用 LOCAL_MULTILIB 變數將版本設定為 32 位元和 64 位元,並覆寫全域 TARGET_PREFER_32_BIT 變數。

如要覆寫 TARGET_PREFER_32_BIT,請將 LOCAL_MULTILIB 設為下列其中一種狀態:

  • both 會建構 32 位元和 64 位元。
  • 32 只會建構 32 位元版本。
  • 64 僅建構 64 位元版本。
  • first 只會為第一個架構進行建構 (32 位元裝置為 32 位元,64 位元裝置為 64 位元)。

根據預設,LOCAL_MULTILIB 未設定,且建構系統會依據模組類別和其他 LOCAL_* 變數 (例如 LOCAL_MODULE_TARGET_ARCHLOCAL_32_BIT_ONLY) 決定要建構的架構。

如要針對特定架構建構模組,請使用以下變數:

  • LOCAL_MODULE_TARGET_ARCH:將這個變數設為架構清單,例如 arm x86 arm64。如果建構的架構位於該清單中,建構系統就會納入目前的模組。

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH:這個變數是 LOCAL_MODULE_TARGET_ARCH 的反向。如果建構的架構是該清單中的 not,建構系統就會納入目前的模組。

這兩個變數有以下幾種變化版本:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

如果按照列出的架構而略過目前的模組,建構系統會發出警告。

如要為特定架構設定建構旗標,請使用架構專屬的 LOCAL_* 變數,其中 * 是架構專屬的後置字串,例如:

  • LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
  • LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
  • LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,

只有在為該架構建構二進位檔時,這些變數才會套用。

有時,您可以根據二進位檔是為 32 位元或 64 位元建構而成,更輕鬆地設定標記。使用 LOCAL_* 變數搭配 _32_64 字尾,例如:

  • LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
  • LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
  • LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,

設定程式庫安裝路徑

針對非 multilib 版本,您可以使用 LOCAL_MODULE_PATH 將程式庫安裝到預設位置以外的位置。例如 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw

不過,在多重程式庫建構中,請改用 LOCAL_MODULE_RELATIVE_PATH

LOCAL_MODULE_RELATIVE_PATH := hw

使用這個格式時,64 位元和 32 位元程式庫都會安裝在正確的位置。

如果您同時建構 32 位元和 64 位元的可執行檔,請使用下列其中一個變數來區分安裝路徑:

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64:指定已安裝的檔案名稱。
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64:指定安裝路徑。

取得來源檔案的中繼目錄

在 Multilib 建構作業中,如果您為 $(local-intermediates-dir) (或具有明確變數的 $(intermediates-dir-for)) 產生來源檔案,則無法穩定運作。這是因為 32 位元和 64 位元版本都需要產生的中繼來源,但 $(local-intermediates-dir) 只會指向兩個中繼目錄中的其中一個。

建構系統提供專屬的多重程式庫友善中介目錄,用於產生來源。如要擷取中繼目錄路徑,請使用 $(local-generated-sources-dir)$(generated-sources-dir-for) 巨集。這些巨集的用法與 $(local-intermediates-dir)$(intermediates-dir-for) 類似。

如果來源檔案產生至這個專屬目錄,並由 LOCAL_GENERATED_SOURCES 挑選,則會在多重程式庫建構中針對 32 位元和 64 位元建構。

表示預建二進位檔目標的系統架構

在多重程式庫建構作業中,您無法使用 TARGET_ARCH,或 TARGET_ARCH 搭配 TARGET_2ND_ARCH,來表示預先建構的二進位目標的系統架構。請改用 LOCAL_* 變數 LOCAL_MODULE_TARGET_ARCHLOCAL_MODULE_UNSUPPORTED_TARGET_ARCH

有了這些變數,即使建構系統正在處理 64 位元的多重程式庫建構作業,也能選擇對應的 32 位元預先建構二進位檔。

如果您想使用所選架構來計算預先建構的二進位檔的原始路徑,請呼叫 $(get-prebuilt-src-arch)

確保產生 32 位元和 64 位元的 ODEX 檔案

針對 64 位元裝置,Google 預設會為啟動映像檔和任何 Java 程式庫產生 32 位元和 64 位元 ODEX 檔案。對於 APK,Google 預設只會為主要的 64 位元架構產生 ODEX。如果應用程式同時在 32 位元和 64 位元處理程序中啟動,請使用 LOCAL_MULTILIB := both 來確保產生 32 位元和 64 位元 ODEX 檔案。如果應用程式有任何 32 位元或 64 位元 JNI 程式庫,該標記也會告知建構系統加入這些程式庫。