Kompilowanie wersji dla architektur 32- i 64-bitowych

System kompilacji obsługuje kompilowanie plików binarnych dla 2 architektur procesora docelowego, 32-bitowej i 64-bitowej, w ramach tej samej kompilacji. Ta kompilacja z 2 platformami docelowymi jest nazywana kompilacją multilib.

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

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

Określ drugą architekturę procesora i ABI

BoardConfig.mk zawiera te zmienne do skonfigurowania 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ładowy plik makefile, który korzysta z tych zmiennych, znajdziesz w sekcji build/make/target/board/generic_arm64/BoardConfig.mk.

W kompilacji multilib nazwy modułów w PRODUCT_PACKAGES obejmują zarówno pliki binarne 32-bitowe, jak i 64-bitowe, o ile są zdefiniowane przez system kompilacji. Biblioteki uwzględnione przez zależność są instalowane tylko wtedy, gdy są wymagane przez inną bibliotekę lub plik wykonywalny 32-bitowy lub 64-bitowy.

Nazwy modułów w wierszu poleceń make obejmują jednak tylko wersję 64-bitową. Na przykład po uruchomieniu polecenia lunch aosp_arm64-engmake libc zostanie utworzona tylko 64-bitowa biblioteka libc. Aby skompilować 32-bitową bibliotekę libc, musisz uruchomić polecenie make libc_32.

Definiowanie architektury modułu w pliku Android.mk

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

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

  • both tworzy zarówno 32-bitowe, jak i 64-bitowe wersje.
  • 32 tworzy tylko wersje 32-bitowe.
  • 64 kompiluje tylko wersję 64-bitową.
  • first – kompilacje tylko dla pierwszej architektury (32-bitowej na urządzeniach 32-bitowych i 64-bitowej na urządzeniach 64-bitowych).

Domyślnie zmienna LOCAL_MULTILIB nie jest ustawiona, a system kompilacji decyduje, którą architekturę ma skompilować, na podstawie klasy modułu i innych zmiennych LOCAL_*, takich jak LOCAL_MODULE_TARGET_ARCHLOCAL_32_BIT_ONLY.

Jeśli chcesz utworzyć moduł dla określonych architektur, użyj tych 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, system kompilacji uwzględnia bieżący moduł.

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH – ta zmienna jest przeciwieństwem zmiennej LOCAL_MODULE_TARGET_ARCH. Jeśli budowana architektura jest notna tej liście, bieżący moduł jest uwzględniany przez system kompilacji.

Istnieją niewielkie warianty tych 2 zmiennych:

  • 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 określonej architektury, użyj zmiennych LOCAL_* specyficznych dla architektury, gdzie * to sufiks specyficzny dla 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 plik binarny jest tworzony dla danej architektury.

Czasami łatwiej jest skonfigurować flagi na podstawie tego, czy plik binarny jest kompilowany dla architektury 32-bitowej czy 64-bitowej. Użyj zmiennej LOCAL_* z sufiksem _32 lub _64, np.:

  • 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 obsługi wielu bibliotek możesz użyć polecenia LOCAL_MODULE_PATH, aby zainstalować bibliotekę w innym miejscu niż domyślne. Na przykład:LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw.

W przypadku kompilacji wieloarchitekturowej użyj jednak tego kodu: LOCAL_MODULE_RELATIVE_PATH

LOCAL_MODULE_RELATIVE_PATH := hw

W tym formacie biblioteki 64-bitowe i 32-bitowe są instalowane w odpowiednim miejscu.

Jeśli tworzysz plik wykonywalny w wersji 32-bitowej 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 zainstalowaną nazwę pliku.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 – określa ścieżkę instalacji.

Uzyskiwanie katalogu pośredniego dla plików źródłowych

W przypadku kompilacji z wieloma bibliotekami, jeśli 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, ponieważ pośrednie wygenerowane źródła są wymagane zarówno w przypadku kompilacji 32-bitowych, jak i 64-bitowych, ale $(local-intermediates-dir) wskazuje tylko jeden z tych dwóch katalogów pośrednich.

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

Jeśli plik źródłowy zostanie wygenerowany w tym dedykowanym katalogu i pobrany przez LOCAL_GENERATED_SOURCES, zostanie utworzony w wersji 32-bitowej i 64-bitowej w ramach kompilacji wielolibowej.

Wskazywanie architektury systemu w przypadku wstępnie utworzonych plików binarnych

W kompilacji wieloarchitekturowej nie możesz używać tagu TARGET_ARCH ani tagu TARGET_ARCH w połączeniu z tagiem TARGET_2ND_ARCH, aby wskazać architekturę systemu wstępnie skompilowanych binarnych elementów docelowych. 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 wstępnie skompilowany plik binarny 32-bitowy, nawet jeśli pracuje nad kompilacją 64-bitową z wieloma bibliotekami.

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

Zapewnij generowanie 32-bitowych i 64-bitowych plików ODEX.

W przypadku urządzeń 64-bitowych Google domyślnie generuje pliki ODEX w wersji 32-bitowej i 64-bitowej dla obrazu rozruchowego i wszystkich bibliotek Java. W przypadku plików APK Google domyślnie generuje pliki ODEX tylko dla głównej architektury 64-bitowej. Jeśli aplikacja jest uruchamiana w procesach 32-bitowych i 64-bitowych, użyj LOCAL_MULTILIB := both, aby mieć pewność, że zostaną wygenerowane pliki ODEX zarówno 32-bitowe, jak i 64-bitowe. Jeśli aplikacja zawiera biblioteki JNI 32-bitowe lub 64-bitowe, ta flaga informuje też system kompilacji, że należy je uwzględnić.