Jack を使用したコンパイル (AOSP 6.0 ~ 8.1)

Jack は、Android 6.0 ~ 8.1 のデフォルトの Android ビルド ツールチェーンです。

Jack は、Java ソースを Android dex バイトコードにコンパイルした Android ツールチェーンです。 Jack を使用するために特別なことをする必要はありません。標準の makefile コマンドを使用してツリーまたはプロジェクトをコンパイルするだけです。 Android 8.1 は、Jack を使用する最後のリリースです。

ジャックについて

ジャックは図 1 に示すように機能します。

ジャックの概要。

図 1.ジャックの概要。

ジャックライブラリフォーマット

Jack には、ライブラリのコンパイル済み dex コードを含む独自の.jackファイル形式があり、より高速なコンパイル (pre-dex) が可能です。

Jack ライブラリ ファイルの内容。

図 2. Jack ライブラリ ファイルの内容。

ジル

次の図に示すように、Jill ツールは既存の.jarライブラリを新しいライブラリ形式に変換します。

既存の「jar.」ライブラリをインポートするワークフロー。

図 3.既存の.jarライブラリをインポートするワークフロー。

ジャックコンパイルサーバー

Jack を初めて使用すると、コンピューター上でローカルの Jack コンパイル サーバーが起動されます。このサーバー:

  • 新しいホスト JRE JVM の起動、Jack コードのロード、Jack の初期化、コンパイルごとの JIT のウォームアップが不要になるため、本質的な高速化が実現します。また、小規模なコンパイル (インクリメンタル モードなど) では非常に優れたコンパイル時間も実現します。
  • 並列ジャック コンパイルの数を制御するための短期的なソリューションです。サーバーは並列コンパイルの数を制限するため、コンピューターの過負荷 (メモリまたはディスクの問題) を回避します。

Jack サーバーは、コンパイルを行わずにアイドル時間が経過すると、自動的にシャットダウンします。これはローカルホストインターフェイス上の 2 つの TCP ポートを使用し、外部からは使用できません。すべてのパラメータ (並列コンパイルの数、タイムアウト、ポート番号など) は、 $HOME/.jackファイルを編集することで変更できます。

$HOME/.jack ファイル

$HOME/.jackファイルには、完全な bash 構文での Jack サーバー変数の次の設定が含まれています。

  • SERVER=true Jack のサーバー機能を有効にします。
  • SERVER_PORT_SERVICE=8072コンパイル目的でサーバーの TCP ポート番号を設定します。
  • SERVER_PORT_ADMIN=8073管理目的でサーバーの TCP ポート番号を設定します。
  • SERVER_COUNT=1は未使用です。
  • SERVER_NB_COMPILE=4許可される並列コンパイルの最大数を設定します。 SERVER_TIMEOUT=60サーバーがシャットダウンする前にコンパイルを行わずに待機する必要があるアイドル秒数を設定します。 SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}サーバー ログが書き込まれるファイルを設定します。デフォルトでは、この変数は環境変数によってオーバーロードできます。
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}ホスト上で JVM を起動するために使用されるデフォルトのコマンドを設定します。デフォルトでは、この変数は環境変数によってオーバーロードできます。

Jack コンピレーションのトラブルシューティング

問題アクション
コンパイル中にコンピュータが応答しなくなる、またはメモリ不足エラーで Jack コンパイルが失敗する$HOME/.jackを編集し、 SERVER_NB_COMPILEより低い値に変更して、同時 Jack コンパイルの数を減らします。
バックグラウンドサーバーを起動できませんでコンパイルが失敗します最も可能性の高い原因は、TCP ポートがコンピュータですでに使用されていることです。 $HOME/.jack ( SERVER_PORT_SERVICEおよびSERVER_PORT_ADMIN変数) を編集して、ポートを変更します。この状況のブロックを解除するには、 $HOME/.jackを編集し、 SERVERfalseに変更して、Jack コンパイル サーバーを無効にします。残念ながら、これによりコンパイルが大幅に遅くなり、負荷制御 ( makeのオプション-l ) を使用してmake -jを起動する必要が生じる可能性があります。
コンパイルが進まずにスタックしてしまうこの状況のブロックを解除するには、 jack-admin kill-server server を使用して Jack バックグラウンド サーバーを強制終了し、一時ディレクトリ ( /tmpまたは$TMPDIR ) のjack-$USERに含まれる一時ディレクトリを削除します。

ジャックのログを見つける

dist ターゲットを指定してmakeコマンドを実行した場合、Jack ログは$ANDROID_BUILD_TOP/out/dist/logs/jack-server.logにあります。それ以外の場合は、 jack-admin server-logを実行してログを見つけることができます。再現可能な Jack 障害の場合は、次の変数を設定することで、より詳細なログを取得できます。

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

標準の makefile コマンドを使用してツリー (またはプロジェクト) をコンパイルし、標準出力とエラーを添付します。詳細なビルド ログを削除するには、次を実行します。

unset ANDROID_JACK_EXTRA_ARGS

ジャックの制限事項

  • デフォルトでは、Jack サーバーは 1 台のコンピューター上で 1 人のユーザーのみが使用できます。追加のユーザーをサポートするには、ユーザーごとに異なるポート番号を選択し、それに応じてSERVER_NB_COMPILEを調整します。 $HOME/.jackSERVER=falseを設定することで、Jack サーバーを無効にすることもできます。現在のvm-tests-tf統合により、CTS のコンパイルが遅くなります。バイトコード操作ツール (JaCoCo など) はサポートされていません。

ジャックの使い方

Jack は Java プログラミング言語 1.7 をサポートし、以下で説明する追加機能を統合します。

事前デキシング

Jack ライブラリ ファイルを生成するとき、ライブラリの.dexが生成され、プレデックスとして.jackライブラリ ファイル内に保存されます。コンパイル時に、Jack は各ライブラリの predex を再利用します。すべてのライブラリは事前に索引付けされています。

pre-dex を備えた Jack ライブラリ。

図 4. pre-dex を含む Jack ライブラリ。

Jack は、コンパイルで圧縮、難読化、または再パッケージ化が使用されている場合、ライブラリの predex を再利用しません。

インクリメンタルコンパイル

インクリメンタル コンパイルとは、前回のコンパイル以降に操作されたコンポーネント (およびその依存関係) のみが再コンパイルされることを意味します。変更がコンポーネントのセットに限定されている場合、増分コンパイルは完全コンパイルよりも大幅に高速になる可能性があります。

インクリメンタル コンパイルはデフォルトで無効になっています (また、圧縮、難読化、再パッケージ化、またはマルチデックス レガシーが有効になっている場合は自動的に無効になります)。インクリメンタル ビルドを有効にするには、インクリメンタル ビルドするプロジェクトのAndroid.mkファイルに次の行を追加します。

LOCAL_JACK_ENABLED := incremental

縮小と難読化

Jack は ProGuard 構成ファイルを使用して、圧縮と難読化を有効にします。

一般的なオプションには次のようなものがあります。

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (出力 jar は 1 つだけサポートされます)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

縮小オプションには次のようなものがあります。

  • -dontshrink

難読化オプションには次のものが含まれます。

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

無視されるオプションには次のようなものがあります。

  • -dontoptimize (ジャックは最適化しない)
  • -dontpreverify (ジャックは事前検証を行いません)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

再梱包

Jack は jarjar 設定ファイルを使用して再パッケージ化を行います。 Jack は「rule」ルール タイプと互換性がありますが、「zap」または「keep」ルール タイプとは互換性がありません。

マルチデックスのサポート

Jack は、組み込みおよび従来の multidex サポートを提供します。 dex ファイルは 65K メソッドに制限されているため、65K を超えるメソッドを含むアプリは複数の dex ファイルに分割する必要があります。詳細については、 「64K を超えるメソッドを使用するアプリのマルチデックスを有効にする」を参照してください。