About android mk parameters

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES

LOCAL_PREBUILT_LIBS

LOCAL_STATIC_JAVA_LIBRARIES

Android中可能會用到第三方的軟件包,這包括Java包.jar和Native包.so。jar包既可通過Eclipse開發環境集成,也可通過編譯源碼集成,看你的工作環境。

假定自己開發的程序爲MyMaps,需要用到BaiduMaps的庫,包括baidumapapi.jar和libBMapApiEngine_v1_3_1.so。

 

一、Eclipse中集成第三方jar包及.so動態庫

MyMaps工程下創建目錄libs以及libs/armeabi,把baidumapapi.jar放在的libs/目錄下,把libBMapApiEngine_v1_3_1.so放在libs/armeabi/下。

Eclipse中把第三方jar包baidumapapi.jar打包到MyMaps的步驟:

 

1.      右擊工程,選擇Properties;

2.      JavaBuild Path,選擇Libraries;

3.      Libraries頁面點擊右面按鈕“Add Library…”;

4.      選擇“User Library”,點擊“Next”;

5.      點擊“User Libraries”按鈕;

6.      在彈出界面中,點擊“New…”;

7.      輸入“User library name”,點擊“OK”確認;

8.      返回之後,選擇剛剛創建的User library,右面點擊“AddJARs”;

9.      選擇MyMaps/libs/下的baidumapapi.jar;

10.  確認,返回。

 

這樣,編譯之後,該jar包就會被打進MyMaps.apk中,libBMapApiEngine_v1_3_1.so也被打包在lib/armeabi/中。

程序運行過程中,libBMapApiEngine_v1_3_1.so被放在/data/data/<yourAppPackage>/lib/下,加載動態庫時系統會從程序的該lib/目錄下查找.so庫

 

二、源碼中集成第三方集成jar包及.so動態庫

Android源碼中MyMaps放在packages/apps下。

MyMaps下創建目錄libs以及libs/armeabi,並把baidumapapi.jar放在libs/,把libBMapApiEngine_v1_3_1.so放在libs/armeabi

 

2.1 修改Android.mk文件

Android.mk文件如下:

1.  LOCAL_PATH:= $(call my-dir)  

2.  include $(CLEAR_VARS)

4.  LOCAL_MODULE_TAGS := optional 

6.  LOCAL_STATIC_JAVA_LIBRARIES := libbaidumapapi 

8.  LOCAL_SRC_FILES := $(call all-subdir-java-files) 

10. LOCAL_PACKAGE_NAME := MyMaps 

12. include $(BUILD_PACKAGE)  

13.    

14. ##################################################  

15. include $(CLEAR_VARS)  

17. LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libbaidumapapi:libs/baidumapapi.jar

18. LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so  

19. LOCAL_MODULE_TAGS := optional  

20. include $(BUILD_MULTI_PREBUILT)  

21. 

22. # Use the following include to make our testapk.  

23. include $(callall-makefiles-under,$(LOCAL_PATH))  

 

1 集成jar包

LOCAL_STATIC_JAVA_LIBRARIES 取jar庫的別名,可以任意取值;

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuiltjar庫的規則,格式:別名:jar文件路徑。注意:別名一定要與LOCAL_STATIC_JAVA_LIBRARIES 裏所取的別名一致,且不含.jar;jar文件路徑一定要是真實的存放第三方jar包的路徑。

編譯用BUILD_MULTI_PREBUILT

2 集成.so動態庫

LOCAL_PREBUILT_LIBS指定prebuilt so的規則,格式:別名:so文件路徑。注意:別名一般不可改變,特別是第三方jar包使用.so庫的情況,且不含.so;so文件路徑一定要是真實的存放第三方so文件的路徑。

編譯拷貝用BUILD_MULTI_PREBUILT

 

2.2 加入到GRANDFATHERED_USER_MODULES

在文件user_tags.mk中,把libBMapApiEngine_v1_3_1加入到GRANDFATHERED_USER_MODULES中

1.  GRANDFATHERED_USER_MODULES += \  

2.      … \  

3.      libBMapApiEngine_v1_3_1 

user_tags.mk可以是build/core下的,也可以是$(TARGET_DEVICE_DIR)下的,推薦修改$(TARGET_DEVICE_DIR)下的。

 

2.3 編譯結果

MyMaps.apk編譯生成在out/target/product/<YourProduct>/system/app/下;

libBMapApiEngine_v1_3_1.so放在out/target/product/<YourProduct>/system/lib/下,這也是系統加載動態庫時搜索的路徑。

 

附上自己寫的android.mk文件一個

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_STATIC_JAVA_LIBRARIES := lib3party

LOCAL_SRC_FILES := $(call all-subdir-java-files

LOCAL_PACKAGE_NAME := OnlineDownload

include $(BUILD_PACKAGE)

 

include $(CLEAR_VARS)

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=lib3party:libs/android-support-v4.jar

include $(BUILD_MULTI_PREBUILT)

 

當需要加載多個jar包時,只需要按照mk文件規則,在定義變量的地方先空格,然後輸入”\”符號,然後回車,然後輸入jar包別名就行,附上編譯通過的自己寫的導入多個jar包的mk文件

 

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_STATIC_JAVA_LIBRARIES := libname1 \

libname2 \

libname3

 

LOCAL_SRC_FILES := $(callall-subdir-java-files)

LOCAL_PACKAGE_NAME := OnlineDownload

include $(BUILD_PACKAGE)

 

include $(CLEAR_VARS)

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libname1:libs/android-support-v4.jar \

libname2:libs/commons-net-1.2.2.jar \

libname3:libs/jakarta-oro-2.0.8.jar

include $(BUILD_MULTI_PREBUILT)



LOCAL_MODULE_CLASS and LOCAL_MODULE_PATH

3include $(CLEAR_VARS)
4LOCAL_MODULE           := receiver_filter_policy.xml
5LOCAL_MODULE_TAGS      := optional
6LOCAL_MODULE_CLASS     := ETC
7LOCAL_MODULE_PATH      := $(TARGET_OUT_ETC)
8LOCAL_SRC_FILES        := $(LOCAL_MODULE)
9include $(BUILD_PREBUILT)

./product/flounder32/obj/ETC/receiver_filter_policy.xml_intermediates
./product/flounder32/obj/ETC/receiver_filter_policy.xml_intermediates/receiver_filter_policy.xml
./product/flounder32/system/etc/receiver_filter_policy.xml

5include $(CLEAR_VARS)
6LOCAL_MODULE := appops
7LOCAL_SRC_FILES := appops
8LOCAL_MODULE_CLASS := EXECUTABLES
9LOCAL_MODULE_TAGS := optional
10include $(BUILD_PREBUILT)

./product/flounder32/obj/EXECUTABLES/appops_intermediates
./product/flounder32/obj/EXECUTABLES/appops_intermediates/appops
./product/flounder32/system/bin/appops

3include $(CLEAR_VARS)
4
5LOCAL_MULTILIB := 32
6LOCAL_SRC_FILES_arm     := armeabi/libAlphaInputWrapper.so
9
10LOCAL_MODULE := libAlphaInputWrapper
11LOCAL_MODULE_CLASS := SHARED_LIBRARIES
12LOCAL_MODULE_SUFFIX := .so
13LOCAL_MODULE_TAGS := optional
14
15include $(BUILD_PREBUILT)

./product/flounder32/obj/lib/libAlphaInputWrapper.so
./product/flounder32/obj/SHARED_LIBRARIES/libAlphaInputWrapper_intermediates
./product/flounder32/obj/SHARED_LIBRARIES/libAlphaInputWrapper_intermediates/LINKED/libAlphaInputWrapper.so
./product/flounder32/obj/SHARED_LIBRARIES/libAlphaInputWrapper_intermediates/PACKED/libAlphaInputWrapper.so
./product/flounder32/system/lib/libAlphaInputWrapper.so
./product/flounder32/symbols/system/lib/libAlphaInputWrapper.so

In fireos/prebuilts/middleware/h2clientservice/prebuilts/apk/debug/Android.mk

3# the debug apps are only effective for eng build
4ifneq (,$(filter debug,$(FIREOS_PREBUILT_INSTALL)))              if in userdebug build, continue
5
6# enum all the .apk files immediately below current directory
7debug_apps := $(notdir $(wildcard $(LOCAL_PATH)/*.apk))             search for apk file in current folder
8
9# all the debug apps will be signed with the key specified by LOCAL_CERTIFICATE
10# regardless of the original key signed the package with.
11define _add_debug_apps
12include $$(CLEAR_VARS)
13LOCAL_MODULE        := $(basename $1)
14LOCAL_SRC_FILES     := $1
15LOCAL_MODULE_TAGS   := optional
16LOCAL_CERTIFICATE   := $(FIREOS_LOCAL_CERTIFICATE_OVERRIDE)
17LOCAL_MODULE_SUFFIX := $$(COMMON_ANDROID_PACKAGE_SUFFIX)
18LOCAL_MODULE_CLASS  := APPS
19LOCAL_PRIVILEGED_MODULE := true
20include $$(BUILD_PREBUILT)
21endef
22
23$(foreach _apk, $(debug_apps), \
24    $(eval $(call _add_debug_apps,$(_apk))))           For each apk file, call _add_debug_apps function, the parameter is the apk path.
25
26local_install_packages += $(basename $(debug_apps))
27
28debug_apps :=
29
30endif # ifneq (,$(filter debug,$(FIREOS_PREBUILT_INSTALL)))
./product/flounder32/obj/APPS/com.amazon.h2clientservice_intermediates
./product/flounder32/system/priv-app/com.amazon.h2clientservice
./product/flounder32/system/priv-app/com.amazon.h2clientservice/com.amazon.h2clientservice.apk

In fireos/prebuilts/middleware/h2clientservice/prebuilts/jar/Android.mk
19_non_dexed_jar_files := com.amazon.h2contracts.jar
21
22# static jar files must be added manually
23_static_jar_files :=
24
25# generate install jar file list
26_install_jar_files := $(filter-out $(_static_jar_files),$(_non_dexed_jar_files))
27
28
29ifneq ($(strip $(SHOW_COMMANDS)),)
30$(info _non_dexed_jar_files=$(_non_dexed_jar_files))
31$(info _static_jar_files=$(_static_jar_files))
32$(info _install_jar_files=$(_install_jar_files))
33endif
34
35
36include $(CLEAR_VARS)
37LOCAL_PREBUILT_JAVA_LIBRARIES           := $(_install_jar_files)
38LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES    := $(_static_jar_files)
39include $(BUILD_MULTI_NONDEX_JAVA_LIBRARIES)
40
41local_install_packages += $(basename $(_install_jar_files))

 ./product/flounder32/obj/JAVA_LIBRARIES/com.amazon.h2contracts_intermediates
./product/flounder32/system/framework/com.amazon.h2contracts.jar
./common/obj/JAVA_LIBRARIES/com.amazon.h2contracts_intermediates As the jar file may be used by other components, so generate intermediates file for future usage.


In fireos/prebuilts/system/apks/debug/com.amazon.dp.contacts/Android.mk

9LOCAL_MODULE_TAGS         := optional
17LOCAL_MODULE              := com.amazon.dp.contacts
20LOCAL_CERTIFICATE := $(FIREOS_LOCAL_CERTIFICATE_OVERRIDE)
21
26LOCAL_MODULE_CLASS        := APPS
27LOCAL_MODULE_SUFFIX       := $(COMMON_ANDROID_PACKAGE_SUFFIX)
28LOCAL_PRIVILEGED_MODULE := true
39include $(BUILD_PREBUILT)

./product/flounder32/obj/APPS/com.amazon.dp.contacts_intermediates
./product/flounder32/system/priv-app/com.amazon.dp.contacts
./product/flounder32/system/priv-app/com.amazon.dp.contacts/com.amazon.dp.contacts.apk


In In fireos/packages/apps/Precog/Android.mk
8LOCAL_MODULE       := precog-api
9LOCAL_MODULE_TAGS  := optional
10LOCAL_MODULE_CLASS := JAVA_LIBRARIES
11LOCAL_JAVA_LIBRARIES := fireos.sdk.annotations
12
13LOCAL_SRC_FILES := \
14	src/main/java/com/amazon/precog/api/FeatureCallback.java \
21include $(BUILD_JAVA_LIBRARY)
./product/flounder32/obj/JAVA_LIBRARIES/precog-api_intermediates
./product/flounder32/system/framework/precog-api.jar
./common/obj/JAVA_LIBRARIES/precog-api_intermediates


In In fireos/packages/apps/FrankDvrServer/test/Android.mk

1LOCAL_PATH:= $(call my-dir)
2include $(CLEAR_VARS)
3
4LOCAL_PACKAGE_NAME := FrankMediaServerTest
5LOCAL_MODULE_TAGS := optional
6LOCAL_CERTIFICATE := platform
7LOCAL_PRIVILEGED_MODULE := true
8LOCAL_PROGUARD_ENABLED := disabled
9LOCAL_DEX_PREOPT := false
10
11LOCAL_SRC_FILES := $(call all-java-files-under, src)
15include $(BUILD_PACKAGE)
./product/flounder32/obj/APPS/FrankMediaServerTest_intermediates
./product/flounder32/system/priv-app/FrankMediaServerTest/FrankMediaServerTest.apk
./common/obj/APPS/FrankMediaServerTest_intermediates

In frameworks/opt/vcard/Android.mk
16include $(CLEAR_VARS)
19LOCAL_SDK_VERSION := 9
20
21LOCAL_MODULE := com.android.vcard
22LOCAL_SRC_FILES := $(call all-java-files-under, java)
23
24include $(BUILD_STATIC_JAVA_LIBRARY)

./common/obj/JAVA_LIBRARIES/com.android.vcard_intermediates

WITH_DEXPREOPT

所有的 apk 內包含一個 classes.dex 文件。

在 Dalvik上,apk包裏的 dex文件在安裝的時候會通過 dexopt 轉化成另一個格式,叫odex(Opitimized dex),然後存在 /data/dalvik-cache裏面,如:
  /data/dalvik-cache/data@[email protected]@classes.dex
雖然文件後綴還是 .dex,但是這個dex和apk內的那個已經不一樣了。這個文件是針對當前機器的硬件對 dex 文件進行了定製化,也就是說把這個放到別的設備上,不一定能運行。

PS: 在要編譯 rom 的時候,如果參數加上 "WITH_DEXPREOPT=true",會在 /system/app/ 下同時生成 .apk 和 .odex 文件(注意,這裏後綴又用的 .odex,但實際上和系統在 /data/dalvik-cache/ 下的 .dex文件是一樣的)

在 ART上,apk 包裏的 dex文件在安裝的時候通過 dex2oat,也會生成一個後綴爲 .dex 的文件,放在 /data/dalvik-cache中,如:
  /data/dalvik-cache/arm/system@app@[email protected]@classes.dex
  /data/dalvik-cache/arm64/system@vendor@app@[email protected]@classes.dex

這個文件後綴叫 .dex ,但是這個文件又不一樣了,這個既不是 dex 也不是 odex,用 dex2jar 的無法進行反編譯的。文件格式也完全不同,因爲這其實就是一個實打實的 elf文件,這個文件已經可以直接在機器上運行了。

WITH_DEXPREOPT使能編譯時生成 OAT,避免第一次開機時編譯耗時,但會增大 system分區的空間消耗


DONT_DEXPREOPT_PREBUILTS

  使能後,將不會對 Android.mk中包含了 include $(BUILD_PREBUILT)的 Apk進行 oat,例如 Gmail,它很可能會在後期通過商店自行升級,而升級後系統中的 oat文件則沒有意義了,但又無法刪除,會造成空間的浪費(oat比dex文件要大)

WITH_DEXPREOPT_BOOT_IMG_ONLY

  僅僅針對 boot.img進行oat優化(boot.img中包含 boot.art和 boot.oat)

LOCAL_DEX_PREOPT   (from DEX_PREOPT_DEFAULT)

value : ture | false | nostripping

  可用於各個 Android.mk,對每個 package進行單獨配置,當設置爲 true時,dex文件將會從 apk中剔除,如果不想剔除可使用 nostripping.

PRODUCT_DEX_PREOPT_BOOT_FLAGS

  這裏的參數將會傳至 dex2oat,控制 boot.img的編譯優化行爲。

PRODUCT_DEX_PREOPT_DEFAULT_FLAGS

  控制除 boot.img 外,其他(如 jar, apk)的 OAT編譯行爲 例如:

  PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := --compiler-filter=interpret-only
  $(call add-product-dex-preopt-module-config,services,--compiler-filter=space)

WITH_DEXPREOPT_PIC

ture|false

使能 position-independent code,這樣在dex2oat編譯生成的 odex文件在運行時將不必再從 /system 下拷貝到 /data/dalvik-cache/ 目錄下, 可以節省 /data 空間

WITH_ART_SMALL_MODE

true|false

  設置爲 true 時,將只編譯處於 boot classpath 裏的類,其他的均不編譯,這樣既能加快第一次開機時間,因爲大部分必要的類已經編譯過了; 同時也能節省不少空間,因爲 APP 都未進行編譯。缺點是可能損失一性能,這可能要平時覺察不出,但在跑分軟件上會有所體現

編譯選項的經典配置

  爲了提高第一次開機速度,WITH_DEXPREOPT是必須使能的,這樣則在編譯階段會完成 dex2oat的操作,避免在開機時間去做這個轉碼,節省了開機時間(6min以上縮短2min內)。

  但會引起一個缺點,那就是 apk中還是包含了class.dex(dexopt生成的),同時在對應的apk文件夾中又生成了已經轉碼成oat的 class.odex(dex2oat生成的),相當於這部分重複,造成了大量的空間浪費。

  爲了把 apk包裏的 class.dex去除,節省空間,可以打開 DEX PREOPT DEFAULT := ture。

  然而,這樣開機速度是快了,而且節省了不少system空間,但開機後,我們會發現即使在 system中已經存在 class.odex的 apk,第一次開機後還是會在 /data下面生成 class.odex,如data/dalvik-cache/arm64/system@app@[email protected]@classes.dex,這是何解?原來 Google爲了提高安全性,在每一臺機器開機時都會在之前的機器碼加一個隨機的偏移量,這個偏移量是隨機的,每臺機器都不相同,而 data分區下的這些文件就是從 system下的 class.odex加上偏移而來。

A ref: Android預優化那些事

Our preopt solution

We define a variable USE_FIREOS_DEFAULT_DEXPREOPT. User can set it to "true, false, userdata, cache". If not set, we set the value according to the environment.

367ifeq ($(HOST_OS),linux)
368  ifeq ($(TARGET_BUILD_VARIANT),user)
369    # Use the default dexpreopt parameters for user builds.
370    # Not all devices have sufficient space in system for this
371    # configuration to work on other variants. They will either
372    # not dexpreopt at all (like stock AOSP), or make some compromises
373    # to get some benefit from dexpreopt.
374    USE_FIREOS_DEFAULT_DEXPREOPT ?= userdata
375  else  # ! ifeq ($(TARGET_BUILD_VARIANT),user)
376  ifeq ($(TARGET_BUILD_VARIANT),userdebug)
377    USE_FIREOS_DEFAULT_DEXPREOPT ?= userdata
378  endif # ifeq ($(TARGET_BUILD_VARIANT),userdebug)
379  endif # ifeq ($(TARGET_BUILD_VARIANT),user)
380endif # ($(HOST_OS),linux)
381
382# Devices that need a minimal dexpreopt configuration, with only boot.art
383# and boot.oat installed in the system partition should also change the
384# default value of DEX_PREOPT_DEFAULT, typically:
385# DEX_PREOPT_DEFAULT := $(USE_FIREOS_DEFAULT_DEXPREOPT)
386# This will cause non-BOOTCLASSPATH jars and platform applications to
387# get compiled to userdata/cache instead of system. The default value is
388# purposely not overridden here because keeping as much precompiled code
389# in system as possible is optimal for overall storage efficiency and for
390# boot time after system OTA and factory reset.
391
392# Preserve documented AOSP behavior: if WITH_DEXPREOPT is false, we don't
393# want to enable any special FireOS dexpreopt behavior.
394ifeq ($(WITH_DEXPREOPT),false)
395  USE_FIREOS_DEFAULT_DEXPREOPT :=
396  DONT_DEXPREOPT_PREBUILTS := true
397  DEXPREOPT_PREBUILTS_INSTALL := false             this will be used as default value for LOCAL_DEX_PREOPT
398endif
399
400ifneq ($(USE_FIREOS_DEFAULT_DEXPREOPT),)
401  # shared settings for all FireOS dexpreopt modes
402  ifeq ($(filter-out userdata cache,$(USE_FIREOS_DEFAULT_DEXPREOPT)),)         if $(USE_FIREOS_DEFAULT_DEXPREOPT) contain userdata or cache
403    WITH_DEXPREOPT := true
404    # Use this file to indicate that this is a fresh flash.
405    FACTORY_PREOPT_FLAG_FILE := FACTORY_PREOPT
406    # Don't precompile files matching these patterns in
407    # LOCAL_MODULE_PATH.
408    # Note: do not use := here - this must be expanded at use
409    # in order for PRODUCT_OUT to expand correctly.
410    NEVER_DEXPREOPT_DIRS = $(PRODUCT_OUT)/mw_test_apps/%
411    # We should dexpreopt prebuilts unless explicitly overridden
412    DONT_DEXPREOPT_PREBUILTS ?= false
413  endif # ifeq ($(filter-out true userdata cache,$(USE_FIREOS_DEFAULT_DEXPREOPT)),)
414
415  ifeq ($(filter-out userdata,$(USE_FIREOS_DEFAULT_DEXPREOPT)),)     if $(USE_FIREOS_DEFAULT_DEXPREOPT) only contain userdata
416    # Install pre-compiled prebuilts to userdata.
417    DEXPREOPT_PREBUILTS_INSTALL := userdata
418    # Unsetting this should compile out run-time entry points for
419    # dalvik-cache in cache.
420    TARGET_DEXOPT_CACHEFS_SPACE_RESERVE :=
421  else  # ! ifeq ($(filter-out userdata,$(USE_FIREOS_DEFAULT_DEXPREOPT)),)
422  ifeq ($(USE_FIREOS_DEFAULT_DEXPREOPT),cache)     if $(USE_FIREOS_DEFAULT_DEXPREOPT) only contain cache
423    # Install pre-compiled prebuilts to cache.
424    DEXPREOPT_PREBUILTS_INSTALL := cache
425    # Space reserved in the cache partition for system OTA use in kilobytes.
426    # Dexopt should leave at least this much space free.
427    TARGET_DEXOPT_CACHEFS_SPACE_RESERVE ?= 256000
428  endif # ifeq ($(USE_FIREOS_DEFAULT_DEXPREOPT),cache)
429  endif # ifeq ($(filter-out userdata,$(USE_FIREOS_DEFAULT_DEXPREOPT)),)
430endif # ifneq ($(USE_FIREOS_DEFAULT_DEXPREOPT),)

131# If we don't already have an explicit LOCAL_DEX_PREOPT, set the
132# default from DEXPREOPT_PREBUILTS_INSTALL, if set.
133ifeq ($(LOCAL_DEX_PREOPT),)
134ifneq ($(DEXPREOPT_PREBUILTS_INSTALL),)
135LOCAL_DEX_PREOPT := $(DEXPREOPT_PREBUILTS_INSTALL)
136endif
137endif

1354define build-userdataimage-target
1355  $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
1356  @mkdir -p $(TARGET_OUT_DATA)
1358  $(if $(DEXPREOPT_PREBUILTS_INSTALL),\
1359    $(if $(filter-out cache userdata,$(DEXPREOPT_PREBUILTS_INSTALL)),,\
1360      $(hide) mkdir -p $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_ARCH) && \
1361      touch $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_ARCH)/$(FACTORY_PREOPT_FLAG_FILE) ; \
1362      $(if $(TARGET_2ND_ARCH),\
1363        mkdir -p $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_2ND_ARCH) && \
1364        touch $(TARGET_OUT_DATA)/dalvik-cache/$(TARGET_2ND_ARCH)/$(FACTORY_PREOPT_FLAG_FILE) \
1365      ) \
1366    ) \
1367  )
........................
1380endef

LOCAL_DEX_PREOPT initialize

115# Disable dex-preopt of prebuilts to save space, if requested.
116ifeq ($(DONT_DEXPREOPT_PREBUILTS),true)
117LOCAL_DEX_PREOPT := false
118endif
119
120ifneq ($(LOCAL_MODULE_PATH),)
121ifneq ($(NEVER_DEXPREOPT_DIRS),)
122# Test apps that are not pre-installed on the device are pointless to
123# dexpreopt. There may be more cases that should be excluded, so use
124# a general-purpose blacklist.
125ifeq ($(filter-out $(NEVER_DEXPREOPT_DIRS),$(LOCAL_MODULE_PATH)),)        if the module path is in the exclusive app list, don't do preopt.
126LOCAL_DEX_PREOPT := false
127endif
128endif
129endif
130
131# If we don't already have an explicit LOCAL_DEX_PREOPT, set the
132# default from DEXPREOPT_PREBUILTS_INSTALL, if set.
133ifeq ($(LOCAL_DEX_PREOPT),)
134ifneq ($(DEXPREOPT_PREBUILTS_INSTALL),)
135LOCAL_DEX_PREOPT := $(DEXPREOPT_PREBUILTS_INSTALL)
136endif
137endif
138
139# Don't use cache space for apps that are installed on userdata if the
140# default will generally write to cache.
141ifneq ($(LOCAL_MODULE_PATH),)
142ifeq ($(LOCAL_DEX_PREOPT)$(filter-out $(TARGET_OUT_DATA)/%,$(LOCAL_MODULE_PATH)), cache)
143LOCAL_DEX_PREOPT := userdata
144endif
145endif

207#######################################
208# defines built_odex along with rule to install odex
209include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
210#######################################

284ifeq ($(words $(PRODUCT_RUNTIMES)),1)
285  # If we only have one runtime, we can strip classes.dex by default during dex_preopt
286  DEX_PREOPT_DEFAULT := true
287else
288  # If we have more than one, we leave the classes.dex alone for post-boot analysis
289  DEX_PREOPT_DEFAULT := nostripping
290endif


In dex_preopt_odex_install.mk
5# Setting LOCAL_DEX_PREOPT based on WITH_DEXPREOPT, LOCAL_DEX_PREOPT, etc
6LOCAL_DEX_PREOPT := $(strip $(LOCAL_DEX_PREOPT))
7ifneq (true,$(WITH_DEXPREOPT))   not do dexopt by default
8  LOCAL_DEX_PREOPT :=
9else # WITH_DEXPREOPT=true
10  ifeq (,$(TARGET_BUILD_APPS)) # TARGET_BUILD_APPS empty
11    ifndef LOCAL_DEX_PREOPT # LOCAL_DEX_PREOPT undefined
12      ifneq ($(filter $(TARGET_OUT)/%,$(my_module_path)),) # Installed to system.img.
13        ifeq (,$(LOCAL_APK_LIBRARIES)) # LOCAL_APK_LIBRARIES empty
14          # If we have product-specific config for this module?
15          ifeq (disable,$(DEXPREOPT.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG))
16            LOCAL_DEX_PREOPT := false
17          else
18            LOCAL_DEX_PREOPT := $(DEX_PREOPT_DEFAULT)
19          endif
20        else # LOCAL_APK_LIBRARIES not empty
21          LOCAL_DEX_PREOPT := nostripping
22        endif # LOCAL_APK_LIBRARIES not empty
23      endif # Installed to system.img.
24    endif # LOCAL_DEX_PREOPT undefined
25  endif # TARGET_BUILD_APPS empty
26endif # WITH_DEXPREOPT=true
27ifeq (false,$(LOCAL_DEX_PREOPT))
28  LOCAL_DEX_PREOPT :=
29endif
30ifdef LOCAL_UNINSTALLABLE_MODULE
31LOCAL_DEX_PREOPT :=
32endif
33ifeq (,$(strip $(built_dex)$(my_prebuilt_src_file))) # contains no java code
34LOCAL_DEX_PREOPT :=
35endif
36# if module oat file requested in data, disable LOCAL_DEX_PREOPT, will default location to dalvik-cache
37ifneq (,$(filter $(LOCAL_MODULE),$(PRODUCT_DEX_PREOPT_PACKAGES_IN_DATA)))
38LOCAL_DEX_PREOPT :=
39endif
40# if WITH_DEXPREOPT_BOOT_IMG_ONLY=true and module is not in boot class path skip
41ifeq (true,$(WITH_DEXPREOPT_BOOT_IMG_ONLY))
42ifeq ($(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),)
43LOCAL_DEX_PREOPT :=
44endif
45endif

50ifdef LOCAL_DEX_PREOPT
51dexpreopt_boot_jar_module := $(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE))
52ifdef dexpreopt_boot_jar_module
53ifeq ($(DALVIK_VM_LIB),libdvm.so)
54built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
55installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex
56built_installed_odex := $(built_odex):$(installed_odex)
57else # libdvm.so
58# For libart, the boot jars' odex files are replaced by $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE).
59# We use this installed_odex trick to get boot.art installed.
60installed_odex := $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
61# Append the odex for the 2nd arch if we have one.
62installed_odex += $($(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)
63endif # libdvm.so
64else  # boot jar
65ifeq ($(DALVIK_VM_LIB),libdvm.so)
66built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex
67installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex
68built_installed_odex := $(built_odex):$(installed_odex)
69
70$(built_odex) : $(DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BOOT_PREOPT) \
71                $(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS)
72else # libart

74LOCAL_DEX2OAT_TARGET_ARCH := $(DEX2OAT_TARGET_ARCH)
75$(TARGET_2ND_ARCH_VAR_PREFIX)LOCAL_DEX2OAT_TARGET_ARCH := $($(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH)

141ifeq ($(LOCAL_DEX_PREOPT),cache)
142dexpreopt_install_root :=  $(TARGET_OUT_CACHE)/dalvik-cache/
143else ifeq ($(LOCAL_DEX_PREOPT),userdata)
144dexpreopt_install_root :=  $(TARGET_OUT_DATA)/dalvik-cache/
145else
146dexpreopt_install_root :=  $(dir $(LOCAL_INSTALLED_MODULE))
147endif
148
149# Use pattern rule - we may have multiple installed odex files.
150# Ugly syntax - See the definition get-odex-file-path.
151$(installed_odex) : $(dexpreopt_install_root)%$(notdir $(word 1,$(installed_odex))) \
152                  : $(dir $(LOCAL_BUILT_MODULE))%$(notdir $(word 1,$(built_odex))) \
153    | $(ACP)
154	$(call print-install,$@) #fosmod_build_extensions oneline
155	$(copy-file-to-target)
156endif

159# Add the installed_odex to the list of installed files for this module.
160ALL_MODULES.$(my_register_name).INSTALLED += $(installed_odex)
161ALL_MODULES.$(my_register_name).BUILT_INSTALLED += $(built_installed_odex)
162
163# Make sure to install the .odex when you run "make <module_name>"
164$(my_register_name): $(installed_odex)
165
166endif # LOCAL_DEX_PREOPT


220ifdef LOCAL_DEX_PREOPT
222# dexpreopt to cache and userdata should not strip classes.dex
223ifneq ($(filter-out nostripping cache userdata,$(LOCAL_DEX_PREOPT)),)
225	$(call dexpreopt-remove-classes.dex,$@)
226endif
227endif
228	$(align-package)
229
230###############################
231## Rule to build the odex file
232ifdef LOCAL_DEX_PREOPT
233$(built_odex) : $(my_prebuilt_src_file)
234	$(call dexpreopt-one-file,$<,$@)
235endif


odex是從APK中提取出來的可運行文件,即將APK中的class.dex文件通過

dex優化過程將其優化生成odex文件單獨存放。如果沒有odex,系統需要在開機過程中從APK內提取dex再運行;如果在build過程中預先提取,可加快系統啓動速度、節省開機時間

    一般情況下:

        User 版本會預先提取有source code的APK的odex文件,因爲有source code的APK在Android.mk中都會通過include $(BUILD_PACKAGE)來編譯,會調用到package.mk來提取odex

        但User版本不會預先提取通過prebuilt方式預置的APK的odex文件,因爲採用prebuilt方式預置APK是隻有APK文件而沒有source code時,在Android.mk中通過 include $(BUILD_PREBUILT)預置APK,代碼中原本的prebuilt.mk中不會提取odex

    方法:

    實現prebuilt APK提取odex的修改方法如下:修改build/core/prebuilt.mk

1.文件最開始部分添加紅色部分

ifneq (true,$(WITH_DEXPREOPT))

LOCAL_DEX_PREOPT :=

else

ifndef LOCAL_DEX_PREOPT

LOCAL_DEX_PREOPT := $(DEX_PREOPT_DEFAULT)

endif

endif

ifeq (false,$(LOCAL_DEX_PREOPT))

LOCAL_DEX_PREOPT :=

endif

ifeq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)

LOCAL_DEX_PREOPT :=

endif

$(info prebuild $(LOCAL_MODULE)==> $(LOCAL_DEX_PREOPT))

... ...

 

2.添加紅色部分

... ...

ifdef LOCAL_IS_HOST_MODULE

  my_prefix := HOST_

  LOCAL_DEX_PREOPT :=

else

  my_prefix := TARGET_

endif

... ...

 

3.添加紅色部分

... ...

ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)

ifdef LOCAL_DEX_PREOPT

$(built_module): $(DEXPREOPT_BOOT_ODEXS) | $(DEXPREOPT) $(DEXOPT)

endif

ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)

# Ensure that presigned .apks have been aligned.

$(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN)

 #$(transform-prebuilt-to-target-with-zipalign)

 $(transform-prebuilt-to-target)

ifdef LOCAL_DEX_PREOPT

 $(hide) rm -f $(patsubst %.apk,%.odex,$@)

 $(call dexpreopt-one-file,$@,$(patsubst %.apk,%.odex,$@))

ifneq (nostripping,$(LOCAL_DEX_PREOPT))

 $(call dexpreopt-remove-classes.dex,$@)

endif

endif

 $(align-package)

else

# Sign and align non-presigned .apks.

$(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR)

 $(transform-prebuilt-to-target)

 $(sign-package)

ifdef LOCAL_DEX_PREOPT

 $(hide) rm -f $(patsubst %.apk,%.odex,$@)

 $(call dexpreopt-one-file,$@,$(patsubst %.apk,%.odex,$@))

ifneq (nostripping,$(LOCAL_DEX_PREOPT))

 $(call dexpreopt-remove-classes.dex,$@)

endif

endif

 $(align-package)

endif

ifdef LOCAL_DEX_PREOPT

built_odex := $(basename $(built_module)).odex

$(built_odex): $(built_module)

endif

else

... ...

    注意:

    (1)user build默認開啓dexopt功能,eng build關閉,所以只是build user版本會提取APK的odex文件。

    (2)請務必不要忘記把預置的module添加到build/target/product/common.mk(或者[proj].mk)中的PRODUCT_PACKAGES裏面。

    (3)只有prebuilt預置APK時會生效,放置在vendor下拷貝的方式來預置APK是不會生效的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章