Erstellen Sie für 32-Bit- und 64-Bit-Architekturen. Erstellen Sie für 32-Bit- und 64-Bit-Architekturen

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