Kompilowanie z użyciem wtyczki Jack (AOSP 6.0–8.1)

Jack to domyślny łańcuch narzędzi do kompilacji Androida w wersjach 6.0–8.1.

Jack to łańcuch narzędzi Androida, który kompilował kod źródłowy Java do kodu bajtowego dex Androida. Aby korzystać z Jacka, nie musisz niczego zmieniać – wystarczy użyć standardowych poleceń makefile do skompilowania drzewa lub projektu. Android 8.1 to ostatnia wersja, która korzysta z kompilatora Jack.

O Jacku

Gniazdo działa tak, jak pokazano na rysunku 1.

Omówienie gniazda.

Rysunek 1. Omówienie gniazda.

Format biblioteki Jack

Jack ma własny .jack format pliku, który zawiera wstępnie skompilowany kod dex biblioteki, co umożliwia szybszą kompilację (pre-dex).

Zawartość pliku biblioteki Jack.

Rysunek 2. Zawartość pliku biblioteki Jack.

Jill

Jak pokazano na ilustracji poniżej, narzędzie Jill tłumaczy istniejące biblioteki.jar na nowy format biblioteki.

Proces importowania istniejącej biblioteki „jar”.

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

Serwer kompilacji Jacka

Przy pierwszym użyciu narzędzia Jack uruchamia ono na komputerze lokalny serwer kompilacji Jack. Ten serwer:

  • Zapewnia to znaczne przyspieszenie, ponieważ przy każdej kompilacji nie trzeba uruchamiać nowej maszyny JVM JRE hosta, wczytywać kodu Jacka, inicjować Jacka ani rozgrzewać kompilatora JIT. Zapewnia też bardzo dobre czasy kompilacji w przypadku małych kompilacji (np. w trybie przyrostowym).
  • Jest to rozwiązanie krótkoterminowe, które pozwala kontrolować liczbę równoległych kompilacji Jacka. Serwer unika przeciążenia komputera (problem z pamięcią lub dyskiem), ponieważ ogranicza liczbę równoległych kompilacji.

Serwer Jack wyłącza się po okresie bezczynności, w którym nie przeprowadzono żadnej kompilacji. Korzysta z 2 portów TCP w interfejsie hosta lokalnego i nie jest dostępny zewnętrznie. Wszystkie parametry (liczba równoległych kompilacji, limit czasu, numer portu itp.) 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 do celów administracyjnych.
  • SERVER_COUNT=1 nie jest używany.
  • SERVER_NB_COMPILE=4 określa maksymalną liczbę dozwolonych kompilacji równoległych. SERVER_TIMEOUT=60 określa liczbę sekund bezczynności, przez które serwer musi czekać bez kompilacji, zanim się wyłączy. SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} określa plik, w którym zapisywane są dzienniki 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 Jacka

Problem Działanie
komputer przestaje odpowiadać podczas kompilacji lub kompilacje Jacka kończą się niepowodzeniem z powodu błędu braku pamięci; Zmniejsz liczbę jednoczesnych kompilacji Jacka, edytując $HOME/.jack i zmieniając SERVER_NB_COMPILE na mniejszą wartość.
Kompilacje kończą się niepowodzeniem z powodu błędu Nie można uruchomić serwera w tle Najprawdopodobniej przyczyną jest to, że porty TCP są już używane na Twoim komputerze. Zmień porty, edytując zmienne $HOME/.jack (SERVER_PORT_SERVICESERVER_PORT_ADMIN). Aby odblokować sytuację, wyłącz serwer kompilacji Jacka, edytując plik $HOME/.jack i zmieniając SERVER na false. Niestety znacznie spowalnia to kompilację i może wymusić uruchomienie make -j z kontrolą obciążenia (opcja -lmake).
Kompilacja zawiesza się bez postępu Aby rozwiązać ten problem, zatrzymaj serwer w tle Jacka, używając polecenia jack-admin kill-server, a następnie usuń katalogi tymczasowe znajdujące się w katalogu jack-$USER w katalogu tymczasowym (/tmp lub $TMPDIR).

Znajdź log Jacka

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

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

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

unset ANDROID_JACK_EXTRA_ARGS

Ograniczenia dotyczące gniazd

Domyślnie serwer Jack może być używany tylko przez jednego użytkownika na komputerze. Aby obsługiwać dodatkowych użytkowników, wybierz różne numery portów dla każdego z nich i odpowiednio dostosuj SERVER_NB_COMPILE. Serwer Jack możesz też wyłączyć, 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.

Korzystanie z Jacka

Jack obsługuje język programowania Java 1.7 i integruje dodatkowe funkcje opisane poniżej.

Pre-dex

Podczas generowania pliku biblioteki Jack generowany jest .dex biblioteki i zapisywany w pliku biblioteki .jack jako wstępnie zindeksowany plik DEX. Podczas kompilacji Jack ponownie wykorzystuje plik pre-dex z każdej biblioteki. Wszystkie biblioteki są wstępnie indeksowane.

Biblioteki Jack z wstępnie zindeksowanymi plikami DEX.

Rysunek 4. Biblioteki Jack z wstępnie zindeksowanymi plikami DEX.

Jack nie używa ponownie wstępnie skompilowanej biblioteki, jeśli w kompilacji używane jest zmniejszanie, zaciemnianie lub ponowne pakowanie.

Kompilacja przyrostowa

Kompilacja przyrostowa oznacza, że ponownie kompilowane są tylko komponenty, które zostały zmienione od czasu ostatniej kompilacji (oraz 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 automatycznie dezaktywowana, gdy włączone jest zmniejszanie, zaciemnianie, ponowne pakowanie lub starsza wersja multi-dex). Aby włączyć przyrostowe kompilacje, dodaj ten wiersz do pliku Android.mk projektu, który chcesz kompilować przyrostowo:

LOCAL_JACK_ENABLED := incremental

Kompresowanie i zaciemnianie

Jack używa plików konfiguracji ProGuard, aby włączyć zmniejszanie i zaciemnianie.

Najczęstsze opcje to:

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

Opcje zmniejszania obejmują:

  • -dontshrink

Opcje zaciemniania obejmują:

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

Ignorowane opcje to:

  • -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

Jack używa plików konfiguracji jarjar do ponownego pakowania. Jack jest zgodny z typami reguł „rule”, ale nie z typami „zap” ani „keep”.

Obsługa multidexu

Jack oferuje wbudowaną i starszą obsługę multidexu. Pliki DEX są ograniczone do 65 tys. metod, więc aplikacje z większą liczbą metod muszą być podzielone na kilka plików DEX. Więcej informacji znajdziesz w artykule Włączanie multidexu w przypadku aplikacji z ponad 64 tys. metod.