64-Bit-Builds verstehen

Das Build-System unterstützt das Erstellen von Binärdateien für zwei Ziel-CPU-Architekturen (64 Bit und 32 Bit) im selben Build. Dies wird als Multilib-Build bezeichnet .

Für native statische Bibliotheken und gemeinsam genutzte Bibliotheken richtet das Erstellungssystem 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 -Variablen oder einer modulbezogenen Variablen überschreiben.

Produkt Konfiguration

BoardConfig.mk enthält die folgenden Variablen, um die zweite CPU-Architektur und ABI zu konfigurieren:

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

Ein Beispiel finden Sie in build/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, solange sie vom Build-System definiert werden. Für Bibliotheken, die durch Abhängigkeit eingebunden werden, wird eine 32-Bit-Bibliothek nur installiert, wenn sie von einer anderen 32-Bit-Bibliothek oder ausführbaren Datei benötigt wird. Dasselbe gilt für 64-Bit-Bibliotheken.

Modulnamen in der make -Befehlszeile decken jedoch nur die 64-Bit-Version ab. Wenn Sie beispielsweise lunch aosp_arm64-eng , erstellt make libc nur die 64-Bit-libc. Um die 32-Bit-Libc zu erstellen, müssen Sie make libc_32 .

Moduldefinition in Android.mk

Sie können die Variable LOCAL_MULTILIB verwenden, um Ihren Build für 32 Bit/64 Bit zu konfigurieren und die globale Variable TARGET_PREFER_32_BIT zu überschreiben.

Stellen Sie LOCAL_MULTILIB auf einen der folgenden Werte ein:

  • "both" erstellt sowohl 32-Bit- als auch 64-Bit-Versionen.
  • "32" baut nur 32 Bit.
  • "64" baut nur 64 Bit.
  • "first" baut nur für die erste Architektur (32 Bit in 32-Bit-Geräten und 64 Bit in 64-Bit-Geräten).
  • "" ist die Standardeinstellung. Das Bausystem entscheidet basierend auf der Modulklasse und anderen LOCAL_ Variablen, wie LOCAL_MODULE_TARGET_ARCH und LOCAL_32_BIT_ONLY , welche Architektur gebaut 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 Erstellungssystem eingeschlossen.
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
    Diese Variable ist das Gegenteil von LOCAL_MODULE_TARGET_ARCH . Wenn die zu erstellende Architektur nicht in dieser Liste enthalten ist, wird das aktuelle Modul vom Erstellungssystem eingeschlossen.

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. Eine architekturspezifische LOCAL_ -Variable ist eine normale LOCAL_ -Variable mit einem Architektursuffix, 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 derzeit eine Binärdatei für diese Architektur erstellt wird.

Manchmal ist es einfacher, Flags basierend darauf einzurichten, ob die Binärdatei derzeit 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,

Pfad installieren

Zuvor konnten 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 .

Verwenden Sie 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 Ort 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.

Generierte Quellen

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 von 32-Bit- als auch von 64-Bit-Builds benötigt werden, aber $(local-intermediates-dir) nur auf eines der beiden Zwischenverzeichnisse zeigt.

Das Build-System bietet ein dediziertes, multilib-freundliches Zwischenverzeichnis zum Generieren von Quellen. Sie können $(local-generated-sources-dir) oder $(generated-sources-dir-for) aufrufen, um den Pfad des Verzeichnisses zu erhalten. Ihre Verwendung ist ähnlich wie $(local-intermediates-dir) und $(intermediates-dir-for) .

Wenn eine Quelldatei in diesem dedizierten Verzeichnis generiert und von LOCAL_GENERATED_SOURCES wird, wird sie in einem Multilib-Build sowohl für 32 Bit als auch für 64 Bit erstellt.

Vorgefertigt

In einem Multilib-Build können Sie TARGET_ARCH (oder zusammen mit TARGET_2ND_ARCH ) nicht verwenden, um dem Build-System mitzuteilen, auf welche Architektur die vorgefertigte Binärdatei abzielt. 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 gewählte Architektur verwenden möchten, um den Quellpfad für die vorgefertigte Binärdatei zu berechnen, rufen $(get-prebuilt-src-arch) .

Generierung von ODEX-Dateien

Für 64-Bit-Geräte generieren wir standardmäßig sowohl 32-Bit- als auch 64-Bit-ODEX-Dateien für das Boot-Image und alle Java-Bibliotheken. Für APKs generieren wir 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 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.