Compilazione con Jack (AOSP 6.0 - 8.1)

Jack è la toolchain di build Android predefinita per Android 6.0 - 8.1

Jack è una toolchain Android che ha compilato il codice sorgente Java nel bytecode dex di Android. Non devi fare nulla di diverso per usare Jack: usa semplicemente i comandi makefile standard per compilare l'albero o il tuo progetto. Android 8.1 è l'ultima versione che utilizza Jack.

A proposito di Jack

Jack funziona come mostrato nella Figura 1.

Panoramica di Jack.

Figura 1. Panoramica del jack.

Formato della libreria Jack

Jack ha il proprio formato file .jack che contiene il codice dex precompilato per la libreria, consentendo una compilazione più rapida (pre-dex).

Contenuto del file della libreria Jack.

Figura 2. Contenuto del file della libreria Jack.

Jill

Come mostrato nella figura seguente, lo strumento Jill traduce le librerie .jar esistenti nel nuovo formato di libreria.

Flusso di lavoro per importare una libreria `jar.` esistente.

Figura 3. Flusso di lavoro per importare una libreria .jar esistente.

Server di compilazione Jack

La prima volta che si utilizza Jack, viene avviato un server di compilazione Jack locale sul computer. Questo server:

  • Apporta una velocità intrinseca perché evita di avviare una nuova JVM JRE host, caricare il codice Jack, inizializzare Jack e riscaldare JIT ad ogni compilazione. Fornisce anche tempi di compilazione molto buoni durante le piccole compilazioni (ad esempio, in modalità incrementale).
  • È una soluzione a breve termine per controllare il numero di compilazioni Jack parallele. Il server evita di sovraccaricare il computer (problemi di memoria o disco) perché limita il numero di compilazioni parallele.

Il server Jack si spegne dopo un periodo di inattività senza alcuna compilazione. Utilizza due porte TCP sull'interfaccia localhost e non è disponibile esternamente. Tutti i parametri (numero di compilazioni parallele, timeout, numero di porte, ecc.) possono essere modificati modificando il file $HOME/.jack .

$HOME/.jack

Il file $HOME/.jack contiene le seguenti impostazioni per le variabili del server Jack in una sintassi bash completa:

  • SERVER=true abilita la funzionalità server di Jack.
  • SERVER_PORT_SERVICE=8072 imposta il numero di porta TCP del server per scopi di compilazione.
  • SERVER_PORT_ADMIN=8073 imposta il numero di porta TCP del server per scopi amministrativi.
  • SERVER_COUNT=1 non è utilizzato.
  • SERVER_NB_COMPILE=4 imposta il numero massimo di compilazioni parallele consentite. SERVER_TIMEOUT=60 imposta il numero di secondi di inattività che il server deve attendere senza alcuna compilazione prima di spegnersi. SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} imposta il file in cui vengono scritti i log del server. Per impostazione predefinita, questa variabile può essere sovraccaricata da una variabile di ambiente.
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} imposta il comando predefinito utilizzato per avviare una JVM sull'host. Per impostazione predefinita, questa variabile può essere sovraccaricata dalla variabile di ambiente.

Risoluzione dei problemi relativi alle compilazioni Jack

Problema Azione
Il computer non risponde durante la compilazione oppure si verifica un errore di compilazione Jack a causa di memoria esaurita Ridurre il numero di compilazioni Jack simultanee modificando $HOME/.jack e cambiando SERVER_NB_COMPILE su un valore inferiore.
Le compilazioni non riescono su Impossibile avviare il server in background La causa più probabile è che le porte TCP siano già utilizzate sul tuo computer. Cambia le porte modificando $HOME/.jack (variabili SERVER_PORT_SERVICE e SERVER_PORT_ADMIN ). Per sbloccare la situazione, disabilitare il server di compilazione Jack modificando $HOME/.jack e cambiando SERVER in false . Sfortunatamente questo rallenta notevolmente la compilazione e potrebbe costringerti a lanciare make -j con il controllo del carico (opzione -l di make ).
La compilazione si blocca senza alcun progresso Per sbloccare la situazione, killa il server in background di Jack utilizzando jack-admin kill-server ) quindi rimuovi le directory temporanee contenute in jack-$USER della tua directory temporanea ( /tmp o $TMPDIR ).

Trovare il registro di Jack

Se hai eseguito un comando make con una destinazione dist, il log di Jack si trova in $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log . Altrimenti, puoi trovare il log eseguendo jack-admin server-log . In caso di guasti Jack riproducibili, è possibile ottenere un registro più dettagliato impostando la seguente variabile:

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

Utilizza i comandi makefile standard per compilare l'albero (o il tuo progetto) e allegare output ed errore standard. Per rimuovere i log di build dettagliati, esegui:

unset ANDROID_JACK_EXTRA_ARGS

Limitazioni di Jack

  • Per impostazione predefinita, il server Jack può essere utilizzato da un solo utente su un computer. Per supportare utenti aggiuntivi, seleziona numeri di porta diversi per ciascun utente e modifica SERVER_NB_COMPILE di conseguenza. Puoi anche disabilitare il server Jack impostando SERVER=false in $HOME/.jack . La compilazione CTS è lenta a causa dell'attuale integrazione vm-tests-tf . Gli strumenti di manipolazione del bytecode (come JaCoCo) non sono supportati.

Usando Jack

Jack supporta il linguaggio di programmazione Java 1.7 e integra le funzionalità aggiuntive descritte di seguito.

Pre-dexing

Quando si genera un file di libreria Jack, il .dex della libreria viene generato e archiviato all'interno del file di libreria .jack come pre-dex. Durante la compilazione, Jack riutilizza il pre-dex di ciascuna libreria. Tutte le librerie sono predexizzate.

Librerie Jack con pre-dex.

Figura 4. Librerie Jack con pre-dex.

Jack non riutilizza il pre-dex della libreria se nella compilazione vengono utilizzati la riduzione, l'offuscamento o il riconfezionamento.

Compilazione incrementale

Compilazione incrementale significa che vengono ricompilati solo i componenti toccati dall'ultima compilazione (e le relative dipendenze). La compilazione incrementale può essere notevolmente più veloce di una compilazione completa quando le modifiche sono limitate a un insieme di componenti.

La compilazione incrementale è disabilitata per impostazione predefinita (e viene automaticamente disattivata quando sono abilitati la riduzione, l'offuscamento, il riconfezionamento o l'eredità multi-dex). Per abilitare le build incrementali, aggiungi la seguente riga al file Android.mk del progetto che desideri creare in modo incrementale:

LOCAL_JACK_ENABLED := incremental

Restringimento e offuscamento

Jack utilizza i file di configurazione ProGuard per consentire la riduzione e l'offuscamento.

Le opzioni comuni includono quanto segue:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (supportato solo 1 jar di output)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

Le opzioni di restringimento includono quanto segue:

  • -dontshrink

Le opzioni di offuscamento includono quanto segue:

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

Le opzioni ignorate includono quanto segue:

  • -dontoptimize (Jack non ottimizza)
  • -dontpreverify (Jack non preverifica)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

Riconfezionamento

Jack utilizza i file di configurazione jarjar per eseguire il riconfezionamento. Sebbene Jack sia compatibile con i tipi di regole "regola", non è compatibile con i tipi di regole "zap" o "mantieni".

Supporto multidex

Jack offre supporto multidex integrato e legacy. Poiché i file dex sono limitati a metodi da 65.000, le app con metodi superiori a 65.000 devono essere suddivise in più file dex. Per ulteriori dettagli, consulta Abilitare il multidex per le app con metodi superiori a 64K