使用 Jack 編譯 (AOSP 6.0 - 8.1),使用 Jack 編譯 (AOSP 6.0 - 8.1)

Jack 是 Android 6.0 - 8.1 的預設 Android 建置工具鏈

Jack 是一個 Android 工具鏈,可將 Java 原始碼編譯為 Android dex 字節碼。您不必做任何不同的事情來使用 Jack - 只需使用標準 makefile 命令來編譯樹或您的專案。 Android 8.1 是最後一個使用 Jack 的版本。

關於傑克

Jack的工作原理如圖1所示。

傑克概述。

圖 1.插孔概覽。

傑克庫格式

Jack 有自己的.jack檔案格式,其中包含函式庫的預編譯 dex 程式碼,允許更快的編譯(pre-dex)。

Jack 庫檔案內容。

圖 2.Jack庫文件內容。

吉爾

如下圖所示,Jill工具將現有的.jar庫轉換為新的庫格式。

導入現有「jar.」庫的工作流程。

圖 3.導入現有.jar庫的工作流程。

Jack編譯伺服器

第一次使用 Jack 時,它會在您的電腦上啟動本機 Jack 編譯伺服器。該伺服器:

  • 帶來內在的加速,因為它避免了在每次編譯時啟動新的主機 JRE JVM、載入 Jack 程式碼、初始化 Jack 以及預熱 JIT。它還在小型編譯期間(例如,在增量模式下)提供非常好的編譯時間。
  • 是控制並行Jack編譯數量的短期解決方案。伺服器避免了電腦過載(記憶體或磁碟問題),因為它限制了並行編譯的數量。

Jack 伺服器在空閒時間後自行關閉,沒有進行任何編譯。它使用本機主機介面上的兩個 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/.jackSERVER_PORT_SERVICESERVER_PORT_ADMIN變數)來變更連接埠。若要解除這種情況,請透過編輯$HOME/.jack並將SERVER改為false來停用 Jack 編譯伺服器。不幸的是,這會顯著減慢您的編譯速度,並可能迫使您啟動帶有負載控制的make -jmake的選項-l )。
編譯卡住了沒有任何進展要解除這種情況,請使用jack-admin kill-server終止 Jack 後台伺服器,然後刪除臨時目錄的jack-$USER中包含的臨時目錄( /tmp$TMPDIR )。

找到傑克日誌

如果您使用 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 伺服器只能由一台電腦上的一個使用者使用。若要支援其他用戶,請為每個用戶選擇不同的連接埠號碼並相應地調整SERVER_NB_COMPILE 。您也可以透過在$HOME/.jack中設定SERVER=false停用 Jack 伺服器。由於目前的vm-tests-tf集成,CTS 編譯速度很慢。不支援字節碼操作工具(例如 JaCoCo)。

使用傑克

Jack 支援 Java 程式語言 1.7 並整合了下述附加功能。

預索引

產生 Jack 庫檔案時,會產生該庫的.dex ,並將其作為 pre-dex 儲存在.jack庫檔案內。編譯時,Jack 重用了每個函式庫中的 pre-dex。所有庫均已預先索引。

有 pre-dex 的 Jack 庫。

圖 4.具有預 dex 的 Jack 庫。

如果在編譯中使用縮略、混淆或重新打包,Jack 不會重複使用函式庫 pre-dex。

增量編譯

增量編譯意味著僅重新編譯自上次編譯以來觸及的元件(及其相依性)。當變更僅限於一組元件時,增量編譯可能比完整編譯快得多。

增量編譯預設為停用狀態(並且在啟用收縮、混淆、重新打包或多 dex 遺留功能時會自動停用)。若要啟用增量構建,請將以下行新增至要增量建置的專案的Android.mk檔案:

LOCAL_JACK_ENABLED := incremental

縮小和混淆

Jack 使用 ProGuard 設定檔來啟用收縮和混淆。

常見選項包括以下內容:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (僅支援 1 個輸出 jar)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

收縮選項包括以下:

  • -dontshrink

混淆選項包括以下內容:

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

忽略的選項包括以下內容:

  • -dontoptimize (Jack 不優化)
  • -dontpreverify (Jack 不進行預先驗證)
  • -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 提供內建和傳統的多重分包支援。由於 dex 檔案限制為 65K 方法,因此具有超過 65K 方法的應用程式必須拆分為多個 dex 檔案。有關更多詳細信息,請參閱為具有超過 64K 方法的應用程式啟用 multidex

,

Jack 是 Android 6.0 - 8.1 的預設 Android 建置工具鏈

Jack 是一個 Android 工具鏈,可將 Java 原始碼編譯為 Android dex 字節碼。您不必做任何不同的事情來使用 Jack - 只需使用標準 makefile 命令來編譯樹或您的專案。 Android 8.1 是使用 Jack 的最後一個版本。

關於傑克

Jack的工作原理如圖1所示。

傑克概述。

圖 1.插孔概覽。

Jack庫格式

Jack 有自己的.jack檔案格式,其中包含函式庫的預編譯 dex 程式碼,允許更快的編譯(pre-dex)。

Jack 庫檔案內容。

圖 2.Jack庫文件內容。

吉爾

如下圖所示,Jill工具將現有的.jar庫轉換為新的庫格式。

導入現有「jar.」庫的工作流程。

圖 3.導入現有.jar庫的工作流程。

Jack編譯伺服器

第一次使用 Jack 時,它會在您的電腦上啟動本機 Jack 編譯伺服器。該伺服器:

  • 帶來內在的加速,因為它避免了在每次編譯時啟動新的主機 JRE JVM、載入 Jack 程式碼、初始化 Jack 以及預熱 JIT。它還在小型編譯期間(例如,在增量模式下)提供非常好的編譯時間。
  • 是控制並行Jack編譯數量的短期解決方案。伺服器避免了電腦過載(記憶體或磁碟問題),因為它限制了並行編譯的數量。

Jack 伺服器在空閒時間後自行關閉,沒有進行任何編譯。它使用本機主機介面上的兩個 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/.jackSERVER_PORT_SERVICESERVER_PORT_ADMIN變數)來變更連接埠。若要解除這種情況,請透過編輯$HOME/.jack並將SERVER改為false來停用 Jack 編譯伺服器。不幸的是,這會顯著減慢您的編譯速度,並可能迫使您啟動帶有負載控制的make -jmake的選項-l )。
編譯卡住了沒有任何進展要解除這種情況,請使用jack-admin kill-server終止 Jack 後台伺服器,然後刪除臨時目錄的jack-$USER中包含的臨時目錄( /tmp$TMPDIR )。

找到傑克日誌

如果您使用 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 伺服器只能由一台電腦上的一個使用者使用。若要支援其他用戶,請為每個用戶選擇不同的連接埠號碼並相應地調整SERVER_NB_COMPILE 。您也可以透過在$HOME/.jack中設定SERVER=false停用 Jack 伺服器。由於目前的vm-tests-tf集成,CTS 編譯速度很慢。不支援字節碼操作工具(例如 JaCoCo)。

使用傑克

Jack 支援 Java 程式語言 1.7 並整合了下述附加功能。

預索引

產生 Jack 庫檔案時,會產生該庫的.dex ,並將其作為 pre-dex 儲存在.jack庫檔案內。編譯時,Jack 重用了每個函式庫中的 pre-dex。所有庫均已預先索引。

有 pre-dex 的 Jack 庫。

圖 4.具有預 dex 的 Jack 庫。

如果在編譯中使用縮略、混淆或重新打包,Jack 不會重複使用函式庫 pre-dex。

增量編譯

增量編譯意味著僅重新編譯自上次編譯以來觸及的元件(及其相依性)。當變更僅限於一組元件時,增量編譯可能比完整編譯快得多。

增量編譯預設為停用狀態(並且在啟用收縮、混淆、重新打包或多 dex 遺留功能時會自動停用)。若要啟用增量構建,請將以下行新增至要增量建置的專案的Android.mk檔案:

LOCAL_JACK_ENABLED := incremental

縮小和混淆

Jack 使用 ProGuard 設定檔來啟用收縮和混淆。

常見選項包括以下內容:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (僅支援 1 個輸出 jar)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

收縮選項包括以下:

  • -dontshrink

混淆選項包括以下內容:

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

忽略的選項包括以下內容:

  • -dontoptimize (Jack 不優化)
  • -dontpreverify (Jack 不進行預先驗證)
  • -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 提供內建和傳統的多重分包支援。由於 dex 檔案限制為 65K 方法,因此具有超過 65K 方法的應用程式必須拆分為多個 dex 檔案。有關更多詳細信息,請參閱為具有超過 64K 方法的應用程式啟用 multidex