Kompilowanie za pomocą narzędzia Jack

Jack był domyślnym łańcuchem narzędzi do kompilowania Androida w wersjach 6.0–8.1. Służył do kompilowania kodu źródłowego Java do kodu bajtowego Androida dex, jak pokazano na ilustracji 1:

Omówienie gniazda.

Ilustracja 1. Omówienie narzędzia Jack.

Format pliku .jack zawiera wstępnie skompilowany kod dex biblioteki, co przyspiesza kompilację (wstępna kompilacja dex).

Zawartość pliku biblioteki Jack.

Ilustracja 2. Zawartość pliku biblioteki Jack.

Narzędzie Jill

Narzędzie Jill tłumaczy istniejące biblioteki .jar na nowy format biblioteki .jack, jak pokazano na ilustracji 3:

Proces importowania istniejącej biblioteki „jar”.

Ilustracja 3. Proces importowania istniejącej biblioteki .jar.

Serwer kompilacji Jack

Gdy używasz narzędzia Jack po raz pierwszy, uruchamia ono na Twoim komputerze lokalny serwer kompilacji Jack. Ten serwer:

  • przyspiesza działanie, ponieważ unika uruchamiania nowej maszyny JVM hosta JRE, wczytywania kodu Jack, inicjowania Jack i rozgrzewania JIT przy każdej kompilacji. Zapewnia też bardzo dobre czasy kompilacji podczas małych kompilacji (np. w trybie przyrostowym).
  • jest rozwiązaniem krótkoterminowym, które pozwala kontrolować liczbę równoległych kompilacji Jack. Serwer unika przeciążenia komputera (problemów z pamięcią lub dyskiem), ponieważ ogranicza liczbę równoległych kompilacji.

Serwer Jack wyłącza się po upływie czasu bezczynności bez kompilacji. Używa 2 portów TCP w interfejsie localhost i nie jest dostępny z zewnątrz. Wszystkie parametry (np. liczba równoległych kompilacji, limit czasu i numery portów) można modyfikować, edytując plik $HOME/.jack.

Plik $HOME/.jack

Plik $HOME/.jack zawiera te ustawienia zmiennych serwera Jack w pełnej składni bash:

  • SERVER=true włącza funkcję serwera Jack.
  • SERVER_PORT_SERVICE=8072 ustawia numer portu TCP serwera na potrzeby kompilacji.
  • SERVER_PORT_ADMIN=8073 ustawia numer portu TCP serwera na potrzeby administracji.
  • SERVER_COUNT=1 jest nieużywane.
  • SERVER_NB_COMPILE=4 ustawia maksymalną liczbę dozwolonych równoległych kompilacji. SERVER_TIMEOUT=60 ustawia liczbę sekund bezczynności, po których serwer musi poczekać bez kompilacji, zanim się wyłączy. SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} ustawia plik, w którym zapisywane są logi serwera. Domyślnie tę zmienną można zastąpić zmienną środowiskową.
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} ustawia domyślne polecenie używane do uruchamiania maszyny JVM na hoście. Domyślnie tę zmienną można zastąpić zmienną środowiskową.

Rozwiązywanie problemów z kompilacjami Jack

Problem Działanie
Podczas kompilacji komputer przestaje odpowiadać lub kompilacje Jack kończą się niepowodzeniem z powodu błędu braku pamięci. Zmniejsz liczbę jednoczesnych kompilacji Jack, edytując plik $HOME/.jack i zmieniając wartość SERVER_NB_COMPILE na mniejszą.
Kompilacje kończą się niepowodzeniem z powodu nie można uruchomić serwera w tle. Najprawdopodobniej porty TCP są już używane na Twoim komputerze. Zmień porty, edytując plik $HOME/.jack (zmienne SERVER_PORT_SERVICE i SERVER_PORT_ADMIN). Aby odblokować sytuację, wyłącz serwer kompilacji Jack, edytując $HOME/.jack i zmieniając SERVER na false. Niestety znacznie spowolni to kompilację i może zmusić Cię do uruchomienia make -j z kontrolą obciążenia (opcja -l polecenia make).
Kompilacja zawiesza się bez postępu. Aby odblokować sytuację, zatrzymaj serwer w tle Jack za pomocą polecenia jack-admin kill-server, a następnie usuń katalogi tymczasowe znajdujące się w katalogu tymczasowym (/tmp lub $TMPDIR) w katalogu jack-$USER.

Znajdowanie logu Jack

Jeśli polecenie make zostało uruchomione z celem dist, log Jack znajduje się w lokalizacji $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. W przeciwnym razie log można znaleźć, uruchamiając polecenie jack-admin server-log. W przypadku powtarzających się błędów Jack możesz uzyskać bardziej szczegółowy log, ustawiając tę zmienną:

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

Użyj standardowych poleceń makefile, aby skompilować drzewo (lub projekt) i dołączyć standardowe dane wyjściowe oraz błędy. Aby usunąć szczegółowe logi kompilacji, uruchom:

unset ANDROID_JACK_EXTRA_ARGS

Ograniczenia narzędzia Jack

Domyślnie serwer Jack może być używany tylko przez 1 użytkownika na komputerze. Aby obsługiwać dodatkowych użytkowników, wybierz różne numery portów dla każdego użytkownika i odpowiednio dostosuj wartość SERVER_NB_COMPILE. Możesz też wyłączyć serwer Jack, ustawiając wartość SERVER=false w pliku $HOME/.jack. Kompilacja CTS jest powolna z powodu bieżącej integracji vm-tests-tf. Narzędzia do manipulowania kodem bajtowym (np. JaCoCo) nie są obsługiwane.

Używanie narzędzia Jack

Narzędzie Jack obsługuje język programowania Java 1.7 i integruje dodatkowe funkcje opisane w tej sekcji. Użyj standardowych poleceń makefile, aby skompilować drzewo lub projekt.

Wstępna kompilacja dex

Podczas generowania pliku biblioteki Jack plik .dex biblioteki jest generowany i przechowywany w pliku biblioteki .jack jako wstępnie skompilowany plik dex. Podczas kompilacji narzędzie Jack ponownie używa wstępnie skompilowanego pliku dex z każdej biblioteki. Wszystkie biblioteki są wstępnie kompilowane do formatu dex.

Biblioteki Jack z wstępnie skompilowanym kodem dex.

Ilustracja 4. Biblioteki Jack ze wstępnie skompilowanym plikiem dex.

Narzędzie Jack nie używa wstępnie skompilowanego pliku dex biblioteki, jeśli w kompilacji używane jest zmniejszanie, zaciemnianie lub przepakowywanie.

Kompilacja przyrostowa

Kompilacja przyrostowa oznacza, że kompilowane są tylko te komponenty, które zostały zmienione od czasu ostatniej kompilacji (i ich zależności). Kompilacja przyrostowa może być znacznie szybsza niż pełna kompilacja, gdy zmiany są ograniczone do zestawu komponentów.

Kompilacja przyrostowa jest domyślnie wyłączona (i jest automatycznie dezaktywowana, gdy włączone jest zmniejszanie, zaciemnianie, przepakowywanie lub starsza wersja multidex). Aby włączyć kompilacje przyrostowe, dodaj ten wiersz do pliku Android.mk projektu, który chcesz skompilować przyrostowo:

LOCAL_JACK_ENABLED := incremental

Zmniejszanie i zaciemnianie

Narzędzie Jack używa plików konfiguracji ProGuard, aby włączyć zmniejszanie i zaciemnianie. Typowe opcje:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (obsługiwany jest tylko 1 wyjściowy plik jar)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

Opcje zmniejszania:

  • -dontshrink

Opcje zaciemniania:

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

Ignorowane opcje:

  • -dontoptimize (Jack nie optymalizuje)
  • -dontpreverify (Jack nie przeprowadza wstępnej weryfikacji)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

Przepakowywanie

Narzędzie Jack używa plików konfiguracji jarjar do przepakowywania. Narzędzie Jack jest zgodne z typami reguł rule, ale nie jest zgodne z typami reguł zap ani keep.

Obsługa multidex

Narzędzie Jack oferuje wbudowaną i starszą obsługę multidex. Ponieważ pliki dex są ograniczone do 65 tys. metod, aplikacje z ponad 65 tys. metod muszą być podzielone na kilka plików dex. Więcej informacji znajdziesz w artykule Włączanie multidex w aplikacjach z ponad 64 tys. metod.