Kompilacja dla architektur 32- i 64-bitowych

System kompilacji obsługuje kompilowanie binarnych plików dla 2 architektur procesorów (32- i 64-bitowych) w ramach tej samej kompilacji. Ta kompilacja z 2 docelowymi zasobami jest nazywana kompilacją multilib.

W przypadku wbudowanych bibliotek statycznych i bibliotek udostępnionych system kompilacji konfiguruje reguły kompilowania plików binarnych dla obu architektur. Konfiguracja usługi (PRODUCT_PACKAGES) w połączeniu z wykresem zależności określa, które pliki binarne zostaną skompilowane i zainstalowane w obrazie systemu.

W przypadku plików wykonywalnych i aplikacji system kompilacji domyślnie tworzy tylko wersję 64-bitową, ale możesz zastąpić to ustawienie za pomocą zmiennej globalnej BoardConfig.mk lub zmiennej w zakresie modułu.

Określ drugą architekturę procesora i ABI

Plik BoardConfig.mk zawiera te zmienne, które umożliwiają skonfigurowanie drugiej architektury 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ład pliku make, który używa tych zmiennych, znajdziesz w pliku build/make/target/board/generic_arm64/BoardConfig.mk.

W kompilacji wieloplatformowej nazwy modułów w PRODUCT_PACKAGES obejmują zarówno pliki binarne 32- i 64-bitowe, o ile są one zdefiniowane przez system kompilacji. W przypadku bibliotek uwzględnionych przez zależność biblioteka 32- lub 64-bitowa jest instalowana tylko wtedy, gdy jest wymagana przez inną 32- lub 64-bitową bibliotekę lub plik wykonywalny.

Jednak nazwy modułów w wierszu poleceń make obejmują tylko wersję 64-bitową. Na przykład po uruchomieniu lunch aosp_arm64-eng make libc kompiluje tylko 64-bitową bibliotekę libc. Aby skompilować 32-bitową bibliotekę libc, musisz uruchomić make libc_32.

Definiowanie architektury modułów w Android.mk

Za pomocą zmiennej LOCAL_MULTILIB możesz skonfigurować kompilację na potrzeby wersji 32- i 64-bitowej oraz zastąpić globalną zmienną TARGET_PREFER_32_BIT.

Aby zastąpić wartość TARGET_PREFER_32_BIT, ustaw wartość parametru LOCAL_MULTILIB na jedną z tych opcji:

  • both tworzy zarówno wersję 32-bitową, jak i 64-bitową.
  • 32 kompiluje tylko wersje 32-bitowe.
  • 64 kompiluje tylko wersje 64-bitowe.
  • first kompiluje tylko pierwszą architekturę (32-bitową na urządzeniach 32-bitowych i 64-bitową na urządzeniach 64-bitowych).

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

Jeśli chcesz skompilować moduł pod kątem określonych architektur, użyj tych zmiennych:

  • LOCAL_MODULE_TARGET_ARCH – ustaw tę zmienną na listę architektur, takich jak arm x86 arm64. Jeśli budowana architektura znajduje się na tej liście, system kompilacji uwzględnia bieżący moduł.

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH – ta zmienna jest przeciwieństwem zmiennej LOCAL_MODULE_TARGET_ARCH. Jeśli tworzona architektura znajduje się na tej liście, system kompilacji uwzględnia bieżący moduł.not

Te 2 zmiennych mają drobne warianty:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

System kompilacji ostrzega, jeśli bieżący moduł zostanie pominięty z powodu wymienionej architektur.

Aby skonfigurować flagi kompilacji dla konkretnej architektury, użyj zmiennych LOCAL_*, gdzie * to sufiks dla danej architektury, np.:

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

Te zmienne są stosowane tylko wtedy, gdy kompilowany jest plik binarny dla tej architektury.

Czasami łatwiej jest skonfigurować flagi na podstawie tego, czy plik binarny jest kompilowany na potrzeby wersji 32- 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,

Ustawianie ścieżki instalacji biblioteki

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

W przypadku kompilacji multilib należy jednak użyć opcji LOCAL_MODULE_RELATIVE_PATH:

LOCAL_MODULE_RELATIVE_PATH := hw

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

Jeśli kompilujesz plik wykonywalny w wersji 32- i 64-bitowej, użyj jednej z tych zmiennych, aby odróż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

W kompilacji wieloplatformowej wygenerowanie plików źródłowych do $(local-intermediates-dir) (lub $(intermediates-dir-for) z wyraźnymi zmiennymi) nie działa niezawodnie. Dzieje się tak, ponieważ pośrednie wygenerowane źródła są wymagane zarówno w przypadku wersji 32-bitowej, jak i 64-bitowej, ale $(local-intermediates-dir) wskazuje tylko na jeden z tych dwóch katalogów pośrednich.

System kompilacji udostępnia specjalny katalog pośredni, przyjazny dla bibliotek wieloplatformowych, do generowania źródeł. Aby pobrać ścieżkę do katalogu pośredniego, użyj makra $(local-generated-sources-dir) lub $(generated-sources-dir-for). Te makrosy mają podobne zastosowania jak makro $(local-intermediates-dir)$(intermediates-dir-for).

Jeśli plik źródłowy zostanie wygenerowany w tym specjalnym katalogu i przejęty przez LOCAL_GENERATED_SOURCES, zostanie skompilowany w wersji 32- i 64-bitowej w kompilacji wieloplatformowej.

Wskazać architekturę systemu gotowych do użycia docelowych plików binarnych

W kompilacji z wieloma bibliotekami nie możesz używać TARGET_ARCH ani TARGET_ARCH w połączeniu z TARGET_2ND_ARCH do wskazywania architektury systemowej gotowych celów binarnych. Zamiast tego używaj 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 multilib.

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

Sprawdź, czy generowanie plików ODEX w wersji 32- i 64-bitowej

W przypadku urządzeń 64-bitowych Google domyślnie 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 pliki ODEX tylko dla podstawowej architektury 64-bitowej. Jeśli aplikacja jest uruchamiana w procesach 32-bitowych i 64-bitowych, użyj LOCAL_MULTILIB := both, by mieć pewność, że zostaną wygenerowane zarówno 32-bitowe, jak i 64-bitowe pliki ODEX. Jeśli aplikacja zawiera 32- lub 64-bitowe biblioteki JNI, ten parametr spowoduje, że system kompilacji uwzględni je w kompilacji.