Das Build-System unterstützt die Erstellung 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 Bibliotheken und gemeinsam genutzte Bibliotheken richtet das Build-System Regeln zum Erstellen von Binärdateien für beide Architekturen ein. Die Produktkonfiguration ( PRODUCT_PACKAGES
) bestimmt zusammen mit dem Abhängigkeitsdiagramm, welche Binärdateien erstellt und im Systemabbild installiert werden.
Für ausführbare Dateien und Apps erstellt das Build-System standardmäßig nur die 64-Bit-Version, aber Sie können diese Einstellung mit einer globalen BoardConfig.mk
Variable oder einer modulbezogenen Variable überschreiben.
Identifizieren Sie eine zweite CPU-Architektur und ABI
BoardConfig.mk
enthält die folgenden Variablen zum Konfigurieren der zweiten CPU-Architektur und der Anwendungsbinärschnittstelle (ABI):
-
TARGET_2ND_ARCH
-
TARGET_2ND_ARCH_VARIANT
-
TARGET_2ND_CPU_VARIANT
-
TARGET_2ND_CPU_ABI
-
TARGET_2ND_CPU_ABI2
Ein Beispiel-Makefile, das diese Variablen verwendet, finden Sie build/make/target/board/generic_arm64/BoardConfig.mk
.
In einem Multilib-Build decken die Modulnamen in PRODUCT_PACKAGES
sowohl die 32-Bit- als auch die 64-Bit-Binärdateien ab, sofern sie vom Build-System definiert werden. Für Bibliotheken, die durch Abhängigkeiten einbezogen werden, wird eine 32-Bit- oder 64-Bit-Bibliothek nur dann installiert, wenn sie von einer anderen 32-Bit- oder 64-Bit-Bibliothek oder ausführbaren Datei benötigt wird.
Allerdings decken die Modulnamen in der make
-Befehlszeile nur die 64-Bit-Version ab. Beispielsweise erstellt make libc
nach dem Ausführen lunch aosp_arm64-eng
nur die 64-Bit-Libc. Um die 32-Bit-Libc zu erstellen, müssen Sie make libc_32
ausführen.
Definieren Sie die Modularchitektur in Android.mk
Sie können die Variable LOCAL_MULTILIB
verwenden, um Ihren Build für 32 Bit und 64 Bit zu konfigurieren und die globale Variable TARGET_PREFER_32_BIT
zu überschreiben.
Um TARGET_PREFER_32_BIT
zu überschreiben, legen Sie LOCAL_MULTILIB
auf einen der folgenden Werte fest:
-
both
Builds sind sowohl 32-Bit als auch 64-Bit. -
32
baut nur 32 Bit auf. -
64
baut nur 64 Bit auf. -
first
Builds nur für die erste Architektur (32 Bit bei 32-Bit-Geräten und 64 Bit bei 64-Bit-Geräten).
Standardmäßig ist LOCAL_MULTILIB
nicht festgelegt und das Build-System entscheidet basierend auf der Modulklasse und anderen 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 die zu erstellende Architektur in dieser Liste enthalten ist, wird das aktuelle Modul vom Build-System einbezogen.LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
– Diese Variable ist das Gegenteil vonLOCAL_MODULE_TARGET_ARCH
. Wenn die zu erstellende Architekturnot
in dieser Liste enthalten ist, wird das aktuelle Modul vom Build-System einbezogen.
Es gibt kleinere Varianten dieser beiden Variablen:
-
LOCAL_MODULE_TARGET_ARCH_WARN
-
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN
Das Build-System warnt, wenn das aktuelle Modul aufgrund der aufgeführten Architekturen übersprungen wird.
Um Build-Flags für eine bestimmte Architektur einzurichten, verwenden Sie die architekturspezifischen LOCAL_ *
-Variablen, wobei *
ein architekturspezifisches Suffix ist, zum Beispiel:
-
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 eine Binärdatei für diese Architektur 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
, zum Beispiel:
-
LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
-
LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
-
LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,
Legen Sie den Installationspfad der Bibliothek fest
Bei einem Nicht-Multilib-Build können Sie LOCAL_MODULE_PATH
verwenden, um eine Bibliothek an einem anderen Speicherort als dem Standardspeicherort zu installieren. Zum Beispiel LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
.
Verwenden Sie jedoch in einem Multilib-Build 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-Datei 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.
Besorgen Sie sich ein Zwischenverzeichnis für Quelldateien
Wenn Sie in einem Multilib-Build Quelldateien in $(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)
jedoch nur auf eines der beiden Zwischenverzeichnisse verweist.
Das Build-System stellt ein dediziertes, multilib-freundliches Zwischenverzeichnis zum Generieren von Quellen bereit. Um den Pfad des Zwischenverzeichnisses abzurufen, verwenden Sie das Makro $(local-generated-sources-dir)
oder $(generated-sources-dir-for)
. Die Verwendung dieser Makros ähnelt $(local-intermediates-dir)
und $(intermediates-dir-for)
.
Wenn eine Quelldatei in diesem dedizierten 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 erstellt.
Geben Sie die Systemarchitektur vorgefertigter binärer Ziele an
In einem Multilib-Build können Sie TARGET_ARCH
oder TARGET_ARCH
in Kombination mit TARGET_2ND_ARCH
nicht 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 Build-System die entsprechende vorgefertigte 32-Bit-Binärdatei auswählen, selbst wenn es an einem 64-Bit-Multilib-Build arbeitet.
Wenn Sie die ausgewählte Architektur verwenden möchten, um den Quellpfad für die vorgefertigte Binärdatei zu berechnen, rufen Sie $(get-prebuilt-src-arch)
auf.
Stellen Sie sicher, dass 32-Bit- und 64-Bit-ODEX-Dateien generiert werden
Für 64-Bit-Geräte 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, verwenden Sie LOCAL_MULTILIB := both
, um sicherzustellen, dass sowohl 32-Bit- als auch 64-Bit-ODEX-Dateien generiert werden. Wenn die App über 32-Bit- oder 64-Bit-JNI-Bibliotheken verfügt, weist dieses Flag das Build-System auch an, diese einzuschließen.