System kompilacji obsługuje tworzenie plików binarnych dla 2 docelowych architektur procesora – 32-bitowej i 64-bitowej – w ramach tej samej kompilacji. Taka kompilacja dla 2 architektur jest nazywana kompilacją multilib.
W przypadku wbudowanych bibliotek statycznych i bibliotek współdzielonych system kompilacji konfiguruje reguły tworzenia plików binarnych dla obu architektur. Konfiguracja produktu (PRODUCT_PACKAGES) wraz z grafem zależności określa, które pliki binarne są tworzone 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ślanie drugiej architektury procesora i ABI
BoardConfig.mk zawiera te zmienne do konfigurowania drugiej architektury procesora i interfejsu binarnego aplikacji (ABI):
TARGET_2ND_ARCHTARGET_2ND_ARCH_VARIANTTARGET_2ND_CPU_VARIANTTARGET_2ND_CPU_ABITARGET_2ND_CPU_ABI2
Przykładowy plik makefile, który używa tych zmiennych, znajdziesz w
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 lunch aosp_arm64-eng polecenie make libc tworzy tylko 64-bitową bibliotekę libc. Aby utworzyć 32-bitową bibliotekę libc, musisz uruchomić polecenie make libc_32.
Definiowanie architektury modułu w Android.mk
Za pomocą zmiennej LOCAL_MULTILIB możesz skonfigurować kompilację dla architektury 32-bitowej i 64-bitowej oraz zastąpić globalną zmienną TARGET_PREFER_32_BIT.
Aby zastąpić TARGET_PREFER_32_BIT, ustaw LOCAL_MULTILIB na jedną z tych wartości:
both– tworzy zarówno wersję 32-bitową, jak i 64-bitową.32– tworzy tylko wersję 32-bitową.64– tworzy tylko wersję 64-bitową.first– tworzy tylko dla pierwszej architektury (32-bitowej na urządzeniach 32-bitowych i 64-bitowej na urządzeniach 64-bitowych).
Domyślnie LOCAL_MULTILIB nie jest ustawiona, a system kompilacji decyduje, którą
architekturę utworzyć, na podstawie klasy modułu i innych
LOCAL_* zmiennych, takich jak LOCAL_MODULE_TARGET_ARCH
i LOCAL_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 architektura, dla której tworzona jest kompilacja, znajduje się na tej liście, bieżący moduł jest uwzględniany przez system kompilacji.LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH– ta zmienna jest przeciwieństwemLOCAL_MODULE_TARGET_ARCH. Jeśli architektura, dla której tworzona jest kompilacja,notznajduje się na tej liście, bieżący moduł jest uwzględniany przez system kompilacji.
Istnieją drobne warianty tych 2 zmiennych:
LOCAL_MODULE_TARGET_ARCH_WARNLOCAL_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
specyficznych dla architektury LOCAL_* gdzie
* jest sufiksem specyficznym 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 tej architektury.
Czasami łatwiej jest skonfigurować flagi na podstawie tego, czy plik binarny jest tworzony 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 innej niż multilib możesz użyć LOCAL_MODULE_PATH, aby zainstalować bibliotekę w innej lokalizacji niż domyślna lokalizacja. Na przykład LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw.
W kompilacji multilib użyj jednak LOCAL_MODULE_RELATIVE_PATH:
LOCAL_MODULE_RELATIVE_PATH := hw
W tym formacie zarówno biblioteka 64-bitowa, jak i 32-bitowa są instalowane w prawidłowej lokalizacji.
Jeśli tworzysz plik wykonywalny zarówno w wersji 32-bitowej, jak 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.
Pobieranie katalogu pośredniego dla plików źródłowych
W kompilacji multilib generowanie plików źródłowych do $(local-intermediates-dir) (lub $(intermediates-dir-for) z jawnymi zmiennymi) nie działa niezawodnie. Dzieje się tak, ponieważ pośrednie wygenerowane źródła są wymagane zarówno przez kompilację 32-bitową, jak i 64-bitową, ale $(local-intermediates-dir) wskazuje tylko jeden z 2 katalogów pośrednich.
System kompilacji udostępnia dedykowany katalog pośredni, który jest przyjazny dla multilib, do generowania źródeł. Aby pobrać ścieżkę katalogu pośredniego, użyj makra $(local-generated-sources-dir) lub $(generated-sources-dir-for). Użycie tych makr jest podobne do $(local-intermediates-dir) i $(intermediates-dir-for).
Jeśli plik źródłowy jest generowany w tym dedykowanym katalogu i pobierany przez LOCAL_GENERATED_SOURCES, w kompilacji multilib jest on tworzony zarówno w wersji 32-bitowej, jak i 64-bitowej.
Wskazywanie architektury systemu w przypadku wstępnie utworzonych celów binarnych
W kompilacji multilib nie możesz używać TARGET_ARCH ani TARGET_ARCH w połączeniu z TARGET_2ND_ARCH, aby wskazać architekturę systemu w przypadku wstępnie utworzonych celó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 wstępnie utworzony plik binarny 32-bitowy, nawet jeśli działa w kompilacji multilib 64-bitowej.
Jeśli chcesz użyć wybranej architektury do obliczenia ścieżki źródłowej wstępnie utworzonego pliku binarnego, wywołaj $(get-prebuilt-src-arch).
Zapewnianie generowania plików ODEX 32-bitowych i 64-bitowych
W przypadku urządzeń 64-bitowych Google domyślnie generuje pliki ODEX 32-bitowe i 64-bitowe dla obrazu rozruchowego i wszystkich 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, aby mieć pewność, że zostaną wygenerowane pliki ODEX 32-bitowe i 64-bitowe. Jeśli aplikacja ma biblioteki JNI 32-bitowe lub 64-bitowe, ta flaga informuje też system kompilacji, aby je uwzględnił.