Membangun aplikasi untuk arsitektur 32-bit dan 64-bit

Sistem build mendukung pembuatan biner untuk dua arsitektur CPU target, 32 bit dan 64 bit, dalam build yang sama. Build dua target ini dikenal sebagai build multilib.

Untuk library statis bawaan dan library bersama, sistem build menyiapkan aturan untuk membuat biner bagi kedua arsitektur. Konfigurasi produk (PRODUCT_PACKAGES), bersama dengan grafik dependensi, menentukan biner yang di-build dan diinstal ke image sistem.

Untuk file yang dapat dieksekusi dan aplikasi, sistem build hanya mem-build versi 64-bit secara default, tetapi Anda dapat mengganti setelan ini dengan variabel BoardConfig.mk global atau variabel cakupan modul.

Mengidentifikasi arsitektur CPU dan ABI kedua

BoardConfig.mk menyertakan variabel berikut untuk mengonfigurasi arsitektur CPU kedua dan antarmuka biner aplikasi (ABI):

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

Untuk contoh makefile yang menggunakan variabel ini, lihat build/make/target/board/generic_arm64/BoardConfig.mk.

Dalam build multilib, nama modul di PRODUCT_PACKAGES mencakup biner 32-bit dan 64-bit, selama ditentukan oleh sistem build. Untuk library yang disertakan oleh dependensi, library 32-bit atau 64-bit hanya diinstal jika diperlukan oleh library 32-bit atau 64-bit lain atau dapat dieksekusi.

Namun, nama modul di command line make hanya mencakup versi 64-bit. Misalnya, setelah menjalankan lunch aosp_arm64-eng, make libc hanya akan mem-build libc 64-bit. Untuk mem-build libc 32-bit, Anda harus menjalankan make libc_32.

Menentukan arsitektur modul di Android.mk

Anda dapat menggunakan variabel LOCAL_MULTILIB untuk mengonfigurasi build untuk 32 bit dan 64 bit serta mengganti variabel TARGET_PREFER_32_BIT global.

Untuk mengganti TARGET_PREFER_32_BIT, tetapkan LOCAL_MULTILIB ke salah satu hal berikut:

  • both membangun 32 bit dan 64 bit.
  • 32 hanya mem-build 32 bit.
  • 64 hanya mem-build 64 bit.
  • first hanya di-build untuk arsitektur pertama (32 bit di perangkat 32-bit dan 64 bit di perangkat 64-bit).

Secara default, LOCAL_MULTILIB tidak ditetapkan dan sistem build memutuskan arsitektur mana yang akan dibuat berdasarkan class modul dan variabel LOCAL_* lainnya, seperti LOCAL_MODULE_TARGET_ARCH dan LOCAL_32_BIT_ONLY.

Jika ingin mem-build modul untuk arsitektur tertentu, gunakan variabel berikut:

  • LOCAL_MODULE_TARGET_ARCH - Tetapkan variabel ini ke daftar arsitektur, seperti arm x86 arm64. Jika arsitektur yang sedang dibangun berada dalam daftar tersebut, modul saat ini akan disertakan oleh sistem build.

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH - Variabel ini adalah kebalikan dari LOCAL_MODULE_TARGET_ARCH. Jika arsitektur yang dibangun adalah not dalam daftar tersebut, modul saat ini akan disertakan oleh sistem build.

Ada varian kecil dari kedua variabel ini:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

Sistem build memperingatkan jika modul saat ini dilewati karena arsitektur yang tercantum.

Guna menyiapkan flag build untuk arsitektur tertentu, gunakan variabel LOCAL_* khusus arsitektur dengan * adalah akhiran khusus arsitektur, misalnya:

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

Variabel ini hanya diterapkan jika biner sedang dibuat untuk arsitektur tersebut.

Terkadang lebih mudah untuk menyiapkan flag berdasarkan apakah biner di-build untuk 32-bit atau 64-bit. Gunakan variabel LOCAL_* dengan akhiran _32 atau _64, misalnya:

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

Menetapkan jalur penginstalan library

Untuk build non-multilib, Anda dapat menggunakan LOCAL_MODULE_PATH untuk menginstal library ke lokasi selain lokasi default. Misalnya, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw.

Namun, dalam build multilib, gunakan LOCAL_MODULE_RELATIVE_PATH sebagai gantinya:

LOCAL_MODULE_RELATIVE_PATH := hw

Dengan format ini, library 64-bit dan 32-bit akan diinstal di lokasi yang benar.

Jika Anda mem-build file yang dapat dieksekusi sebagai 32 bit dan 64 bit, gunakan salah satu variabel berikut untuk membedakan jalur penginstalan:

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64 - Menentukan nama file yang diinstal.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 - Menentukan jalur penginstalan.

Mendapatkan direktori perantara untuk file sumber

Dalam build multilib, jika Anda membuat file sumber ke $(local-intermediates-dir) (atau $(intermediates-dir-for) dengan variabel eksplisit), file tersebut tidak berfungsi dengan andal. Hal ini karena sumber yang dihasilkan perantara diperlukan oleh build 32-bit dan 64-bit, tetapi $(local-intermediates-dir) hanya mengarah ke salah satu dari dua direktori perantara.

Sistem build menyediakan direktori perantara khusus, ramah multilib, dan menengah untuk menghasilkan sumber. Untuk mengambil jalur direktori perantara, gunakan makro $(local-generated-sources-dir) atau $(generated-sources-dir-for). Penggunaan makro ini mirip dengan $(local-intermediates-dir) dan $(intermediates-dir-for).

Jika file sumber dibuat ke direktori khusus ini dan diambil oleh LOCAL_GENERATED_SOURCES, file tersebut akan di-build untuk 32 bit dan 64 bit dalam build multilib.

Menunjukkan arsitektur sistem target biner bawaan

Dalam build multilib, Anda tidak dapat menggunakan TARGET_ARCH, atau TARGET_ARCH yang dikombinasikan dengan TARGET_2ND_ARCH, untuk menunjukkan arsitektur sistem target biner bawaan. Sebagai gantinya, gunakan variabel LOCAL_* LOCAL_MODULE_TARGET_ARCH atau LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH.

Dengan variabel ini, sistem build dapat memilih biner bawaan 32-bit yang sesuai meskipun berfungsi pada build multilib 64-bit.

Jika Anda ingin menggunakan arsitektur yang dipilih untuk menghitung jalur sumber untuk biner bawaan, panggil $(get-prebuilt-src-arch).

Memastikan pembuatan file ODEX 32-bit dan 64-bit

Untuk perangkat 64-bit, secara default Google membuat file ODEX 32-bit dan 64-bit untuk image booting dan library Java apa pun. Untuk APK, secara default Google membuat ODEX hanya untuk arsitektur 64-bit utama. Jika aplikasi diluncurkan dalam proses 32-bit dan 64-bit, gunakan LOCAL_MULTILIB := both untuk memastikan file ODEX 32-bit dan 64-bit dihasilkan. Jika aplikasi memiliki library JNI 32-bit atau 64-bit, flag tersebut juga akan memberi tahu sistem build untuk menyertakannya.