為 32 位元和 64 位元架構建構,為 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

在 multilib 建置中, 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 位元建置來設定標誌會更容易。使用帶有_32_64後綴的LOCAL_ *變量,例如:

  • 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 - 指定安裝路徑。

取得原始檔案的中間目錄

在 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_ARCHTARGET_ARCHTARGET_2ND_ARCH組合來指示預先建置二進位目標的系統體系結構。相反,請使用LOCAL_ *變數LOCAL_MODULE_TARGET_ARCHLOCAL_MODULE_UNSUPPORTED_TARGET_ARCH

透過這些變量,建置系統可以選擇相應的 32 位元預先建置二進位文件,即使它正在 64 位元 multilib 建置上工作。

如果您想要使用所選的體系結構來計算預先建置二進位檔案的來源路徑,請呼叫$(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 庫,則該標誌也會告訴建置系統包含它們。