Kompilieren mit Jack (AOSP 6.0 - 8.1)

Jack ist die Standard-Android-Build-Toolchain für Android 6.0–8.1

Jack ist eine Android-Toolchain, die Java-Quellen in Android-Dex-Bytecode kompiliert. Sie müssen nichts anders machen, um Jack zu verwenden – verwenden Sie einfach Ihre Standard-Makefile-Befehle, um den Baum oder Ihr Projekt zu kompilieren. Android 8.1 ist die letzte Version, die Jack verwendet.

Über Jack

Jack funktioniert wie in Abbildung 1 gezeigt.

Jack-Übersicht.

Abbildung 1. Jack-Übersicht.

Jack-Bibliotheksformat

Jack verfügt über ein eigenes .jack Dateiformat, das den vorkompilierten Dex-Code für die Bibliothek enthält und so eine schnellere Kompilierung (Pre-Dex) ermöglicht.

Inhalt der Jack-Bibliotheksdatei.

Abbildung 2. Inhalt der Jack-Bibliotheksdatei.

Jill

Wie in der folgenden Abbildung dargestellt, übersetzt das Jill-Tool die vorhandenen .jar Bibliotheken in das neue Bibliotheksformat.

Workflow zum Importieren einer vorhandenen „jar.“-Bibliothek.

Abbildung 3. Workflow zum Importieren einer vorhandenen .jar Bibliothek.

Jack-Kompilierungsserver

Wenn Jack zum ersten Mal verwendet wird, wird ein lokaler Jack-Kompilierungsserver auf Ihrem Computer gestartet. Dieser Server:

  • Bringt eine intrinsische Beschleunigung mit sich, da das Starten einer neuen Host-JRE-JVM, das Laden von Jack-Code, die Initialisierung von Jack und das Aufwärmen der JIT bei jeder Kompilierung entfallen. Es bietet auch sehr gute Kompilierungszeiten bei kleinen Kompilierungen (z. B. im inkrementellen Modus).
  • Ist eine kurzfristige Lösung zur Kontrolle der Anzahl paralleler Jack-Zusammenstellungen. Der Server verhindert eine Überlastung Ihres Computers (Speicher- oder Festplattenproblem), da er die Anzahl paralleler Kompilierungen begrenzt.

Der Jack-Server schaltet sich nach einer Leerlaufzeit ohne Kompilierung selbst ab. Es verwendet zwei TCP-Ports auf der Localhost-Schnittstelle und ist extern nicht verfügbar. Alle Parameter (Anzahl paralleler Kompilierungen, Timeout, Portnummer usw.) können durch Bearbeiten der Datei $HOME/.jack geändert werden.

$HOME/.jack-Datei

Die Datei $HOME/.jack enthält die folgenden Einstellungen für Jack-Servervariablen in einer vollständigen Bash-Syntax:

  • SERVER=true aktiviert die Serverfunktion von Jack.
  • SERVER_PORT_SERVICE=8072 legt die TCP-Portnummer des Servers für Kompilierungszwecke fest.
  • SERVER_PORT_ADMIN=8073 legt die TCP-Portnummer des Servers für Verwaltungszwecke fest.
  • SERVER_COUNT=1 ist unbenutzt.
  • SERVER_NB_COMPILE=4 legt die maximale Anzahl zulässiger paralleler Kompilierungen fest. SERVER_TIMEOUT=60 legt die Anzahl der Leerlaufsekunden fest, die der Server ohne Kompilierung warten muss, bevor er sich selbst herunterfährt. SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} legt die Datei fest, in die Serverprotokolle geschrieben werden. Standardmäßig kann diese Variable durch eine Umgebungsvariable überladen werden.
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} legt den Standardbefehl fest, der zum Starten einer JVM auf dem Host verwendet wird. Standardmäßig kann diese Variable durch Umgebungsvariable überladen werden.

Fehlerbehebung bei Jack-Zusammenstellungen

Problem Aktion
Ihr Computer reagiert während der Kompilierung nicht mehr oder es kommt zu einem Fehler bei der Kompilierung von Jack aufgrund von „Nicht genügend Arbeitsspeicher“. Reduzieren Sie die Anzahl gleichzeitiger Jack-Kompilierungen, indem Sie $HOME/.jack bearbeiten und SERVER_NB_COMPILE auf einen niedrigeren Wert ändern.
Kompilierungen schlagen fehl, da der Hintergrundserver nicht gestartet werden kann Die wahrscheinlichste Ursache ist, dass auf Ihrem Computer bereits TCP-Ports verwendet werden. Ändern Sie Ports, indem Sie $HOME/.jack (Variablen SERVER_PORT_SERVICE und SERVER_PORT_ADMIN ) bearbeiten. Um die Situation zu entsperren, deaktivieren Sie den Jack-Kompilierungsserver, indem Sie $HOME/.jack bearbeiten und SERVER in false ändern. Leider verlangsamt dies Ihre Kompilierung erheblich und zwingt Sie möglicherweise dazu make -j mit Ladekontrolle zu starten (Option -l von make ).
Die Kompilierung bleibt ohne Fortschritt hängen Um die Situation zu entsperren, beenden Sie den Jack-Hintergrundserver mit jack-admin kill-server und entfernen Sie dann die in jack-$USER enthaltenen temporären Verzeichnisse Ihres temporären Verzeichnisses ( /tmp oder $TMPDIR ).

Das Jack-Protokoll finden

Wenn Sie einen make -Befehl mit einem dist-Ziel ausgeführt haben, befindet sich das Jack-Protokoll unter $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log . Andernfalls können Sie das Protokoll finden, indem Sie jack-admin server-log ausführen. Bei reproduzierbaren Jack-Ausfällen können Sie ein detaillierteres Protokoll erhalten, indem Sie die folgende Variable festlegen:

export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"

Verwenden Sie Standard-Makefile-Befehle, um den Baum (oder Ihr Projekt) zu kompilieren und Standardausgabe und Fehler anzuhängen. Führen Sie Folgendes aus, um detaillierte Build-Protokolle zu entfernen:

unset ANDROID_JACK_EXTRA_ARGS

Jack-Einschränkungen

  • Standardmäßig kann der Jack-Server nur von einem Benutzer auf einem Computer verwendet werden. Um zusätzliche Benutzer zu unterstützen, wählen Sie für jeden Benutzer unterschiedliche Portnummern aus und passen Sie SERVER_NB_COMPILE entsprechend an. Sie können den Jack-Server auch deaktivieren, indem Sie SERVER=false in $HOME/.jack festlegen. Die CTS-Kompilierung ist aufgrund der aktuellen vm-tests-tf Integration langsam. Bytecode-Manipulationstools (wie JaCoCo) werden nicht unterstützt.

Mit Jack

Jack unterstützt die Programmiersprache Java 1.7 und integriert die unten beschriebenen zusätzlichen Funktionen.

Vordexing

Beim Generieren einer Jack-Bibliotheksdatei wird die .dex der Bibliothek generiert und als Pre-Dex in der .jack Bibliotheksdatei gespeichert. Beim Kompilieren verwendet Jack den Pre-Dex aus jeder Bibliothek wieder. Alle Bibliotheken sind vordediziert.

Jack-Bibliotheken mit Pre-Dex.

Abbildung 4. Jack-Bibliotheken mit Pre-Dex.

Jack verwendet den Pre-Dex der Bibliothek nicht wieder, wenn bei der Kompilierung Verkleinerung, Verschleierung oder Neuverpackung verwendet wird.

Inkrementelle Kompilierung

Inkrementelle Kompilierung bedeutet, dass nur die seit der letzten Kompilierung berührten Komponenten (und ihre Abhängigkeiten) neu kompiliert werden. Die inkrementelle Kompilierung kann erheblich schneller sein als eine vollständige Kompilierung, wenn Änderungen auf eine Reihe von Komponenten beschränkt sind.

Die inkrementelle Kompilierung ist standardmäßig deaktiviert (und wird automatisch deaktiviert, wenn Verkleinerung, Verschleierung, Neuverpackung oder Multi-Dex-Legacy aktiviert ist). Um inkrementelle Builds zu aktivieren, fügen Sie die folgende Zeile zur Android.mk Datei des Projekts hinzu, das Sie inkrementell erstellen möchten:

LOCAL_JACK_ENABLED := incremental

Schrumpfung und Verschleierung

Jack verwendet ProGuard-Konfigurationsdateien, um die Verkleinerung und Verschleierung zu ermöglichen.

Zu den gängigen Optionen gehören die folgenden:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (nur 1 Ausgabe-JAR wird unterstützt)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

Zu den Schrumpfoptionen gehören die folgenden:

  • -dontshrink

Zu den Verschleierungsoptionen gehören die folgenden:

  • -dontobfuscate
  • -printmapping
  • -applymapping
  • -obfuscationdictionary
  • -classobfuscationdictionary
  • -packageobfuscationdictionary
  • -useuniqueclassmembernames
  • -dontusemixedcaseclassnames
  • -keeppackagenames
  • -flattenpackagehierarchy
  • -repackageclasses
  • -keepattributes
  • -adaptclassstrings

Zu den ignorierten Optionen gehören die folgenden:

  • -dontoptimize (Jack optimiert nicht)
  • -dontpreverify (Jack führt keine Vorverifizierung durch)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

Umpacken

Jack verwendet Jarjar-Konfigurationsdateien, um das Neupacken durchzuführen. Während Jack mit den Regeltypen „rule“ kompatibel ist, ist es nicht mit den Regeltypen „zap“ oder „keep“ kompatibel.

Multidex-Unterstützung

Jack bietet integrierte und ältere Multidex-Unterstützung. Da Dex-Dateien auf 65.000 Methoden beschränkt sind, müssen Apps mit mehr als 65.000 Methoden in mehrere Dex-Dateien aufgeteilt werden. Weitere Einzelheiten finden Sie unter Aktivieren von Multidex für Apps mit über 64.000 Methoden