Für 32-Bit- und 64-Bit-Architekturen erstellen

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 von LOCAL_MODULE_TARGET_ARCH. Wenn die zu erstellende Architektur not 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.