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

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

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

Informacje o Jacku

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

Omówienie gniazda.

Rysunek 1. Omówienie Jacka.

Format biblioteki Jacka

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

Zawartość pliku biblioteki Jack.

Rysunek 2. Zawartość pliku biblioteki Jacka.

Jill

Jak pokazano na rysunku 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

Gdy używasz Jacka po raz pierwszy, uruchamia on na Twoim komputerze lokalny serwer kompilacji Jacka. Ten serwer:

  • Zapewnia wbudowane przyspieszenie, ponieważ unika uruchamiania nowej maszyny JVM JRE hosta, wczytywania kodu Jacka, inicjowania Jacka 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 Jacka. Serwer unika przeciążenia komputera (problemów z pamięcią lub dyskiem), ponieważ ogranicza liczbę równoległych kompilacji.

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

Plik $HOME/.jack

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

  • SERVER=true włącza funkcję serwera Jacka.
  • SERVER_PORT_SERVICE=8072 ustawia numer portu TCP serwera na potrzeby kompilacji.
  • SERVER_PORT_ADMIN=8073 ustawia numer portu TCP serwera na potrzeby administracyjne.
  • SERVER_COUNT=1 jest nieużywany.
  • SERVER_NB_COMPILE=4 ustawia maksymalną liczbę dozwolonych kompilacji równoległych. SERVER_TIMEOUT=60 ustawia liczbę sekund bezczynności, po których serwer musi czekać 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 Jacka

Problem Działanie
Twój komputer przestaje odpowiadać podczas kompilacji lub kompilacje Jacka kończą się niepowodzeniem z powodu błędu Out of memory error Zmniejsz liczbę jednoczesnych kompilacji Jacka, edytując plik $HOME/.jack i zmieniając wartość SERVER_NB_COMPILE na mniejszą.
Kompilacje kończą się niepowodzeniem z powodu błędu Cannot launch background server Najprawdopodobniej przyczyną jest to, że 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 Jacka, 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 działający w tle Jack za pomocą polecenia jack-admin kill-server, a następnie usuń katalogi tymczasowe znajdujące się w katalogu jack-$USER w katalogu tymczasowym (/tmp lub $TMPDIR).

Znajdowanie logu Jacka

Jeśli uruchomisz polecenie make z celem dist, log Jacka znajdzie się w lokalizacji $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. W przeciwnym razie możesz znaleźć log, uruchamiając polecenie jack-admin server-log. W przypadku powtarzających się błędów Jacka 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 to polecenie:

unset ANDROID_JACK_EXTRA_ARGS

Ograniczenia gniazda słuchawek

Domyślnie serwer Jacka może być używany tylko przez 1 użytkownika na komputerze. Aby obsługiwać dodatkowych użytkowników, wybierz dla każdego z nich inne numery portów i odpowiednio dostosuj wartość SERVER_NB_COMPILE. Możesz też wyłączyć serwer Jacka, 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 gniazda słuchawek

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

Pre-dex

Podczas generowania pliku biblioteki Jacka plik .dex biblioteki jest generowany i przechowywany w pliku biblioteki .jack jako pre-dex. Podczas kompilacji Jack ponownie używa pre-dex z każdej biblioteki. Wszystkie biblioteki są wstępnie indeksowane.

Biblioteki Jack z wstępnie skompilowanym kodem dex.

Rysunek 4. Biblioteki Jacka z pre-dex.

Jack nie używa ponownie pre-dex biblioteki, jeśli w kompilacji używane jest zmniejszanie, zaciemnianie lub przepakowywanie.

Kompilacja przyrostowa

Kompilacja przyrostowa oznacza, że tylko komponenty, które zostały zmienione od czasu ostatniej kompilacji (i ich zależności), są ponownie kompilowane. 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, przepakowywanie lub starsza wersja multidex). Aby włączyć kompilacje przyrostowe, dodaj ten wiersz do pliku Android.mk projektu, który chcesz kompilować przyrostowo:

LOCAL_JACK_ENABLED := incremental

Zmniejszanie i zaciemnianie

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 weryfikuje wstępnie)
  • -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 przepakowywania. Jack jest zgodny z typami reguł „rule”, ale nie jest zgodny z typami reguł „zap” ani „keep”.

Obsługa multidex

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.