Kompilacja dla architektur 32-bitowych i 64-bitowych, Kompilacja dla architektur 32-bitowych i 64-bitowych

System kompilacji obsługuje tworzenie plików binarnych dla dwóch docelowych architektur procesorów, 32-bitowej i 64-bitowej, w tej samej kompilacji. Ta kompilacja z dwoma celami jest nazywana kompilacją multilib .

W przypadku wbudowanych bibliotek statycznych i bibliotek współdzielonych system kompilacji konfiguruje reguły budowania plików binarnych dla obu architektur. Konfiguracja produktu ( PRODUCT_PACKAGES ) wraz z wykresem zależności określa, które pliki binarne są budowane i instalowane w obrazie systemu.

W przypadku plików wykonywalnych i aplikacji system kompilacji domyślnie tworzy tylko wersję 64-bitową, ale można zastąpić to ustawienie zmienną globalną BoardConfig.mk lub zmienną o zasięgu modułu.

Zidentyfikuj drugą architekturę procesora i ABI

BoardConfig.mk zawiera następujące zmienne umożliwiające skonfigurowanie architektury drugiego procesora i interfejsu binarnego aplikacji (ABI):

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

Przykładowy plik makefile używający tych zmiennych można znaleźć w build/make/target/board/generic_arm64/BoardConfig.mk .

W kompilacji z wieloma bibliotekami nazwy modułów w PRODUCT_PACKAGES obejmują zarówno 32-bitowe, jak i 64-bitowe pliki binarne, o ile są zdefiniowane przez system kompilacji. W przypadku bibliotek objętych zależnością biblioteka 32-bitowa lub 64-bitowa jest instalowana tylko wtedy, gdy jest wymagana przez inną bibliotekę 32-bitową lub 64-bitową lub plik wykonywalny.

Jednakże nazwy modułów w wierszu poleceń make dotyczą tylko wersji 64-bitowej. Na przykład, po uruchomieniu lunch aosp_arm64-eng , make libc zbudowało tylko 64-bitową bibliotekę libc. Aby zbudować 32-bitową bibliotekę libc, musisz uruchomić make libc_32 .

Zdefiniuj architekturę modułów w Android.mk

Możesz użyć zmiennej LOCAL_MULTILIB , aby skonfigurować kompilację dla wersji 32-bitowej i 64-bitowej i zastąpić zmienną globalną TARGET_PREFER_32_BIT .

Aby zastąpić TARGET_PREFER_32_BIT , ustaw LOCAL_MULTILIB na jedną z następujących opcji:

  • both wersje są zarówno 32-bitowe, jak i 64-bitowe.
  • 32 kompilacje tylko 32-bitowe.
  • 64 kompilacje tylko 64-bitowe.
  • first kompilacje tylko dla pierwszej architektury (32-bitowe na urządzeniach 32-bitowych i 64-bitowe na urządzeniach 64-bitowych).

Domyślnie LOCAL_MULTILIB nie jest ustawiony i system kompilacji decyduje, którą architekturę zbudować na podstawie klasy modułu i innych zmiennych LOCAL_ * , takich jak LOCAL_MODULE_TARGET_ARCH i LOCAL_32_BIT_ONLY .

Jeśli chcesz zbudować moduł dla konkretnych architektur, użyj następujących zmiennych:

  • LOCAL_MODULE_TARGET_ARCH - Ustaw tę zmienną na listę architektur, np. arm x86 arm64 . Jeśli budowana architektura znajduje się na tej liście, bieżący moduł zostanie uwzględniony w systemie kompilacji.

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH - Ta zmienna jest przeciwieństwem LOCAL_MODULE_TARGET_ARCH . Jeśli budowana architektura not znajduje się na tej liście, bieżący moduł zostanie uwzględniony w systemie kompilacji.

Istnieją mniejsze warianty tych dwóch zmiennych:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

System kompilacji ostrzega, jeśli bieżący moduł zostanie pominięty ze względu na wymienione architektury.

Aby ustawić flagi kompilacji dla określonej architektury, użyj specyficznych dla architektury zmiennych LOCAL_ * , gdzie * jest przyrostkiem specyficznym dla architektury, na przykład:

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

Zmienne te są stosowane tylko wtedy, gdy tworzony jest plik binarny dla tej architektury.

Czasami łatwiej jest ustawić flagi w zależności od tego, czy plik binarny jest tworzony dla wersji 32-bitowej, czy 64-bitowej. Użyj zmiennej LOCAL_ * z przyrostkiem _32 lub _64 , na przykład:

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

Ustaw ścieżkę instalacji biblioteki

W przypadku kompilacji innej niż multilib możesz użyć LOCAL_MODULE_PATH , aby zainstalować bibliotekę w lokalizacji innej niż domyślna. Na przykład LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw .

Jednak w kompilacji z wieloma bibliotekami użyj zamiast tego LOCAL_MODULE_RELATIVE_PATH :

LOCAL_MODULE_RELATIVE_PATH := hw

W tym formacie zarówno biblioteki 64-bitowe, jak i 32-bitowe są instalowane we właściwej lokalizacji.

Jeśli tworzysz plik wykonywalny zarówno w wersji 32-bitowej, jak i 64-bitowej, użyj jednej z następujących zmiennych, aby rozróżnić ścieżkę instalacji:

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64 - Określa nazwę zainstalowanego pliku.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 - Określa ścieżkę instalacji.

Uzyskaj katalog pośredni dla plików źródłowych

Jeśli w kompilacji multilib wygenerujesz pliki źródłowe do $(local-intermediates-dir) (lub $(intermediates-dir-for) z jawnymi zmiennymi), nie będzie to działać niezawodnie. Dzieje się tak dlatego, że pośrednio wygenerowane źródła są wymagane zarówno w kompilacjach 32-bitowych, jak i 64-bitowych, ale $(local-intermediates-dir) wskazuje tylko na jeden z dwóch katalogów pośrednich.

System kompilacji zapewnia dedykowany, przyjazny dla wielu bibliotek katalog pośredni do generowania źródeł. Aby pobrać ścieżkę do katalogu pośredniego, użyj makra $(local-generated-sources-dir) lub $(generated-sources-dir-for) . Zastosowania tych makr są podobne do $(local-intermediates-dir) i $(intermediates-dir-for) .

Jeśli plik źródłowy zostanie wygenerowany w tym dedykowanym katalogu i pobrany przez LOCAL_GENERATED_SOURCES , zostanie on zbudowany zarówno dla wersji 32-bitowej, jak i 64-bitowej w kompilacji z wieloma bibliotekami.

Wskaż architekturę systemu z prekompilowanymi obiektami binarnymi

W kompilacji z wieloma bibliotekami nie można używać TARGET_ARCH ani TARGET_ARCH w połączeniu z TARGET_2ND_ARCH do wskazania architektury systemu wstępnie zbudowanych obiektów binarnych. Zamiast tego użyj zmiennych LOCAL_ * LOCAL_MODULE_TARGET_ARCH lub LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH .

Dzięki tym zmiennym system kompilacji może wybrać odpowiedni 32-bitowy, wstępnie skompilowany plik binarny, nawet jeśli działa na 64-bitowej kompilacji z wieloma bibliotekami.

Jeśli chcesz użyć wybranej architektury do obliczenia ścieżki źródłowej dla wstępnie zbudowanego pliku binarnego, wywołaj $(get-prebuilt-src-arch) .

Zapewnij generowanie plików ODEX w wersji 32-bitowej i 64-bitowej

W przypadku urządzeń 64-bitowych domyślnie Google generuje zarówno 32-bitowe, jak i 64-bitowe pliki ODEX dla obrazu rozruchowego i wszelkich bibliotek Java. W przypadku plików APK Google domyślnie generuje ODEX tylko dla podstawowej architektury 64-bitowej. Jeśli aplikacja jest uruchamiana zarówno w procesach 32-bitowych, jak i 64-bitowych, użyj LOCAL_MULTILIB := both , aby upewnić się, że zostaną wygenerowane zarówno 32-bitowe, jak i 64-bitowe pliki ODEX. Jeśli aplikacja ma jakieś 32-bitowe lub 64-bitowe biblioteki JNI, ta flaga informuje również system kompilacji, aby je uwzględnił.