# dexpreopt_odex_install.mk is used to define odex creation rules for JARs and APKs # This file depends on variables set in base_rules.mk # Input variables: my_manifest_or_apk # Output variables: LOCAL_DEX_PREOPT, LOCAL_UNCOMPRESS_DEX
# We explicitly uncompress APKs of privileged apps, and used by # privileged apps ifneq (true,$(DONT_UNCOMPRESS_PRIV_APPS_DEXS)) ifeq (true,$(LOCAL_PRIVILEGED_MODULE))
LOCAL_UNCOMPRESS_DEX := true endif
ifndef LOCAL_DEX_PREOPT_GENERATE_PROFILE # If LOCAL_DEX_PREOPT_GENERATE_PROFILE is not defined, default it based on the existence of the # profile class listing. TODO: Use product specific directory here.
ifdef PRODUCT_DEX_PREOPT_PROFILE_DIR
LOCAL_DEX_PREOPT_PROFILE := $(PRODUCT_DEX_PREOPT_PROFILE_DIR)/$(LOCAL_MODULE).prof
ifeq (true,$(my_process_profile))
ifndef LOCAL_DEX_PREOPT_PROFILE
$(call pretty-error,Must have specified class listing (LOCAL_DEX_PREOPT_PROFILE)) endif ifeq (,$(dex_preopt_profile_src_file))
$(call pretty-error, Internal error: dex_preopt_profile_src_file must be set) endif endif
################################################################################ # Local module variables and functions used in dexpreopt and manifest_check. ################################################################################
# TODO(b/132357300): This may filter out too much, as PRODUCT_PACKAGES doesn't # include all packages (the full list is unknown until reading all Android.mk # makefiles). As a consequence, a library may be present but not included in # dexpreopt, which will result in class loader context mismatch and a failure # to load dexpreopt code on device. # However, we have to do filtering here. Otherwise, we may include extra # libraries that Soong and Make don't generate build rules for (e.g., a library # that exists in the source tree but not installable), and therefore get Ninja # errors. # We have deferred CLC computation to the Ninja phase, but the dependency # computation still needs to be done early. For now, this is the best we can do.
my_filtered_optional_uses_libraries := $(filter $(PRODUCT_PACKAGES), \
$(LOCAL_OPTIONAL_USES_LIBRARIES))
ifeq ($(LOCAL_MODULE_CLASS),APPS) # compatibility libraries are added to class loader context of an app only if # targetSdkVersion in the app's manifest is lower than the given SDK version
# Bootclasspath jars are accessible by all apps, so they don't have to and # should not be in the CLC. # For framework.jar, the name in `PRODUCT_BOOT_JARS` is `framework-minus-apex`, # so we need to use `FRAMEWORK_LIBRARIES`, which contains `framework`, to be # used for filtering.
my_all_boot_jars := \
$(foreach jar,$(PRODUCT_BOOT_JARS) $(PRODUCT_APEX_BOOT_JARS),$(call word-colon,2,$(jar))) \
$(FRAMEWORK_LIBRARIES)
# The order needs to be deterministic.
my_dexpreopt_libs_all := $(sort $(my_dexpreopt_libs) $(my_dexpreopt_libs_compat))
# Module dexpreopt.config depends on dexpreopt.config files of each # <uses-library> dependency, because these libraries may be processed after # the current module by Make (there's no topological order), so the dependency # information (paths, class loader context) may not be ready yet by the time # this dexpreopt.config is generated. So it's necessary to add file-level # dependencies between dexpreopt.config files.
my_dexpreopt_dep_configs := $(foreach lib, \
$(filter-out $(my_dexpreopt_libs_compat),$(my_dexpreopt_libs)), \
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,)/dexpreopt.config)
# 1: SDK version # 2: list of libraries # # Make does not process modules in topological order wrt. <uses-library> # dependencies, therefore we cannot rely on variables to get the information # about dependencies (in particular, their on-device path and class loader # context). This information is communicated via dexpreopt.config files: each # config depends on configs for <uses-library> dependencies of this module, # and the dex_preopt_config_merger.py script reads all configs and inserts the # missing bits from dependency configs into the module config. # # By default on-device path is /system/framework/*.jar, and class loader # subcontext is empty. These values are correct for compatibility libraries, # which are special and not handled by dex_preopt_config_merger.py. #
add_json_class_loader_context = \
$(call add_json_array, $(1)) \
$(foreach lib, $(2),\
$(call add_json_map_anon) \
$(call add_json_str, Name, $(lib)) \
$(call add_json_str, Host, $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
$(call add_json_str, Device, /system/framework/$(lib).jar) \
$(call add_json_val, Subcontexts, null) \
$(call end_json_map)) \
$(call end_json_array)
################################################################################ # Verify <uses-library> coherence between the build system and the manifest. ################################################################################
# Some libraries do not have a manifest, so there is nothing to check against. # Handle it as if the manifest had zero <uses-library> tags: it is ok unless the # module has non-empty LOCAL_USES_LIBRARIES or LOCAL_OPTIONAL_USES_LIBRARIES.
ifndef my_manifest_or_apk ifneq (,$(strip $(LOCAL_USES_LIBRARIES)$(LOCAL_OPTIONAL_USES_LIBRARIES)))
$(error $(LOCAL_MODULE) has non-empty <uses-library> list but no manifest) else
LOCAL_ENFORCE_USES_LIBRARIES := false endif endif
# Disable the check for tests. ifneq (,$(filter $(LOCAL_MODULE_TAGS),tests))
LOCAL_ENFORCE_USES_LIBRARIES := false endif ifneq (,$(LOCAL_COMPATIBILITY_SUITE))
LOCAL_ENFORCE_USES_LIBRARIES := false
# Enable the check for WTS ifneq ($(filter wts,$(LOCAL_COMPATIBILITY_SUITE)),)
LOCAL_ENFORCE_USES_LIBRARIES := true endif
endif
# Disable the check if the app contains no java code. ifeq (,$(strip $(built_dex)$(my_prebuilt_src_file)$(LOCAL_SOONG_DEX_JAR)))
LOCAL_ENFORCE_USES_LIBRARIES := false endif
# Disable <uses-library> checks if dexpreopt is globally disabled. # Without dexpreopt the check is not necessary, and although it is good to have, # it is difficult to maintain on non-linux build platforms where dexpreopt is # generally disabled (the check may fail due to various unrelated reasons, such # as a failure to get manifest from an APK). ifneq (true,$(WITH_DEXPREOPT))
LOCAL_ENFORCE_USES_LIBRARIES := false elseifeq (true,$(WITH_DEXPREOPT_ART_BOOT_IMG_ONLY))
LOCAL_ENFORCE_USES_LIBRARIES := false endif
# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES against the manifest.
ifndef LOCAL_ENFORCE_USES_LIBRARIES
LOCAL_ENFORCE_USES_LIBRARIES := true endif
# dexpreopt is disabled when TARGET_BUILD_UNBUNDLED_IMAGE is true, # but dexpreopt config files are required to dexpreopt in post-processing. ifeq ($(TARGET_BUILD_UNBUNDLED_IMAGE),true)
my_create_dexpreopt_config := true endif
ifeq ($(my_create_dexpreopt_config), true) ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
my_module_multilib := $(LOCAL_MULTILIB) # If the module is not an SDK library and it's a system server jar, only preopt the primary arch. ifeq (,$(filter $(JAVA_SDK_LIBRARIES),$(LOCAL_MODULE))) # For a Java library, by default we build odex for both 1st arch and 2nd arch. # But it can be overridden with "LOCAL_MULTILIB := first". ifneq (,$(filter $(PRODUCT_SYSTEM_SERVER_JARS),$(LOCAL_MODULE))) # For system server jars, we build for only "first".
my_module_multilib := first endif endif
# Only preopt primary arch for translated arch since there is only an image there. ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
my_module_multilib := first endif
# ################################################# # Odex for the 1st arch
my_dexpreopt_archs += $(TARGET_ARCH)
my_dexpreopt_images += $(DEXPREOPT_IMAGE_$(my_dexpreopt_infix)_$(TARGET_ARCH))
my_dexpreopt_images_deps += $(DEXPREOPT_IMAGE_DEPS_$(my_dexpreopt_infix)_$(TARGET_ARCH)) # Odex for the 2nd arch
ifdef TARGET_2ND_ARCH ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true) ifneq (first,$(my_module_multilib))
my_dexpreopt_archs += $(TARGET_2ND_ARCH)
my_dexpreopt_images += $(DEXPREOPT_IMAGE_$(my_dexpreopt_infix)_$(TARGET_2ND_ARCH))
my_dexpreopt_images_deps += $(DEXPREOPT_IMAGE_DEPS_$(my_dexpreopt_infix)_$(TARGET_2ND_ARCH)) endif# my_module_multilib is not first. endif# TARGET_TRANSLATE_2ND_ARCH not true endif# TARGET_2ND_ARCH # ################################################# else# must be APPS # The preferred arch # Save the module multilib since setup_one_odex modifies it.
my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
my_dexpreopt_archs += $(TARGET_$(my_2nd_arch_prefix)ARCH)
my_dexpreopt_images += \
$(DEXPREOPT_IMAGE_$(my_dexpreopt_infix)_$(TARGET_$(my_2nd_arch_prefix)ARCH))
my_dexpreopt_images_deps += \
$(DEXPREOPT_IMAGE_DEPS_$(my_dexpreopt_infix)_$(TARGET_$(my_2nd_arch_prefix)ARCH))
ifdef TARGET_2ND_ARCH ifeq ($(my_module_multilib),both) # The non-preferred arch
my_2nd_arch_prefix := $(if $(LOCAL_2ND_ARCH_VAR_PREFIX),,$(TARGET_2ND_ARCH_VAR_PREFIX))
my_dexpreopt_archs += $(TARGET_$(my_2nd_arch_prefix)ARCH)
my_dexpreopt_images += \
$(DEXPREOPT_IMAGE_$(my_dexpreopt_infix)_$(TARGET_$(my_2nd_arch_prefix)ARCH))
my_dexpreopt_images_deps += \
$(DEXPREOPT_IMAGE_DEPS_$(my_dexpreopt_infix)_$(TARGET_$(my_2nd_arch_prefix)ARCH)) endif# LOCAL_MULTILIB is both endif# TARGET_2ND_ARCH endif# LOCAL_MODULE_CLASS
# System server jars defined in Android.mk are deprecated. ifneq (true, $(PRODUCT_BROKEN_DEPRECATED_MK_SYSTEM_SERVER_JARS)) ifneq (,$(filter %:$(LOCAL_MODULE), $(PRODUCT_SYSTEM_SERVER_JARS) $(PRODUCT_APEX_SYSTEM_SERVER_JARS)))
$(error System server jars defined in Android.mk are deprecated. \
Convert $(LOCAL_MODULE) to Android.bp or temporarily disable the error \
with 'PRODUCT_BROKEN_DEPRECATED_MK_SYSTEM_SERVER_JARS := true') endif endif
ifdef LOCAL_DEX_PREOPT # System server jars must be copied into predefined locations expected by # dexpreopt. Copy rule must be exposed to Ninja (as it uses these files as # inputs), so it cannot go in dexpreopt.sh. ifneq (,$(filter %:$(LOCAL_MODULE), $(PRODUCT_SYSTEM_SERVER_JARS)))
my_dexpreopt_jar_copy := $(OUT_DIR)/soong/system_server_dexjars/$(LOCAL_MODULE).jar
$(my_dexpreopt_jar_copy): PRIVATE_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
$(my_dexpreopt_jar_copy): $(LOCAL_BUILT_MODULE)
@cp $(PRIVATE_BUILT_MODULE) $@ endif
# The root "product_packages.txt" is generated by `build/make/core/Makefile`. It contains a list # of all packages that are installed on the device. We use `grep` to filter the list by the app's # dependencies to create a per-app list, and use `rsync --checksum` to prevent the file's mtime # from being changed if the contents don't change. This avoids unnecessary dexpreopt reruns.
my_dexpreopt_product_packages := $(intermediates)/product_packages.txt
.KATI_RESTAT: $(my_dexpreopt_product_packages)
$(my_dexpreopt_product_packages): PRIVATE_MODULE := $(LOCAL_MODULE)
$(my_dexpreopt_product_packages): PRIVATE_LIBS := $(my_dexpreopt_libs_all)
$(my_dexpreopt_product_packages): PRIVATE_STAGING := $(my_dexpreopt_product_packages).tmp
$(my_dexpreopt_product_packages): $(PRODUCT_OUT)/product_packages.txt
@echo"$(PRIVATE_MODULE) dexpreopt product_packages" ifneq (,$(my_dexpreopt_libs_all))
grep -F -x \
$(addprefix -e ,$(PRIVATE_LIBS)) \
$(PRODUCT_OUT)/product_packages.txt \
> $(PRIVATE_STAGING) \
|| true else rm -f $(PRIVATE_STAGING) && touch $(PRIVATE_STAGING) endif
rsync --checksum $(PRIVATE_STAGING) $@
# We need to add all the installed files to ALL_MODULES.$(my_register_name).INSTALLED in order # for the build system to properly track installed files. (for sbom, installclean, etc) # We install all the files in a zip file generated at execution time, which means we have to guess # what's going to be in that zip file before it's created. We then check at executation time that # our guess is correct. # _system_other corresponds to OdexOnSystemOtherByName() in soong. # The other paths correspond to dexpreoptCommand()
_dexlocation := $(patsubst $(PRODUCT_OUT)/%,%,$(LOCAL_INSTALLED_MODULE))
_dexname := $(basename $(notdir $(_dexlocation)))
_system_other := $(strip $(if $(strip $(BOARD_USES_SYSTEM_OTHER_ODEX)), \
$(if $(strip $(SANITIZE_LITE)),, \
$(if $(filter $(_dexname),$(PRODUCT_SYSTEM_SERVER_APPS)),, \
$(if $(strip $(foreach myfilter,$(SYSTEM_OTHER_ODEX_FILTER),$(filter system/$(myfilter),$(_dexlocation))$(filter $(myfilter),$(_dexlocation)))), \
system_other/))))) # _dexdir has a trailing /
_dexdir := $(_system_other)$(dir $(_dexlocation))
my_dexpreopt_zip_contents := $(sort \
$(foreach arch,$(my_dexpreopt_archs), \
$(_dexdir)oat/$(arch)/$(_dexname).odex \
$(_dexdir)oat/$(arch)/$(_dexname).vdex \
$(if $(filter false,$(LOCAL_DEX_PREOPT_APP_IMAGE)),, \
$(if $(my_process_profile)$(filter true,$(LOCAL_DEX_PREOPT_APP_IMAGE)), \
$(_dexdir)oat/$(arch)/$(_dexname).art))) \
$(if $(my_process_profile),$(_dexlocation).prof))
_dexlocation :=
_dexdir :=
_dexname :=
_system_other :=
my_dexpreopt_zip := $(intermediates)/dexpreopt.zip
$(my_dexpreopt_zip): PRIVATE_MODULE := $(LOCAL_MODULE)
$(my_dexpreopt_zip): $(my_dexpreopt_deps)
$(my_dexpreopt_zip): | $(DEXPREOPT_GEN_DEPS)
$(my_dexpreopt_zip): .KATI_DEPFILE := $(my_dexpreopt_zip).d
$(my_dexpreopt_zip): PRIVATE_DEX := $(my_dex_jar)
$(my_dexpreopt_zip): PRIVATE_SCRIPT := $(my_dexpreopt_script)
$(my_dexpreopt_zip): PRIVATE_ZIP_CONTENTS := $(my_dexpreopt_zip_contents)
$(my_dexpreopt_zip): $(my_dexpreopt_script)
@echo"$(PRIVATE_MODULE) dexpreopt" rm -f $@ echo -n > $@.contents
$(foreach f,$(PRIVATE_ZIP_CONTENTS),echo"$(f)" >> $@.contents$(newline))
bash $(PRIVATE_SCRIPT) $(PRIVATE_DEX) $@ if ! diff <(zipinfo -1 $@ | sort) $@.contents >&2; then \ echo"Contents of $@ did not match what make was expecting." >&2 && exit 1; \ fi
# Normally this happens in sbom.mk, which is included from base_rules.mk. But since # dex_preopt_odex_install.mk is included after base_rules.mk, it misses these odex files.
$(foreach installed_file,$(addprefix $(PRODUCT_OUT)/,$(my_dexpreopt_zip_contents)), \
$(eval ALL_INSTALLED_FILES.$(installed_file) := $(my_register_name)))
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.