針對 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

在多重程式庫建構作業中,只要建構系統定義了 32 位元和 64 位元二進位檔,PRODUCT_PACKAGES 中的模組名稱就會涵蓋這兩種二進位檔。如果是依附元件內含的程式庫,只有在其他 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,

設定程式庫安裝路徑

對於非多重程式庫建構作業,您可以使用 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 - 指定安裝路徑。

取得來源檔案的中繼目錄

在多重程式庫建構中,如果產生來源檔案至 $(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_ARCHTARGET_ARCHTARGET_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 程式庫,這個標記也會告知建構系統一併納入這些程式庫。