Compilando com Jack (AOSP 6.0 - 8.1)

Jack é o conjunto de ferramentas de compilação padrão do Android para Android 6.0 - 8.1

Jack é um conjunto de ferramentas Android que compilou a fonte Java no bytecode dex do Android. Você não precisa fazer nada diferente para usar o Jack - basta usar os comandos padrão do makefile para compilar a árvore ou seu projeto. O Android 8.1 é a última versão que usa Jack.

Sobre Jack

Jack funciona conforme mostrado na Figura 1.

Visão geral de Jack.

Figura 1. Visão geral do Jack.

Formato da biblioteca Jack

Jack possui seu próprio formato de arquivo .jack que contém o código dex pré-compilado para a biblioteca, permitindo uma compilação mais rápida (pré-dex).

Conteúdo do arquivo da biblioteca Jack.

Figura 2. Conteúdo do arquivo da biblioteca Jack.

Jill

Conforme mostrado na figura a seguir, a ferramenta Jill traduz as bibliotecas .jar existentes para o novo formato de biblioteca.

Fluxo de trabalho para importar uma biblioteca `jar.` existente.

Figura 3. Fluxo de trabalho para importar uma biblioteca .jar existente.

Servidor de compilação Jack

Na primeira vez que o Jack é usado, ele inicia um servidor de compilação local do Jack no seu computador. Este servidor:

  • Traz uma aceleração intrínseca porque evita iniciar um novo JRE JVM host, carregar o código Jack, inicializar o Jack e aquecer o JIT a cada compilação. Ele também fornece tempos de compilação muito bons durante pequenas compilações (por exemplo, no modo incremental).
  • É uma solução de curto prazo para controlar o número de compilações paralelas de Jack. O servidor evita sobrecarregar o computador (problema de memória ou disco) porque limita o número de compilações paralelas.

O servidor Jack desliga após um tempo ocioso sem qualquer compilação. Ele usa duas portas TCP na interface localhost e não está disponível externamente. Todos os parâmetros (número de compilações paralelas, timeout, número de portas, etc.) podem ser modificados editando o arquivo $HOME/.jack .

Arquivo $HOME/.jack

O arquivo $HOME/.jack contém as seguintes configurações para variáveis ​​do servidor Jack em uma sintaxe bash completa:

  • SERVER=true ativa o recurso de servidor do Jack.
  • SERVER_PORT_SERVICE=8072 define o número da porta TCP do servidor para fins de compilação.
  • SERVER_PORT_ADMIN=8073 define o número da porta TCP do servidor para fins administrativos.
  • SERVER_COUNT=1 não é utilizado.
  • SERVER_NB_COMPILE=4 define o número máximo de compilações paralelas permitidas. SERVER_TIMEOUT=60 define o número de segundos inativos que o servidor deve esperar sem qualquer compilação antes de desligar. SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} define o arquivo onde os logs do servidor são gravados. Por padrão, esta variável pode ser sobrecarregada por uma variável de ambiente.
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} define o comando padrão usado para iniciar uma JVM no host. Por padrão, esta variável pode ser sobrecarregada pela variável de ambiente.

Solução de problemas de compilações de Jack

Problema Ação
Seu computador não responde durante a compilação ou você experimenta falhas nas compilações do Jack devido a um erro de falta de memória Reduza o número de compilações simultâneas de Jack editando $HOME/.jack e alterando SERVER_NB_COMPILE para um valor mais baixo.
As compilações estão falhando em Não é possível iniciar o servidor em segundo plano A causa mais provável é que as portas TCP já estejam em uso no seu computador. Altere as portas editando $HOME/.jack (variáveis SERVER_PORT_SERVICE e SERVER_PORT_ADMIN ). Para desbloquear a situação, desative o servidor de compilação Jack editando $HOME/.jack e alterando SERVER para false . Infelizmente, isso retarda significativamente sua compilação e pode forçá-lo a iniciar make -j com controle de carregamento (opção -l do make ).
A compilação fica travada sem nenhum progresso Para desbloquear a situação, elimine o servidor de segundo plano Jack usando jack-admin kill-server ) e remova os diretórios temporários contidos em jack-$USER do seu diretório temporário ( /tmp ou $TMPDIR ).

Encontrando o registro de Jack

Se você executou um comando make com um destino dist, o log do Jack estará localizado em $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log . Caso contrário, você pode encontrar o log executando jack-admin server-log . No caso de falhas reproduzíveis do Jack, você pode obter um log mais detalhado definindo a seguinte variável:

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

Use comandos makefile padrão para compilar a árvore (ou seu projeto) e anexar a saída padrão e o erro. Para remover logs de compilação detalhados, execute:

unset ANDROID_JACK_EXTRA_ARGS

Limitações de Jack

  • Por padrão, o servidor Jack pode ser usado por apenas um usuário em um computador. Para oferecer suporte a usuários adicionais, selecione números de porta diferentes para cada usuário e ajuste SERVER_NB_COMPILE adequadamente. Você também pode desabilitar o servidor Jack definindo SERVER=false em $HOME/.jack . A compilação do CTS é lenta devido à integração atual vm-tests-tf . Ferramentas de manipulação de bytecode (como JaCoCo) não são suportadas.

Usando Jack

Jack suporta a linguagem de programação Java 1.7 e integra os recursos adicionais descritos abaixo.

Pré-dexação

Ao gerar um arquivo de biblioteca Jack, o .dex da biblioteca é gerado e armazenado dentro do arquivo de biblioteca .jack como um pré-dex. Ao compilar, Jack reutiliza o pré-dex de cada biblioteca. Todas as bibliotecas são pré-dexadas.

Bibliotecas Jack com pré-dex.

Figura 4. Bibliotecas Jack com pré-dex.

Jack não reutiliza o pré-dex da biblioteca se a redução, ofuscação ou reempacotamento for usada na compilação.

Compilação incremental

Compilação incremental significa que apenas os componentes tocados desde a última compilação (e suas dependências) são recompilados. A compilação incremental pode ser significativamente mais rápida do que uma compilação completa quando as alterações são limitadas a um conjunto de componentes.

A compilação incremental está desabilitada por padrão (e é automaticamente desativada quando a redução, ofuscação, reempacotamento ou legado multi-dex está habilitado). Para ativar compilações incrementais, adicione a seguinte linha ao arquivo Android.mk do projeto que você deseja compilar de forma incremental:

LOCAL_JACK_ENABLED := incremental

Encolhimento e ofuscação

Jack usa arquivos de configuração do ProGuard para permitir redução e ofuscação.

As opções comuns incluem o seguinte:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (apenas 1 jar de saída suportado)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

As opções de redução incluem o seguinte:

  • -dontshrink

As opções de ofuscação incluem o seguinte:

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

As opções ignoradas incluem o seguinte:

  • -dontoptimize (Jack não otimiza)
  • -dontpreverify (Jack não pré-verifica)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

Reembalagem

Jack usa arquivos de configuração jarjar para reempacotar. Embora Jack seja compatível com os tipos de regras "rule", não é compatível com os tipos de regras "zap" ou "keep".

Suporte multidex

Jack oferece suporte multidex integrado e legado. Como os arquivos dex são limitados a 65 mil métodos, os aplicativos com mais de 65 mil métodos devem ser divididos em vários arquivos dex. Para obter mais detalhes, consulte Habilitar multidex para aplicativos com mais de 64 mil métodos