天天看點

Dex2Oat執行參數總結

Android源碼編譯完的産物,都會放在out目錄下,而/out/host目錄中主要存放Android開發工具的産物,包含SDK各種工具,比如adb,dex2oat,aapt等。在整個編譯完成之後,可以使用這些工具,比如dex2oat可以用來将dex檔案轉化為oat檔案,在aosp目錄下,執行out/host/linux-x86/bin/dex2oatd + 參數即可完成這個轉化工作。

例如:

out/host/linux-x86/bin/dex2oatd --runtime-arg -Xms64m --runtime-arg -Xmx512m --boot-image=out/target/product/ranchu/dex_bootjars/system/framework/boot.art --dex-file=out/target/product/ranchu/obj/APPS/Telecom_intermediates/oat/arm64/package.odex.input --dex-location=/system/priv-app/Telecom/Telecom.apk --oat-file=out/target/product/ranchu/obj/APPS/Telecom_intermediates/oat/arm64/package.odex --android-root=out/target/product/ranchu/system --instruction-set=arm64 --instruction-set-variant=generic --instruction-set-features=default --include-patch-information --runtime-arg -Xnorelocate --no-generate-debug-info --abort-on-hard-verifier-error --no-inline-from=core-oj.jar
           

參數說明:

--dex-file=<dex-file>: specifies a .dex, .jar, or .apk file to compile.
Example: --dex-file=/system/framework/core.jar

指定要編譯的檔案路徑,這個檔案既可以是一個dex檔案,也可以是一個内部包含dex檔案的apk或jar檔案。對于一次要編譯多個檔案的情況,每個檔案都要用單獨的一個--dex-file來指定。
           
--dex-location=<dex-location>: specifies an alternative dex location to encode in the oat file for the corresponding --dex-file argument.
Example: --dex-file=/home/build/out/system/framework/core.jar
         --dex-location=/system/framework/core.jar

指定要寫入最終編譯出目标oat檔案内部的編譯檔案的路徑。
對于一次要編譯多個檔案的情況,每一個路徑都需要用--dex-location來指定,且出現的次序要和--dex-file指定的次序相同。
           
--zip-fd=<file-descriptor>: specifies a file descriptor of a zip file
containing a classes.dex file to compile.
Example: --zip-fd=

指定要編譯檔案的檔案描述符。--zip-fd和--dex-file必須指定一個,但兩者也互相沖突,不能同時出現,否則都會報錯退出。
           
--zip-location=<zip-location>: specifies a symbolic name for the file
corresponding to the file descriptor specified by --zip-fd.
Example: --zip-location=/system/app/Calculator.apk

說明前面通過--zip-fd參數傳入的那個檔案描述符号對應的檔案的路徑。這個參數和--zip-location必須配對使用,也就是說,如果沒有--zip-fd但是傳入了--zip-location,或者有--zip-fd但是沒有傳入--zip-location,兩種情況dex2oat都會報錯退出。
           
--oat-file=<file.oat>: specifies the oat output destination via a filename.
Example: --oat-file=/system/framework/boot.oat

指定編譯輸出的oat檔案的路徑。
           
--oat-fd=<number>: specifies the oat output destination via a file descriptor.
Example: --oat-fd=6

指定編譯輸出的oat檔案的檔案描述符。--oat-fd和--oat-file必須指定一個,但兩者也是沖突的,不能同時出現,否則都會報錯退出。
           
--oat-location=<oat-name>: specifies a symbolic name for the file corresponding to the file descriptor specified by --oat-fd.
Example: --oat-location=/data/dalvik-cache/[email protected]@Calculator.apk.oat

也是指定編譯輸出的oat檔案的路徑,不過與--oat-file不同,--oat-location是必須要和--oat-fd配對使用的,兩個參數必須同時出現。
通過上面可以看出,dex2oat接受兩種方式指定要編譯的檔案和輸出的檔案,分别是通過檔案路徑或通過檔案的描述符。如果是通過檔案的描述符的話,dex2oat雖然可以對這個檔案進行操作,但并不知道這個檔案在什麼位置,是以還需要通過以location結尾的參數來告之;而如果是通過檔案路徑的話,則dex2oat會直接打開這個檔案,再對其進行操作。
而對于結尾為fd的參數來說,一般都是父程序先将檔案打開,獲得檔案描述符後,在fork出的子程序中掉用execv來運作dex2oat程式,因為子程序是繼承父程序所打開的檔案描述符的,是以可以直接對其操作。
           
--oat-symbols=<file.oat>: specifies the oat output destination with full symbols.
Example: --oat-symbols=/symbols/system/framework/boot.oat

也是指定編譯要輸出的oat檔案,但和--oat-file不同的是,如果使用--oat-symbols,則輸出的oat檔案會包含所有的符号,而--oat-file則不會。
并且--oat-symbols和--oat-fd是沖突的,隻允許出現一個,如果兩個同時出現,則會報錯退出。
           
--image=<file.art>: specifies the output image filename.
Example: --image=/system/framework/boot.art

指定要編譯出的ART鏡像檔案(Image)所存放的路徑。如果指定了這個參數,就說明此次掉用dex2oat是為了編譯出系統鏡像檔案,而不是編譯一個普通的應用程式。
這個參數和--oat-fd是沖突的,兩者不能同時出現,否則dex2oat會報錯退出。
           
--image-classes=<classname-file>: specifies classes to include in an image.
Example: --image=frameworks/base/preloaded-classes

指定要編譯處的ART鏡像檔案(Image)需要包含哪些類的一個清單。
對于Android x和x系統來說,這個參數被設定成“/system/etc/preloaded-classes”。
           
--base=<hex-address>: specifies the base address when creating a boot image.
Example: --base=

指定image加載進記憶體時,被映射到的起始記憶體位址。
           
--boot-image=<file.art>: provide the image file for the boot class path.
Example: --boot-image=/system/framework/boot.art
Default: $ANDROID_ROOT/system/framework/boot.art

指定系統鏡像檔案存放的路徑。如果不指定的話,預設系統将其設定成“/system/framework/boot.art”。但是,實際上鏡像檔案并不是存放在這個位置,而是在“/system/framework/<image_isa>/boot.art”,比如在arm平台上(非位),其鏡像檔案是放在“/system/framework/arm/boot.art”中的。
           
--android-root=<path>: used to locate libraries for portable linking.
Example: --android-root=out/host/linux-x86
Default: $ANDROID_ROOT

指定Android系統的根路徑。如果不指定的話,預設情況下dex2oat會讀取目前系統的環境變量ANDROID_ROOT,将其值作為Android系統的根路徑,繼續編譯下去。如果連環境變量ANDROID_ROOT也讀不到的話,則報錯退出。
一般情況下,Android裝置上,環境變量ANDROID_ROOT被設定成了“/system”。
           
--instruction-set=(arm|arm64|mips|mips64|x86|x86_64): compile for a particular instruction set.
Example: --instruction-set=x86
Default: arm

指定要用什麼指令集來編譯dex檔案。目前共支援六種指令集,三種平台(arm、mips和x86),每種平台有分為位和位兩種。
           
--instruction-set-features=...,: Specify instruction set features
Example: --instruction-set-features=div
Default: default

對于一個處理器來說,除了要知道其能執行代碼的指令集之外,還需要知道它的一些特别的屬性,進而可以在編譯中的代碼中使用到。
對于支援arm指令集的處理器來說,有“smp”(對稱多處理器,也就是多核)、“div”(硬體除法器)和“lpae”(大記憶體模式)三個。
           
--compile-pic: Force indirect use of code, methods, and classes
Default: disabled

用PIC(Position Independent Code,位置無關代碼)模式來編譯。
           
--compiler-backend=(Quick|Optimizing): select compiler backend set.
Example: --compiler-backend=Optimizing
Default: Quick

指定編譯器的後端使用哪種模式,可選的是所謂快模式(Quick)或優化模式(Optimizing)。如果沒有特别指定的話,編譯鏡像使用快模式,而編譯一般的應用程式則使用優化模式。
什麼是編譯器的後段呢?其實這是LLVM引入的概念。所有的程式先用前端翻譯成中間表示層,然後進行優化,最後用後端将優化過的中間表示層代碼編譯成平台相關的代碼。Android雖然沒有直接用LLVM編譯器(以前也确實用過,但從開始就廢棄掉了),但是借鑒了這種編譯器的設計結構。
值得一提的是,如果使用優化模式,則一定是用PIC模式進行編譯。
           
--compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything|time):
select compiler filter.
Example: --compiler-filter=everything
Default: speed

指定一些編譯選項,預設是speed,以速度優先。
           
--huge-method-max=<method-instruction-count>: threshold size for a huge
method for compiler filter tuning.
Example: --huge-method-max=10000
Default: 

告訴dex2oat,當發現一個函數内包含的指令數目超過多少時,被當作巨大函數來處理。如果不指定,預設的值是。
           
--large-method-max=<method-instruction-count>: threshold size for a large
method for compiler filter tuning.
Example: --large-method-max=600
Default: 

告訴dex2oat,當發現一個函數内包含的指令數目超過多少時,被當作大函數來處理。如果不指定,預設的值是。
           
--small-method-max=<method-instruction-count>: threshold size for a small
method for compiler filter tuning.
Example: --small-method-max=60
Default: 

告訴dex2oat,當發現一個函數内包含的指令數目超過多少時,被當作小函數來處理。如果不指定,預設的值是。
           
--tiny-method-max=<method-instruction-count>: threshold size for a tiny
method for compiler filter tuning.
Example: --tiny-method-max=20
Default: 

告訴dex2oat,當發現一個函數内包含的指令數目超過多少時,被當作微型函數來處理。如果不指定,預設的值是。
           
--num-dex-methods=<method-count>: threshold size for a small dex file for
compiler filter tuning. If the input has fewer than this many methods and the filter is not interpret-only or verify-none, overrides the filter to use speed
Example: --num-dex-method=900
Default: 

告訴dex2oat,當發現一個dex檔案内部包含的方法數少于多少時,将被當作小dex檔案來處理。
具體的來說,如果一個dex檔案内部的方法數小于這個指定值的話,且--compiler-filter編譯過濾器不是被設定成verify-none或interpret-only的話,将編譯過濾器強制設定成speed。
           
--include-patch-information: Include patching information so the generated code
can have its base address moved without full recompilation.

通知dex2oat要把patch的資訊也寫入編譯出的oat檔案中。
           
--no-include-patch-information: Do not include patching information.

通知dex2oat不要把patch的資訊也寫入編譯出的oat檔案中。
           
-g
--generate-debug-info: Generate debug information for native debugging, such as stack unwinding information, ELF symbols and DWARF sections.
This generates all the available information. Unneeded parts can be stripped using standard command line tools such as strip or objcopy.
(enabled by default in debug builds, disabled by default otherwise)

通知dex2oat,要在編譯出的oat檔案中包含調試的資訊。
           
--no-generate-debug-info: Do not generate debug information for native debugging.

通知dex2oat,不要在編譯出的oat檔案中包含調試的資訊。
           
--runtime-arg <argument>: used to specify various arguments for the runtime,
such as initial heap size, maximum heap size, and verbose output.
Use a separate --runtime-arg switch for each argument.
Example: --runtime-arg -Xms256m

告訴ART運作時(Runtime)的參數,例如初始堆大小和最大堆大小之類的,且對每一個不通的參數都要在前面加上--runtime-arg。
順便提一句,dex2oat在編譯的時候會在内部建立一個ART運作時。
           
--swap-file=<file-name>:  specifies a file to use for swap.
Example: --swap-file=/data/tmp/swap.

指定編譯所需要的交換檔案的路徑。
           
--swap-fd=<file-descriptor>:  specifies a file to use for swap (by descriptor).
Example: --swap-fd=

指定編譯所需要的交換檔案的檔案描述符。

這個交換檔案是用來臨時存放編譯過程中所産生的一些資料的,并不是指定了這個交換檔案dex2oat就一定會使用,還必須要滿足一定條件。如果是編譯鏡像檔案的話,則一定不會用交換檔案。如果要編譯的所有dex檔案的數目小于的話,也不會使用。最後,如果要編譯的所有dex檔案的總大小小于MB的話,也不會用(這麼說基本上都不會使用了)。
           

參考資料:dex2oat程式參數總結