建構系統支援在同一個版本中,為兩個目標 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_ARCH
和 LOCAL_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_ARCH
或 LOCAL_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 程式庫,該標記也會告知建構系統加入這些程式庫。