Kompilowanie wersji 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 na 2 urządzenia nazywa się kompilacją multilib.

W przypadku wbudowanych bibliotek statycznych i bibliotek udostępnionych system kompilacji konfiguruje reguły kompilowania plików binarnych dla obu architektur. Konfiguracja produktu (PRODUCT_PACKAGES) wraz z grafem zależności określa, które pliki binarne są kompilowane i instalowane w obrebie obrazu 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

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.

Nazwy modułów na wierszu poleceń make dotyczą jednak tylko wersji 64-bitowej. Na przykład po uruchomieniu lunch aosp_arm64-engmake libc kompiluje tylko 64-bitową bibliotekę libc. Aby skompilować 32-bitową bibliotekę libc, musisz uruchomić make libc_32.

Definiowanie architektury modułu w pliku 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 wersje 32- i 64-bitowe.
  • 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 parametr LOCAL_MULTILIB nie jest ustawiony, a system kompilacji decyduje, którą architekturę użyć na podstawie klasy modułu i innych zmiennych LOCAL_*, takich jak LOCAL_MODULE_TARGET_ARCHLOCAL_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 wartości mają drobne odmiany:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

System kompilacji ostrzega, jeśli bieżący moduł jest pomijany z powodu wymienionych 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 obie biblioteki (64- i 32-bitowa) 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 kompilacji 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 multilib, 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 makroużywają się podobnie jak $(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 wieloplatformowej nie można używać opcji TARGET_ARCH ani TARGET_ARCH w połączeniu z TARGET_2ND_ARCH, aby wskazać architekturę systemu docelowych binarnych plików wstępnie skompilowanych. 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).

Upewnij się, że pliki ODEX są generowane w wersji 32- i 64-bitowej

W przypadku urządzeń 64-bitowych Google domyślnie generuje pliki ODEX 32- i 64-bitowe dla obrazu rozruchowego i wszystkich bibliotek Java. W przypadku pakietów APK Google domyślnie generuje pliki ODEX tylko dla podstawowej architektury 64-bitowej. Jeśli aplikacja jest uruchamiana w procesach 32- i 64-bitowych, użyj narzędzia LOCAL_MULTILIB := both, aby upewnić się, że generowane są pliki ODEX 32- i 64-bitowe. Jeśli aplikacja zawiera 32- lub 64-bitowe biblioteki JNI, ten parametr spowoduje, że system kompilacji uwzględni je w kompilacji.