Das Build-System unterstützt das Erstellen von Binärdateien für zwei Ziel-CPU-Architekturen, 32-Bit und 64-Bit, im selben Build. Dieser Build mit zwei Zielen wird als Multilib-Build bezeichnet.
Für integrierte statische und freigegebene Bibliotheken richtet das Buildsystem Regeln ein, um Binärdateien für beide Architekturen zu erstellen. Die Produktkonfiguration (PRODUCT_PACKAGES
) bestimmt zusammen mit dem Abhängigkeitsdiagramm, welche Binärdateien erstellt und im System-Image installiert werden.
Bei ausführbaren Dateien und Anwendungen erstellt das Build-System standardmäßig nur die 64-Bit-Version. Sie können diese Einstellung jedoch mit einer globalen Variable vom Typ BoardConfig.mk
oder einer modulbezogenen Variablen überschreiben.
Zweite CPU-Architektur und ABI angeben
BoardConfig.mk
enthält die folgenden Variablen zum Konfigurieren der zweiten CPU-Architektur und der Anwendungs-Binärschnittstelle (Application Binary Interface, ABI):
TARGET_2ND_ARCH
TARGET_2ND_ARCH_VARIANT
TARGET_2ND_CPU_VARIANT
TARGET_2ND_CPU_ABI
TARGET_2ND_CPU_ABI2
Ein Beispiel für ein Makefile, in dem diese Variablen verwendet werden, finden Sie unter build/make/target/board/generic_arm64/BoardConfig.mk
.
Bei einem Multilib-Build umfassen die Modulnamen in PRODUCT_PACKAGES
sowohl die 32-Bit- als auch die 64-Bit-Binärdateien, sofern sie vom Buildsystem definiert sind. Bei Bibliotheken, die über eine Abhängigkeit eingebunden sind, wird eine 32‑ oder 64‑Bit-Bibliothek nur installiert, wenn sie von einer anderen 32‑ oder 64‑Bit-Bibliothek oder ausführbaren Datei benötigt wird.
Modulnamen in der make
-Befehlszeile beziehen sich jedoch nur auf die 64‑Bit-Version. Wenn Sie beispielsweise lunch aosp_arm64-eng
ausführen, wird mit make libc
nur die 64‑Bit-libc erstellt. Zum Erstellen der 32-Bit-libc müssen Sie make libc_32
ausführen.
Modularchitektur in Android.mk definieren
Mit der Variablen LOCAL_MULTILIB
können Sie Ihren Build für 32- und 64-Bit-Systeme konfigurieren und die globale Variable TARGET_PREFER_32_BIT
überschreiben.
Wenn Sie TARGET_PREFER_32_BIT
überschreiben möchten, legen Sie für LOCAL_MULTILIB
einen der folgenden Werte fest:
both
bietet sowohl 32-Bit- als auch 64-Bit-Versionen.32
erstellt nur 32-Bit-Builds.64
bietet nur 64-Bit-Versionen.first
-Builds werden nur für die erste Architektur erstellt (32 Bit auf 32-Bit-Geräten und 64 Bit auf 64-Bit-Geräten).
Standardmäßig ist LOCAL_MULTILIB
nicht festgelegt und das Build-System entscheidet anhand der Modulklasse und anderer LOCAL_*
-Variablen wie LOCAL_MODULE_TARGET_ARCH
und LOCAL_32_BIT_ONLY
, welche Architektur erstellt werden soll.
Wenn Sie Ihr Modul für bestimmte Architekturen erstellen möchten, verwenden Sie die folgenden Variablen:
LOCAL_MODULE_TARGET_ARCH
: Legen Sie diese Variable auf eine Liste von Architekturen fest, z. B.arm x86 arm64
. Wenn sich die zu erstellende Architektur in dieser Liste befindet, wird das aktuelle Modul vom Build-System berücksichtigt.LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
: Diese Variable ist das Gegenteil vonLOCAL_MODULE_TARGET_ARCH
. Wenn die zu erstellende Architekturnot
in dieser Liste ist, wird das aktuelle Modul vom Build-System eingeschlossen.
Es gibt geringfügige Varianten dieser beiden Variablen:
LOCAL_MODULE_TARGET_ARCH_WARN
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN
Das Build-System gibt eine Warnung aus, wenn das aktuelle Modul aufgrund der aufgeführten Architekturen übersprungen wird.
Wenn Sie Build-Flags für eine bestimmte Architektur einrichten möchten, verwenden Sie die architekturspezifischen LOCAL_*
-Variablen, wobei *
ein architekturspezifisches Suffix ist, z. B.:
LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,
Diese Variablen werden nur angewendet, wenn für diese Architektur ein Binärprogramm erstellt wird.
Manchmal ist es einfacher, Flags basierend darauf einzurichten, ob die Binärdatei für 32-Bit oder 64-Bit erstellt wird. Verwenden Sie die Variable LOCAL_*
mit dem Suffix _32
oder _64
, z. B.:
LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,
Installationspfad der Bibliothek festlegen
Bei einem Build ohne Multilib können Sie mit LOCAL_MODULE_PATH
eine Bibliothek an einem anderen Speicherort als dem Standardspeicherort installieren. Beispiel: LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
.
Verwenden Sie in einem Multilib-Build jedoch stattdessen LOCAL_MODULE_RELATIVE_PATH
:
LOCAL_MODULE_RELATIVE_PATH := hw
Bei diesem Format werden sowohl die 64-Bit- als auch die 32-Bit-Bibliotheken am richtigen Speicherort installiert.
Wenn Sie eine ausführbare Datei sowohl als 32-Bit- als auch als 64-Bit-Version erstellen, verwenden Sie eine der folgenden Variablen, um den Installationspfad zu unterscheiden:
LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64
: Gibt den Namen der installierten Datei an.LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64
: Gibt den Installationspfad an.
Zwischenverzeichnis für Quelldateien abrufen
Wenn Sie in einem Multilib-Build Quelldateien für $(local-intermediates-dir)
(oder $(intermediates-dir-for)
mit expliziten Variablen) generieren, funktioniert dies nicht zuverlässig. Das liegt daran, dass die generierten Zwischenquellen sowohl für die 32-Bit- als auch für die 64-Bit-Builds erforderlich sind, $(local-intermediates-dir)
aber nur auf eines der beiden Zwischenverzeichnisse verweist.
Das Build-System bietet ein dediziertes, multilib-freundliches Zwischenverzeichnis zum Generieren von Quellen. Verwenden Sie das Makro $(local-generated-sources-dir)
oder $(generated-sources-dir-for)
, um den Pfad des Zwischenverzeichnisses abzurufen. Die Verwendung dieser Makros ähnelt der von $(local-intermediates-dir)
und $(intermediates-dir-for)
.
Wenn eine Quelldatei in diesem speziellen Verzeichnis generiert und von LOCAL_GENERATED_SOURCES
übernommen wird, wird sie in einem Multilib-Build sowohl für 32-Bit- als auch für 64-Bit-Systeme erstellt.
Systemarchitektur vorgefertigter Binärziele angeben
Bei einem Multilib-Build können Sie weder TARGET_ARCH
noch TARGET_ARCH
in Kombination mit TARGET_2ND_ARCH
verwenden, um die Systemarchitektur der vorgefertigten Binärziele anzugeben. Verwenden Sie stattdessen die LOCAL_*
-Variablen LOCAL_MODULE_TARGET_ARCH
oder LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
.
Mit diesen Variablen kann das Buildsystem das entsprechende vorkompilierte 32-Bit-Binärprogramm auswählen, auch wenn es sich um einen 64-Bit-Multilib-Build handelt.
Wenn Sie die ausgewählte Architektur verwenden möchten, um den Quellpfad für das vorkonfigurierte Binary zu berechnen, rufen Sie $(get-prebuilt-src-arch)
auf.
ODEX-Dateien für 32- und 64-Bit-Systeme generieren
Bei 64-Bit-Geräten generiert Google standardmäßig sowohl 32-Bit- als auch 64-Bit-ODEX-Dateien für das Boot-Image und alle Java-Bibliotheken. Für APKs generiert Google standardmäßig ODEX nur für die primäre 64-Bit-Architektur. Wenn eine App sowohl in 32-Bit- als auch in 64-Bit-Prozessen gestartet wird, können Sie mit LOCAL_MULTILIB := both
dafür sorgen, dass sowohl 32-Bit- als auch 64-Bit-ODEX-Dateien generiert werden. Wenn die App 32-Bit- oder 64-Bit-JNI-Bibliotheken enthält, weist dieses Flag das Build-System an, diese ebenfalls einzubinden.