Kompilieren mit Jack (AOSP 6.0 - 8.1)

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

Jack war eine Android-Toolchain, mit der Java-Quellcode in Android-DEX-Bytecode kompiliert wurde. 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, in der Jack verwendet wird.

Über Jack

Die Buchse funktioniert wie in Abbildung 1 dargestellt.

Übersicht über die Buchsen.

Abbildung 1. Übersicht über die Buchsen.

Jack-Bibliotheksformat

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

Inhalt der Jack-Bibliotheksdatei.

Abbildung 2: Inhalt der Jack-Bibliotheksdatei.

Jule

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 übernimmt folgende Aufgaben:

  • Dies führt zu einer intrinsischen Beschleunigung, da bei jeder Kompilierung das Starten einer neuen Host-JRE-JVM, das Laden von Jack-Code, das Initialisieren von Jack und das Aufwärmen des JIT vermieden werden. Außerdem bietet es sehr gute Kompilierungszeiten bei kleinen Kompilierungen (z. B. im inkrementellen Modus).
  • Ist eine kurzfristige Lösung, um die Anzahl der parallelen Jack-Kompilierungen zu steuern. Der Server vermeidet eine Überlastung Ihres Computers (Speicher- oder Festplattenproblem), da er die Anzahl der parallelen Kompilierungen begrenzt.

Der Jack-Server wird nach einer Leerlaufzeit ohne Kompilierung automatisch heruntergefahren. Es verwendet zwei TCP-Ports auf der localhost-Schnittstelle und ist nicht extern verfügbar. Alle Parameter (Anzahl der parallelen Kompilierungen, Zeitlimit, 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.
  • Mit SERVER_PORT_SERVICE=8072 wird die TCP-Portnummer des Servers für die Kompilierung festgelegt.
  • Mit SERVER_PORT_ADMIN=8073 wird die TCP-Portnummer des Servers für Verwaltungszwecke festgelegt.
  • SERVER_COUNT=1 wird nicht verwendet.
  • Mit SERVER_NB_COMPILE=4 wird die maximale Anzahl der zulässigen parallelen Kompilierungen festgelegt. SERVER_TIMEOUT=60 legt die Anzahl der Sekunden fest, die der Server ohne Kompilierung warten muss, bevor er sich selbst herunterfährt. Mit SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} wird die Datei festgelegt, in die Serverlogs geschrieben werden. Standardmäßig kann diese Variable durch eine Umgebungsvariable überschrieben werden.
  • Mit JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} wird der Standardbefehl festgelegt, der zum Starten einer JVM auf dem Host verwendet wird. Standardmäßig kann diese Variable durch eine Umgebungsvariable überschrieben werden.

Fehlerbehebung bei Jack-Zusammenstellungen

Problem Aktion
Ihr Computer reagiert während der Kompilierung nicht mehr oder Jack-Kompilierungen schlagen mit dem Fehler „Out of memory“ fehl. Reduzieren Sie die Anzahl der gleichzeitigen Jack-Kompilierungen, indem Sie $HOME/.jack bearbeiten und SERVER_NB_COMPILE in einen niedrigeren Wert ändern.
Kompilierungen schlagen mit der Fehlermeldung Cannot launch background server fehl Die wahrscheinlichste Ursache ist, dass TCP-Ports auf Ihrem Computer bereits verwendet werden. Sie können die Ports ändern, indem Sie $HOME/.jack bearbeiten (Variablen SERVER_PORT_SERVICE und SERVER_PORT_ADMIN). Um die Situation zu entblocken, deaktivieren Sie den Jack-Kompilierungsserver, indem Sie $HOME/.jack bearbeiten und SERVER in false ändern. Leider wird dadurch die Kompilierung erheblich verlangsamt und Sie müssen make -j möglicherweise mit der Laststeuerung starten (Option -l von make).
Kompilierung bleibt ohne Fortschritt hängen Um die Situation zu beheben, beenden Sie den Jack-Hintergrundserver mit jack-admin kill-server und entfernen Sie dann die temporären Verzeichnisse in jack-$USER Ihres temporären Verzeichnisses (/tmp oder $TMPDIR).

Jack-Log suchen

Wenn Sie einen make-Befehl mit einem Ziel für die Verteilung ausgeführt haben, befindet sich das Jack-Log unter $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. Andernfalls können Sie das Log durch Ausführen von jack-admin server-log aufrufen. Bei reproduzierbaren Jack-Fehlern können Sie ein detaillierteres Log 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-Logs zu entfernen:

unset ANDROID_JACK_EXTRA_ARGS

Einschränkungen bei der Kopfhörerbuchse

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 in $HOME/.jack festlegen. Die CTS-Kompilierung ist aufgrund der aktuellen vm-tests-tf-Integration langsam. Tools zur Bytecode-Manipulation wie JaCoCo werden nicht unterstützt.

Jack verwenden

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

Predex

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

Jack-Bibliotheken mit vorab ausgeführter Dex-Kompilierung.

Abbildung 4: Jack-Bibliotheken mit vorab ausgeführter Dex-Kompilierung.

Jack verwendet die Bibliothek nicht vorab in DEX-Format, wenn Shrinking, Verschleierung oder Umpacken bei der Kompilierung 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 deutlich schneller sein als eine vollständige Kompilierung, wenn sich die Änderungen auf eine Reihe von Komponenten beschränken.

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

LOCAL_JACK_ENABLED := incremental

Verkürzung und Verschleierung

Jack verwendet ProGuard-Konfigurationsdateien, um das Verkleinern und Verschleiern zu aktivieren.

Gängige Optionen:

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

Folgende Optionen stehen zur Verfügung:

  • -dontshrink

Folgende Optionen stehen zur Verfügung:

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

Folgende Optionen werden ignoriert:

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

Neuaufbereitung

Jack verwendet jarjar-Konfigurationsdateien für das Umpacken. Jack ist mit Regeltypen vom Typ „rule“ kompatibel, nicht jedoch mit Regeltypen vom Typ „zap“ oder „keep“.

Multidex-Unterstützung

Jack bietet integrierte und Legacy-Multidex-Unterstützung. Da DEX-Dateien auf 65.000 Methoden begrenzt 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 mehr als 64.000 Methoden aktivieren.