Builds 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 Bibliotheken und freigegebene 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 System-Image installiert werden.

Für ausführbare Dateien und Apps erstellt das Build-System standardmäßig nur die 64-Bit-Version. Sie können diese Einstellung jedoch mit einer globalen BoardConfig.mk-Variablen oder einer Variablen auf Modulebene überschreiben.

Zweite CPU-Architektur und ABI identifizieren

BoardConfig.mk enthält die folgenden Variablen zum Konfigurieren der zweiten CPU-Architektur und der zweiten 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 eine Make-Datei, in der diese Variablen verwendet werden, finden Sie unter build/make/target/board/generic_arm64/BoardConfig.mk.

In einem Multilib-Build decken Modulnamen in PRODUCT_PACKAGES sowohl die 32‑Bit- als auch die 64‑Bit-Binärdateien ab, sofern sie vom Build-System definiert werden. Bei Bibliotheken, die durch eine Abhängigkeit eingebunden werden, wird eine 32-Bit- oder 64-Bit-Bibliothek nur installiert, wenn sie von einer anderen 32-Bit- oder 64-Bit-Bibliothek oder einer 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. Wenn Sie die 32-Bit-libc erstellen möchten, 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-Bit und 64-Bit konfigurieren und die globale Variable TARGET_PREFER_32_BIT überschreiben.

Um TARGET_PREFER_32_BIT zu überschreiben, legen Sie für LOCAL_MULTILIB einen der folgenden Werte fest:

  • both erstellt sowohl 32‑Bit- als auch 64‑Bit-Versionen.
  • 32 erstellt nur 32-Bit-Builds.
  • 64-Builds nur für 64 Bit.
  • 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 die zu erstellende Architektur in dieser Liste enthalten ist, 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 berücksichtigt.

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 architekturabhängigen LOCAL_*-Variablen, wobei * ein architekturabhängiges 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 ein Binärprogramm für diese Architektur erstellt wird.

Manchmal ist es einfacher, Flags basierend darauf einzurichten, ob das Binärprogramm 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 für Bibliothek festlegen

Bei einem Build ohne Multilib können Sie LOCAL_MODULE_PATH verwenden, um eine Bibliothek an einem anderen als dem Standardspeicherort zu installieren. Beispiel: LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw.

Bei einem Multilib-Build verwenden Sie 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 installierten Dateinamen an.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64: Gibt den Installationspfad an.

Zwischenverzeichnis für Quelldateien abrufen

Wenn Sie in einem Multilib-Build Quellcode für $(local-intermediates-dir) (oder $(intermediates-dir-for) mit expliziten Variablen) generieren, funktioniert das 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 spezielles, multilib-freundliches Zwischenverzeichnis zum Generieren von Quellen. Verwenden Sie das Makro $(local-generated-sources-dir) oder $(generated-sources-dir-for), um den Pfad des temporären Verzeichnisses abzurufen. Die Verwendung dieser Makros ähnelt der von $(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.

Systemarchitektur von vorgefertigten binären Zielen angeben

In einem Multilib-Build können Sie TARGET_ARCH oder TARGET_ARCH in Kombination mit TARGET_2ND_ARCH nicht verwenden, um die Systemarchitektur der vorkompilierten binären Ziele anzugeben. Verwenden Sie stattdessen die Variablen LOCAL_* LOCAL_MODULE_TARGET_ARCH oder LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH.

Mit diesen Variablen kann das Build-System das entsprechende 32-Bit-Prebuilt-Binärprogramm auswählen, auch wenn es an einem 64-Bit-Multilib-Build arbeitet.

Wenn Sie die ausgewählte Architektur verwenden möchten, um den Quellpfad für die vorkompilierte Binärdatei zu berechnen, rufen Sie $(get-prebuilt-src-arch) auf.

32-Bit- und 64-Bit-ODEX-Dateien generieren

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. Bei 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 32-Bit- oder 64-Bit-JNI-Bibliotheken enthält, weist dieses Flag das Build-System auch an, sie einzuschließen.