建構系統支援在同一個建構作業中,為兩個目標 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_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,
設定程式庫安裝路徑
對於非多重程式庫建構作業,您可以使用 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_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 程式庫,這個標記也會告知建構系統一併納入這些程式庫。