Kompilieren mit Jack (AOSP 6.0 - 8.1)

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

Jack ist eine Android-Toolchain, die Java-Quellcode in Android-Dex-Bytecode kompiliert. Sie müssen nichts weiter tun, um Jack zu verwenden. Verwenden Sie einfach die Standardbefehle für das Makefile, 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 dargestellt.

Übersicht über Jack

Abbildung 1: Übersicht über Jack

Jack-Bibliotheksformat

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

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:

  • Ermöglicht eine inhärente Beschleunigung, da das Starten einer neuen JRE-JVM des Hosts, das Laden von Jack-Code, die Initialisierung von Jack und das Vorwärmen des JIT bei jeder Kompilierung vermieden wird. Außerdem bietet es sehr gute Kompilierungszeiten bei kleinen Kompilationen (z. B. im Inkrementellen Modus).
  • Dies ist eine kurzfristige Lösung, um die Anzahl der parallelen Jack-Kompilierungen zu steuern. Der Server verhindert eine Überlastung Ihres Computers (Speicher- oder Laufwerkproblem), da die Anzahl der parallelen Kompilierungen begrenzt wird.

Der Jack-Server wird nach einer Inaktivitätszeit ohne Kompilierung heruntergefahren. Es verwendet zwei TCP-Ports auf der localhost-Schnittstelle und ist nicht extern verfügbar. Alle Parameter (Anzahl der parallelen Kompilierungen, Zeitlimit, Anzahl der Ports usw.) können durch Bearbeiten der Datei $HOME/.jack geändert werden.

Datei $HOME/.jack

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 die Kompilierung fest.
  • SERVER_PORT_ADMIN=8073 legt die TCP-Portnummer des Servers zu administrativen Zwecken fest.
  • SERVER_COUNT=1 wird nicht verwendet.
  • Mit SERVER_NB_COMPILE=4 wird die maximale Anzahl der zulässigen parallelen Kompilierungen festgelegt. Mit SERVER_TIMEOUT=60 wird festgelegt, wie lange der Server inaktiv bleiben muss, ohne dass eine Kompilierung erfolgt, bevor er heruntergefahren wird. 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.
  • Mit JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} wird der Standardbefehl festgelegt, mit dem eine JVM auf dem Host gestartet wird. Standardmäßig kann diese Variable durch eine Umgebungsvariable überladen werden.

Fehlerbehebung bei Jack-Kompilationen

Problem Aktion
Ihr Computer reagiert während der Kompilierung nicht mehr oder Jack-Kompilierungen schlagen mit dem Fehler „Nicht genügend Arbeitsspeicher“ fehl. Du kannst die Anzahl der gleichzeitigen Jack-Kompilationen reduzieren, indem du $HOME/.jack bearbeitest und SERVER_NB_COMPILE in einen niedrigeren Wert änderst.
Kompilierungen schlagen fehl, weil Cannot launch background server (Hintergrundserver kann nicht gestartet werden) Die wahrscheinlichste Ursache ist, dass TCP-Ports bereits auf Ihrem Computer verwendet werden. Ändern Sie Berichte, indem Sie $HOME/.jack (SERVER_PORT_SERVICE- und SERVER_PORT_ADMIN-Variablen) bearbeiten. Deaktiviere den Jack-Kompilierungsserver, indem du $HOME/.jack bearbeitest und SERVER in false änderst. Leider wird dadurch die Kompilierung erheblich verlangsamt und Sie müssen make -j möglicherweise mit Laststeuerung starten (Option -l von make).
Die Kompilierung bleibt hängen, ohne dass es zu einem Fortschritt kommt Beenden Sie den Jack-Hintergrundserver mit jack-admin kill-server und entfernen Sie dann die temporären Verzeichnisse, die sich in jack-$USER Ihres temporären Verzeichnisses (/tmp oder $TMPDIR) befinden.

Jack-Protokoll finden

Wenn Sie einen make-Befehl mit dem Ziel „dist“ ausgeführt haben, befindet sich das Jack-Protokoll unter $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. Andernfalls können Sie das Protokoll durch Ausführen von jack-admin server-log aufrufen. Bei reproduzierbaren Jack-Fehlern können Sie ein detaillierteres Protokoll abrufen, indem Sie die folgende Variable festlegen:

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

Verwenden Sie standardmäßige Makefile-Befehle, um den Baum (oder Ihr Projekt) zu kompilieren und Standardausgabe und -fehler anzuhängen. Führen Sie folgenden Befehl aus, um detaillierte Build-Logs zu entfernen:

unset ANDROID_JACK_EXTRA_ARGS

Einschränkungen für Steckdosen

Standardmäßig kann der Jack-Server nur von einem Nutzer auf einem Computer verwendet werden. Wenn Sie zusätzliche Nutzer unterstützen möchten, wählen Sie für jeden Nutzer unterschiedliche Portnummern aus und passen Sie SERVER_NB_COMPILE entsprechend an. Sie können den Jack-Server auch deaktivieren, indem Sie SERVER=false auf $HOME/.jack setzen. Die CTS-Kompilierung ist aufgrund der aktuellen vm-tests-tf-Integration langsam. Tools zur Bytecode-Manipulation (z. B. JaCoCo) werden nicht unterstützt.

Jack verwenden

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

Predexing

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

Jack-Bibliotheken mit Pre-Dex

Abbildung 4: Jack-Bibliotheken mit Pre-Dex

Jack verwendet die Bibliothek nicht vor dem DeX, wenn bei der Kompilierung Schrumpfen, Verschleierung oder Umverpackung verwendet wird.

Inkrementelle Kompilierung

Bei der inkrementellen Kompilierung werden nur die Komponenten, die seit der letzten Kompilierung geändert wurden, und ihre Abhängigkeiten neu kompiliert. 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 das Schrumpfen, Verschleierung, Umpacken oder die alte Multi-Dex-Funktion aktiviert ist. Wenn Sie inkrementelle Builds aktivieren möchten, fügen Sie der Android.mk-Datei des Projekts, das Sie inkrementell erstellen möchten, die folgende Zeile hinzu:

LOCAL_JACK_ENABLED := incremental

Verkürzung und Verschleierung

Jack verwendet ProGuard-Konfigurationsdateien, um das Schrumpfen und die Verschleierung zu aktivieren.

Gängige Optionen:

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

Folgende Optionen stehen zur Verfügung:

  • -dontshrink

Zu den Optionen für die Verschleierung gehören:

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

Zu den ignorierten Optionen gehören:

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

Neu verpacken

Jack verwendet JarJar-Konfigurationsdateien für das Umpacken. Jack ist mit Regeltypen vom Typ „Regel“ kompatibel, aber nicht mit „Überspringen“ oder „Behalten“.

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 Informationen finden Sie unter Multidex für Apps mit über 64.000 Methoden aktivieren.