Merge "Revert "Temporarily remove the care_map in the ota package""
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 639c4ef..957da92 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -760,6 +760,19 @@
# Common R directory has been removed.
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/R)
+# Most of SOONG_HOST_OUT_EXECUTABLES has been moved to HOST_OUT_EXECUTABLES
+$(call add-clean-step, rm -rf $(SOONG_HOST_OUT))
+
+# More of SOONG_HOST_OUT_EXECUTABLES has been moved to HOST_OUT_EXECUTABLES
+$(call add-clean-step, rm -rf $(SOONG_HOST_OUT))
+
+# More of SOONG_HOST_OUT_EXECUTABLES has been moved to HOST_OUT_EXECUTABLES
+$(call add-clean-step, rm -rf $(SOONG_HOST_OUT))
+
+# Last of SOONG_HOST_OUT_EXECUTABLES has been moved to HOST_OUT_EXECUTABLES
+# Don't use SOONG_HOST_OUT, it is now an alias for HOST_OUT.
+$(call add-clean-step, rm -rf $(OUT_DIR)/soong/host)
+
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/common/math.mk b/common/math.mk
index ec15f88..0271ea8 100644
--- a/common/math.mk
+++ b/common/math.mk
@@ -121,14 +121,26 @@
$(lastword $(filter $(1) $(2),$(__MATH_NUMBERS))))
endef
+# Returns the lesser of $1 or $2.
+define math_min
+$(strip $(call _math_check_valid,$(1)) $(call _math_check_valid,$(2)) \
+ $(firstword $(filter $(1) $(2),$(__MATH_NUMBERS))))
+endef
+
$(call math-expect-error,(call math_max),Argument missing)
$(call math-expect-error,(call math_max,1),Argument missing)
$(call math-expect-error,(call math_max,1 2,3),Multiple words in a single argument: 1 2)
+$(call math-expect-error,(call math_min,1,2 3),Multiple words in a single argument: 2 3)
$(call math-expect,(call math_max,0,1),1)
$(call math-expect,(call math_max,1,0),1)
$(call math-expect,(call math_max,1,1),1)
$(call math-expect,(call math_max,5,42),42)
$(call math-expect,(call math_max,42,5),42)
+$(call math-expect,(call math_min,0,1),0)
+$(call math-expect,(call math_min,1,0),0)
+$(call math-expect,(call math_min,1,1),1)
+$(call math-expect,(call math_min,7,32),7)
+$(call math-expect,(call math_min,32,7),7)
define math_gt_or_eq
$(if $(filter $(1),$(call math_max,$(1),$(2))),true)
diff --git a/core/Makefile b/core/Makefile
index 486188e..37d09f5 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -527,6 +527,16 @@
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,GENERIC_RAMDISK,$(TARGET_RAMDISK_OUT),,modules.load,,$(kmd)))))
# -----------------------------------------------------------------
+# FSVerity metadata generation
+ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
+
+FSVERITY_APK_KEY_PATH := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
+FSVERITY_APK_OUT := system/etc/security/fsverity/BuildManifest.apk
+FSVERITY_APK_MANIFEST_PATH := system/security/fsverity/AndroidManifest.xml
+
+endif # PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA
+
+# -----------------------------------------------------------------
# Cert-to-package mapping. Used by the post-build signing tools.
# Use a macro to add newline to each echo command
# $1 stem name of the package
@@ -575,6 +585,8 @@
$(if $(PACKAGES.$(p).EXTERNAL_KEY),\
$(call _apkcerts_write_line,$(PACKAGES.$(p).STEM),EXTERNAL,,$(PACKAGES.$(p).COMPRESSED),$(PACKAGES.$(p).PARTITION),$@),\
$(call _apkcerts_write_line,$(PACKAGES.$(p).STEM),$(PACKAGES.$(p).CERTIFICATE),$(PACKAGES.$(p).PRIVATE_KEY),$(PACKAGES.$(p).COMPRESSED),$(PACKAGES.$(p).PARTITION),$@))))
+ $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),\
+ $(call _apkcerts_write_line,$(notdir $(basename $(FSVERITY_APK_OUT))),$(FSVERITY_APK_KEY_PATH).x509.pem,$(FSVERITY_APK_KEY_PATH).pk8,,system,$@))
# In case value of PACKAGES is empty.
$(hide) touch $@
@@ -1672,6 +1684,11 @@
$(if $(filter $(2),system),\
$(if $(INTERNAL_SYSTEM_OTHER_PARTITION_SIZE),$(hide) echo "system_other_size=$(INTERNAL_SYSTEM_OTHER_PARTITION_SIZE)" >> $(1))
$(if $(PRODUCT_SYSTEM_HEADROOM),$(hide) echo "system_headroom=$(PRODUCT_SYSTEM_HEADROOM)" >> $(1))
+ $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity=$(HOST_OUT_EXECUTABLES)/fsverity" >> $(1))
+ $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_generate_metadata=true" >> $(1))
+ $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_key=$(FSVERITY_APK_KEY_PATH)" >> $(1))
+ $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_manifest=$(FSVERITY_APK_MANIFEST_PATH)" >> $(1))
+ $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_out=$(FSVERITY_APK_OUT)" >> $(1))
$(call add-common-ro-flags-to-image-props,system,$(1))
)
$(if $(filter $(2),system_other),\
@@ -1892,14 +1909,18 @@
recovery_sepolicy := \
$(TARGET_RECOVERY_ROOT_OUT)/sepolicy \
$(TARGET_RECOVERY_ROOT_OUT)/plat_file_contexts \
+ $(TARGET_RECOVERY_ROOT_OUT)/plat_service_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/plat_property_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/system_ext_file_contexts \
+ $(TARGET_RECOVERY_ROOT_OUT)/system_ext_service_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/system_ext_property_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/vendor_file_contexts \
+ $(TARGET_RECOVERY_ROOT_OUT)/vendor_service_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/vendor_property_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/odm_file_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/odm_property_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/product_file_contexts \
+ $(TARGET_RECOVERY_ROOT_OUT)/product_service_contexts \
$(TARGET_RECOVERY_ROOT_OUT)/product_property_contexts
# Passed into rsync from non-recovery root to recovery root, to avoid overwriting recovery-specific
@@ -2773,6 +2794,10 @@
ifeq ($(BOARD_AVB_ENABLE),true)
$(BUILT_SYSTEMIMAGE): $(BOARD_AVB_SYSTEM_KEY_PATH)
endif
+ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
+$(BUILT_SYSTEMIMAGE): $(HOST_OUT_EXECUTABLES)/fsverity $(HOST_OUT_EXECUTABLES)/aapt2 \
+ $(FSVERITY_APK_MANIFEST_PATH) $(FSVERITY_APK_KEY_PATH).x509.pem $(FSVERITY_APK_KEY_PATH).pk8
+endif
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
$(call build-systemimage-target,$@)
@@ -4710,6 +4735,7 @@
ifeq ($(AB_OTA_UPDATER),true)
updater_dep := system/update_engine/update_engine.conf
+updater_dep := external/zucchini/version_info.h
endif
# Build OTA tools if non-A/B is allowed
@@ -5183,6 +5209,7 @@
ifeq ($(AB_OTA_UPDATER),true)
@# When using the A/B updater, include the updater config files in the zip.
$(hide) cp $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt
+ $(hide) cp $(TOPDIR)external/zucchini/version_info.h $(zip_root)/META/zucchini_config.txt
$(hide) for part in $(strip $(AB_OTA_PARTITIONS)); do \
echo "$${part}" >> $(zip_root)/META/ab_partitions.txt; \
done
@@ -5433,6 +5460,8 @@
ifeq ($(BUILD_OS),linux)
ifneq ($(DEX2OAT),)
dexpreopt_tools_deps := $(DEXPREOPT_GEN_DEPS) $(DEXPREOPT_GEN) $(AAPT2)
+dexpreopt_tools_deps += $(HOST_OUT_EXECUTABLES)/dexdump
+dexpreopt_tools_deps += $(HOST_OUT_EXECUTABLES)/oatdump
DEXPREOPT_TOOLS_ZIP := $(PRODUCT_OUT)/dexpreopt_tools.zip
$(DEXPREOPT_TOOLS_ZIP): $(dexpreopt_tools_deps)
$(DEXPREOPT_TOOLS_ZIP): PRIVATE_DEXPREOPT_TOOLS_DEPS := $(dexpreopt_tools_deps)
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index ee15b75..7bea305 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -32,7 +32,12 @@
$(call add_soong_config_var,ANDROID,BOARD_BUILD_SYSTEM_ROOT_IMAGE)
$(call add_soong_config_var,ANDROID,PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT)
-ifeq (,$(findstring com.google.android.conscrypt,$(PRODUCT_PACKAGES)))
+ifneq (,$(filter sdk win_sdk sdk_addon,$(MAKECMDGOALS)))
+ # The artifacts in the SDK zip are OK to build with prebuilt stubs enabled,
+ # even if prebuilt apexes are not enabled, because the system images in the
+ # SDK stub are not currently used (and will be removed: b/205008975).
+ MODULE_BUILD_FROM_SOURCE ?= false
+else ifeq (,$(findstring com.google.android.conscrypt,$(PRODUCT_PACKAGES)))
# Prebuilt module SDKs require prebuilt modules to work, and currently
# prebuilt modules are only provided for com.google.android.xxx. If we can't
# find one of them in PRODUCT_PACKAGES then assume com.android.xxx are in use,
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 23a1616..134cb8f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -514,30 +514,26 @@
###########################################################
my_installed_symlinks :=
-my_default_test_module :=
-ifeq ($(use_testcase_folder),true)
-arch_dir := $($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
-my_default_test_module := $($(my_prefix)OUT_TESTCASES)/$(LOCAL_MODULE)/$(arch_dir)/$(my_installed_module_stem)
-arch_dir :=
-endif
ifneq (,$(LOCAL_SOONG_INSTALLED_MODULE))
# Soong already generated the copy rule, but make the installed location depend on the Make
# copy of the intermediates for now, as some rules that collect intermediates may expect
# them to exist.
$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
+
+ $(foreach symlink, $(LOCAL_SOONG_INSTALL_SYMLINKS), \
+ $(call declare-0p-target,$(symlink)))
+ $(my_all_targets) : | $(LOCAL_SOONG_INSTALL_SYMLINKS)
else ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
- ifneq ($(LOCAL_INSTALLED_MODULE),$(my_default_test_module))
- $(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
- $(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
+ $(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
+ $(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
@echo "Install: $@"
- ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
$(copy-file-or-link-to-new-target)
- else
+ else
$(copy-file-to-new-target)
- endif
- $(PRIVATE_POST_INSTALL_CMD)
endif
+ $(PRIVATE_POST_INSTALL_CMD)
# Rule to install the module's companion symlinks
my_installed_symlinks := $(addprefix $(my_module_path)/,$(LOCAL_MODULE_SYMLINKS) $(LOCAL_MODULE_SYMLINKS_$(my_32_64_bit_suffix)))
@@ -735,8 +731,9 @@
# The module itself.
$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
- $(eval my_compat_dist_$(suite) := $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
- $(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem))) \
+ $(eval my_compat_dist_$(suite) := $(patsubst %:$(LOCAL_INSTALLED_MODULE),$(LOCAL_INSTALLED_MODULE):$(LOCAL_INSTALLED_MODULE),\
+ $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
+ $(LOCAL_BUILT_MODULE):$(dir)/$(my_installed_module_stem)))) \
$(eval my_compat_dist_config_$(suite) := ))
@@ -935,9 +932,13 @@
# of files provided by this module. Used by custom packaging rules like
# package-modules.mk that need to copy the built files to a custom install
# location during packaging.
+ #
+ # Translate copies from $(LOCAL_PREBUILT_MODULE_FILE) to $(LOCAL_BUILT_MODULE)
+ # so that package-modules.mk gets any transtive dependencies added to
+ # $(LOCAL_BUILT_MODULE), for example unstripped symbols files.
ALL_MODULES.$(my_register_name).BUILT_INSTALLED := \
$(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED) \
- $(LOCAL_SOONG_INSTALL_PAIRS) \
+ $(patsubst $(LOCAL_PREBUILT_MODULE_FILE):%,$(LOCAL_BUILT_MODULE):%,$(LOCAL_SOONG_INSTALL_PAIRS)) \
$(my_init_rc_pairs) \
$(my_test_data_pairs) \
$(my_vintf_pairs))
@@ -1071,7 +1072,7 @@
##########################################################
# Track module-level dependencies.
# Use $(LOCAL_MODULE) instead of $(my_register_name) to ignore module's bitness.
-ifdef RECORD_ALL_DEPS
+# (b/204397180) Unlock RECORD_ALL_DEPS was acknowledged reasonable for better Atest performance.
ALL_DEPS.MODULES += $(LOCAL_MODULE)
ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(sort \
$(ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS) \
@@ -1088,7 +1089,6 @@
license_files := $(call find-parent-file,$(LOCAL_PATH),MODULE_LICENSE*)
ALL_DEPS.$(LOCAL_MODULE).LICENSE := $(sort $(ALL_DEPS.$(LOCAL_MODULE).LICENSE) $(license_files))
-endif
###########################################################
## Take care of my_module_tags
diff --git a/core/board_config.mk b/core/board_config.mk
index 40b6b3f..15a9944 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -185,19 +185,42 @@
.KATI_READONLY := TARGET_DEVICE_DIR
endif
+# Dumps all variables that match [A-Z][A-Z0-9_]* to the file at $(1)
+# It is used to print only the variables that are likely to be relevant to the
+# board configuration.
+define dump-public-variables
+$(file >$(OUT_DIR)/dump-public-variables-temp.txt,$(subst $(space),$(newline),$(.VARIABLES)))\
+$(file >$(1),\
+$(foreach v, $(shell grep -he "^[A-Z][A-Z0-9_]*$$" $(OUT_DIR)/dump-public-variables-temp.txt | grep -vhE "^(SOONG_.*|LOCAL_PATH|TOPDIR|PRODUCT_COPY_OUT_.*)$$"),\
+$(v) := $(strip $($(v)))$(newline)))
+endef
+
# TODO(colefaust) change this if to RBC_PRODUCT_CONFIG when
# the board configuration is known to work on everything
# the product config works on.
ifndef RBC_BOARD_CONFIG
include $(board_config_mk)
else
- rc := $(shell build/soong/scripts/rbc-run $(board_config_mk) \
- BUILDING_GSI=$(BUILDING_GSI) >$(OUT_DIR)/rbcboardtemp.mk || echo $$?)
- ifneq (,$(rc))
- $(error board configuration converter failed: $(rc))
+ $(shell mkdir -p $(OUT_DIR)/rbc)
+
+ $(call dump-public-variables, $(OUT_DIR)/rbc/make_vars_pre_board_config.mk)
+
+ $(shell $(OUT_DIR)/soong/mk2rbc \
+ --mode=write -r --outdir $(OUT_DIR)/rbc \
+ --boardlauncher=$(OUT_DIR)/rbc/boardlauncher.rbc \
+ --input_variables=$(OUT_DIR)/rbc/make_vars_pre_board_config.mk \
+ $(board_config_mk))
+ ifneq ($(.SHELLSTATUS),0)
+ $(error board configuration converter failed: $(.SHELLSTATUS))
endif
- include $(OUT_DIR)/rbcboardtemp.mk
+ $(shell build/soong/scripts/update_out $(OUT_DIR)/rbc/rbc_board_config_results.mk \
+ $(OUT_DIR)/soong/rbcrun RBC_OUT="make,global" $(OUT_DIR)/rbc/boardlauncher.rbc)
+ ifneq ($(.SHELLSTATUS),0)
+ $(error board configuration runner failed: $(.SHELLSTATUS))
+ endif
+
+ include $(OUT_DIR)/rbc/rbc_board_config_results.mk
endif
ifneq (,$(and $(TARGET_ARCH),$(TARGET_ARCH_SUITE)))
diff --git a/core/config.mk b/core/config.mk
index 8f47ab5..7c93610 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -304,7 +304,7 @@
endef
# soong_config_append appends to the value of the variable in the given Soong
-# config namespace. If the varabile does not exist, it will be defined. If the
+# config namespace. If the variable does not exist, it will be defined. If the
# namespace does not exist, it will be defined.
# $1 is the namespace, $2 is the variable name, $3 is the value
define soong_config_append
@@ -312,6 +312,14 @@
$(eval SOONG_CONFIG_$(strip $1)_$(strip $2):=$(SOONG_CONFIG_$(strip $1)_$(strip $2)) $3)
endef
+# soong_config_append gets to the value of the variable in the given Soong
+# config namespace. If the namespace or variables does not exist, an
+# empty string will be returned.
+# $1 is the namespace, $2 is the variable name
+define soong_config_get
+$(SOONG_CONFIG_$(strip $1)_$(strip $2))
+endef
+
# Set the extensions used for various packages
COMMON_PACKAGE_SUFFIX := .zip
COMMON_JAVA_PACKAGE_SUFFIX := .jar
@@ -539,14 +547,14 @@
ACP := $(prebuilt_build_tools_bin)/acp
CKATI := $(prebuilt_build_tools_bin)/ckati
DEPMOD := $(HOST_OUT_EXECUTABLES)/depmod
-FILESLIST := $(SOONG_HOST_OUT_EXECUTABLES)/fileslist
+FILESLIST := $(HOST_OUT_EXECUTABLES)/fileslist
FILESLIST_UTIL :=$= build/make/tools/fileslist_util.py
HOST_INIT_VERIFIER := $(HOST_OUT_EXECUTABLES)/host_init_verifier
-XMLLINT := $(SOONG_HOST_OUT_EXECUTABLES)/xmllint
+XMLLINT := $(HOST_OUT_EXECUTABLES)/xmllint
# SOONG_ZIP is exported by Soong, but needs to be defined early for
# $OUT/dexpreopt.global. It will be verified against the Soong version.
-SOONG_ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/soong_zip
+SOONG_ZIP := $(HOST_OUT_EXECUTABLES)/soong_zip
# ---------------------------------------------------------------
# Generic tools.
@@ -753,13 +761,16 @@
endif
.KATI_READONLY := BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES
-min_systemsdk_version := $(firstword $(BOARD_API_LEVEL) $(BOARD_SHIPPING_API_LEVEL) $(PRODUCT_SHIPPING_API_LEVEL))
-ifneq (,$(min_systemsdk_version))
-ifneq ($(call numbers_less_than,$(min_systemsdk_version),$(BOARD_SYSTEMSDK_VERSIONS)),)
- $(error BOARD_SYSTEMSDK_VERSIONS ($(BOARD_SYSTEMSDK_VERSIONS)) must all be greater than or equal to BOARD_API_LEVEL, BOARD_SHIPPING_API_LEVEL or PRODUCT_SHIPPING_API_LEVEL ($(min_systemsdk_version)))
-endif
-endif
ifdef PRODUCT_SHIPPING_API_LEVEL
+ board_api_level := $(firstword $(BOARD_API_LEVEL) $(BOARD_SHIPPING_API_LEVEL))
+ ifneq (,$(board_api_level))
+ min_systemsdk_version := $(call math_min,$(board_api_level),$(PRODUCT_SHIPPING_API_LEVEL))
+ else
+ min_systemsdk_version := $(PRODUCT_SHIPPING_API_LEVEL)
+ endif
+ ifneq ($(call numbers_less_than,$(min_systemsdk_version),$(BOARD_SYSTEMSDK_VERSIONS)),)
+ $(error BOARD_SYSTEMSDK_VERSIONS ($(BOARD_SYSTEMSDK_VERSIONS)) must all be greater than or equal to BOARD_API_LEVEL, BOARD_SHIPPING_API_LEVEL or PRODUCT_SHIPPING_API_LEVEL ($(min_systemsdk_version)))
+ endif
ifneq ($(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),28),)
ifneq ($(TARGET_IS_64_BIT), true)
ifneq ($(TARGET_USES_64_BIT_BINDER), true)
@@ -1212,7 +1223,4 @@
DEFAULT_DATA_OUT_MODULES := ltp $(ltp_packages) $(kselftest_modules)
.KATI_READONLY := DEFAULT_DATA_OUT_MODULES
-# Make RECORD_ALL_DEPS readonly.
-RECORD_ALL_DEPS :=$= $(filter true,$(RECORD_ALL_DEPS))
-
include $(BUILD_SYSTEM)/dumpvar.mk
diff --git a/core/dex_preopt_config.mk b/core/dex_preopt_config.mk
index 0c806c1..d5293cf 100644
--- a/core/dex_preopt_config.mk
+++ b/core/dex_preopt_config.mk
@@ -109,6 +109,8 @@
$(call add_json_list, SystemServerJars, $(PRODUCT_SYSTEM_SERVER_JARS))
$(call add_json_list, SystemServerApps, $(PRODUCT_SYSTEM_SERVER_APPS))
$(call add_json_list, ApexSystemServerJars, $(PRODUCT_APEX_SYSTEM_SERVER_JARS))
+ $(call add_json_list, StandaloneSystemServerJars, $(PRODUCT_STANDALONE_SYSTEM_SERVER_JARS))
+ $(call add_json_list, ApexStandaloneSystemServerJars, $(PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS))
$(call add_json_bool, BrokenSuboptimalOrderOfSystemServerJars, $(PRODUCT_BROKEN_SUBOPTIMAL_ORDER_OF_SYSTEM_SERVER_JARS))
$(call add_json_list, SpeedApps, $(PRODUCT_DEXPREOPT_SPEED_APPS))
$(call add_json_list, PreoptFlags, $(PRODUCT_DEX_PREOPT_DEFAULT_FLAGS))
diff --git a/core/envsetup.mk b/core/envsetup.mk
index bb1aa1e..3e40a02 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -323,6 +323,12 @@
SDK_HOST_ARCH := x86
TARGET_OS := linux
+# Some board configuration files use $(PRODUCT_OUT)
+TARGET_OUT_ROOT := $(OUT_DIR)/target
+TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
+PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
+.KATI_READONLY := TARGET_OUT_ROOT TARGET_PRODUCT_OUT_ROOT PRODUCT_OUT
+
include $(BUILD_SYSTEM)/board_config.mk
# the target build type defaults to release
@@ -335,28 +341,24 @@
SOONG_OUT_DIR := $(OUT_DIR)/soong
-TARGET_OUT_ROOT := $(OUT_DIR)/target
-
HOST_OUT_ROOT := $(OUT_DIR)/host
-.KATI_READONLY := SOONG_OUT_DIR TARGET_OUT_ROOT HOST_OUT_ROOT
+.KATI_READONLY := SOONG_OUT_DIR HOST_OUT_ROOT
# We want to avoid two host bin directories in multilib build.
HOST_OUT := $(HOST_OUT_ROOT)/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
-SOONG_HOST_OUT := $(SOONG_OUT_DIR)/host/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
+
+# Soong now installs to the same directory as Make.
+SOONG_HOST_OUT := $(HOST_OUT)
HOST_CROSS_OUT := $(HOST_OUT_ROOT)/$(HOST_CROSS_OS)-$(HOST_CROSS_ARCH)
.KATI_READONLY := HOST_OUT SOONG_HOST_OUT HOST_CROSS_OUT
-TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
-
TARGET_COMMON_OUT_ROOT := $(TARGET_OUT_ROOT)/common
HOST_COMMON_OUT_ROOT := $(HOST_OUT_ROOT)/common
-PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
-
-.KATI_READONLY := TARGET_PRODUCT_OUT_ROOT TARGET_COMMON_OUT_ROOT HOST_COMMON_OUT_ROOT PRODUCT_OUT
+.KATI_READONLY := TARGET_COMMON_OUT_ROOT HOST_COMMON_OUT_ROOT
OUT_DOCS := $(TARGET_COMMON_OUT_ROOT)/docs
OUT_NDK_DOCS := $(TARGET_COMMON_OUT_ROOT)/ndk-docs
diff --git a/core/java_common.mk b/core/java_common.mk
index 1798ca8..5981b60 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -21,15 +21,20 @@
# Modules can override this logic by specifying
# LOCAL_JAVA_LANGUAGE_VERSION explicitly.
ifeq (,$(LOCAL_JAVA_LANGUAGE_VERSION))
- ifneq (,$(filter $(LOCAL_SDK_VERSION), $(TARGET_SDK_VERSIONS_WITHOUT_JAVA_18_SUPPORT)))
- LOCAL_JAVA_LANGUAGE_VERSION := 1.7
- else ifneq (,$(filter $(LOCAL_SDK_VERSION), $(TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT)))
- LOCAL_JAVA_LANGUAGE_VERSION := 1.8
- else ifneq (,$(LOCAL_SDK_VERSION)$(TARGET_BUILD_USE_PREBUILT_SDKS))
- # TODO(ccross): allow 1.9 for current and unbundled once we have SDK system modules
- LOCAL_JAVA_LANGUAGE_VERSION := 1.8
- else
+ ifdef LOCAL_IS_HOST_MODULE
+ # Host modules always default to 1.9
LOCAL_JAVA_LANGUAGE_VERSION := 1.9
+ else
+ ifneq (,$(filter $(LOCAL_SDK_VERSION), $(TARGET_SDK_VERSIONS_WITHOUT_JAVA_18_SUPPORT)))
+ LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+ else ifneq (,$(filter $(LOCAL_SDK_VERSION), $(TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT)))
+ LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+ else ifneq (,$(LOCAL_SDK_VERSION)$(TARGET_BUILD_USE_PREBUILT_SDKS))
+ # TODO(ccross): allow 1.9 for current and unbundled once we have SDK system modules
+ LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+ else
+ LOCAL_JAVA_LANGUAGE_VERSION := 1.9
+ endif
endif
endif
LOCAL_JAVACFLAGS += -source $(LOCAL_JAVA_LANGUAGE_VERSION) -target $(LOCAL_JAVA_LANGUAGE_VERSION)
@@ -378,9 +383,8 @@
endif # USE_CORE_LIB_BOOTCLASSPATH
endif # !LOCAL_IS_HOST_MODULE
-ifdef RECORD_ALL_DEPS
+# (b/204397180) Record ALL_DEPS by default.
ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS) $(full_java_bootclasspath_libs)
-endif
# Export the SDK libs. The sdk library names listed in LOCAL_SDK_LIBRARIES are first exported.
# Then sdk library names exported from dependencies are all re-exported.
diff --git a/core/main.mk b/core/main.mk
index c57f7c9..f7cf8de 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1379,7 +1379,7 @@
# Verify the artifact path requirements made by included products.
is_asan := $(if $(filter address,$(SANITIZE_TARGET)),true)
- ifeq (,$(or $(is_asan),$(DISABLE_ARTIFACT_PATH_REQUIREMENTS),$(RBC_PRODUCT_CONFIG)))
+ ifeq (,$(or $(is_asan),$(DISABLE_ARTIFACT_PATH_REQUIREMENTS),$(RBC_PRODUCT_CONFIG),$(RBC_BOARD_CONFIG)))
include $(BUILD_SYSTEM)/artifact_path_requirements.mk
endif
else
diff --git a/core/node_fns.mk b/core/node_fns.mk
index 8d20160..2243cd7 100644
--- a/core/node_fns.mk
+++ b/core/node_fns.mk
@@ -208,7 +208,7 @@
$(eval $(1).$(2).inherited := \
$(call get-inherited-nodes,$(1).$(2),$(3)))
- $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3))
+ $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3),$(4))
$(call _expand-inherited-values,$(1),$(2),$(3),$(4))
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 9f5a599..800dbbc 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -35,6 +35,10 @@
endif
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
+ifneq ($(strip $(LOCAL_MODULE_STEM)$(LOCAL_BUILT_MODULE_STEM)),)
+$(error $(LOCAL_PATH): Package modules may not define LOCAL_MODULE_STEM or LOCAL_BUILT_MODULE_STEM)
+endif
+
ifneq ($(strip $(LOCAL_MODULE)),)
$(error $(LOCAL_PATH): Package modules may not define LOCAL_MODULE)
endif
diff --git a/core/product-graph.mk b/core/product-graph.mk
index de4e581..f28ea3d 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -81,7 +81,7 @@
$(products_graph): PRIVATE_PRODUCTS_FILTER := $(products_list)
$(products_graph): $(this_makefile)
-ifeq (,$(RBC_PRODUCT_CONFIG)$(RBC_NO_PRODUCT_GRAPH))
+ifeq (,$(RBC_PRODUCT_CONFIG)$(RBC_NO_PRODUCT_GRAPH)$(RBC_BOARD_CONFIG))
@echo Product graph DOT: $@ for $(PRIVATE_PRODUCTS_FILTER)
$(hide) echo 'digraph {' > $@.in
$(hide) echo 'graph [ ratio=.5 ];' >> $@.in
@@ -148,7 +148,7 @@
$(hide) cat $$< | build/make/tools/product_debug.py > $$@
endef
-ifeq (,$(RBC_PRODUCT_CONFIG)$(RBC_NO_PRODUCT_GRAPH))
+ifeq (,$(RBC_PRODUCT_CONFIG)$(RBC_NO_PRODUCT_GRAPH)$(RBC_BOARD_CONFIG))
product_debug_files:=
$(foreach p,$(all_products), \
$(eval $(call transform-product-debug, $(p))) \
@@ -164,4 +164,4 @@
.PHONY: product-graph
@echo RBC_PRODUCT_CONFIG and RBC_NO_PRODUCT_GRAPH should be unset to generate product graph
false
-endif
\ No newline at end of file
+endif
diff --git a/core/product.mk b/core/product.mk
index 23fb939..31b1beb 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -232,9 +232,15 @@
_product_single_value_vars += PRODUCT_SUPPORTS_VERITY
_product_single_value_vars += PRODUCT_SUPPORTS_VERITY_FEC
_product_list_vars += PRODUCT_SYSTEM_SERVER_APPS
+# List of system_server classpath jars on the platform.
_product_list_vars += PRODUCT_SYSTEM_SERVER_JARS
-# List of system_server jars delivered via apex. Format = <apex name>:<jar name>.
+# List of system_server classpath jars delivered via apex. Format = <apex name>:<jar name>.
_product_list_vars += PRODUCT_APEX_SYSTEM_SERVER_JARS
+# List of jars on the platform that system_server loads dynamically using separate classloaders.
+_product_list_vars += PRODUCT_STANDALONE_SYSTEM_SERVER_JARS
+# List of jars delivered via apex that system_server loads dynamically using separate classloaders.
+# Format = <apex name>:<jar name>
+_product_list_vars += PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS
# If true, then suboptimal order of system server jars does not cause an error.
_product_single_value_vars += PRODUCT_BROKEN_SUBOPTIMAL_ORDER_OF_SYSTEM_SERVER_JARS
# If true, then system server jars defined in Android.mk are supported.
@@ -275,10 +281,10 @@
_product_single_value_vars += PRODUCT_DEX_PREOPT_RESOLVE_STARTUP_STRINGS
# Boot image options.
+_product_list_vars += PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION
_product_single_value_vars += \
PRODUCT_EXPORT_BOOT_IMAGE_TO_DIST \
PRODUCT_USE_PROFILE_FOR_BOOT_IMAGE \
- PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION \
PRODUCT_USES_DEFAULT_ART_CONFIG \
_product_single_value_vars += PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
@@ -440,6 +446,16 @@
# This option is only meant to be set by GSI products.
_product_single_value_vars += PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT
+# If set, metadata files for the following artifacts will be generated.
+# - system/framework/*.jar
+# - system/framework/oat/<arch>/*.{oat,vdex,art}
+# - system/etc/boot-image.prof
+# - system/etc/dirty-image-objects
+# One fsverity metadata container file per one input file will be generated in
+# system.img, with a suffix ".fsv_meta". e.g. a container file for
+# "/system/framework/foo.jar" will be "system/framework/foo.jar.fsv_meta".
+_product_single_value_vars += PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA
+
.KATI_READONLY := _product_single_value_vars _product_list_vars
_product_var_list :=$= $(_product_single_value_vars) $(_product_list_vars)
diff --git a/core/product_config.mk b/core/product_config.mk
index 33b15d3..2b44434 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -206,10 +206,10 @@
ifndef RBC_PRODUCT_CONFIG
$(call import-products, $(current_product_makefile))
else
- rc := $(shell build/soong/scripts/rbc-run $(current_product_makefile) \
- >$(OUT_DIR)/rbctemp.mk || echo $$?)
- ifneq (,$(rc))
- $(error product configuration converter failed: $(rc))
+ $(shell build/soong/scripts/update_out $(OUT_DIR)/rbctemp.mk \
+ build/soong/scripts/rbc-run $(current_product_makefile))
+ ifneq ($(.SHELLSTATUS),0)
+ $(error product configuration converter failed: $(.SHELLSTATUS))
endif
include $(OUT_DIR)/rbctemp.mk
PRODUCTS += $(current_product_makefile)
@@ -320,6 +320,16 @@
PRODUCT_SYSTEM_SERVER_JARS := $(call qualify-platform-jars,$(PRODUCT_SYSTEM_SERVER_JARS))
+# Sort APEX boot and system server jars. We use deterministic alphabetical order
+# when constructing BOOTCLASSPATH and SYSTEMSERVERCLASSPATH definition on device
+# after an update. Enforce it in the build system as well to avoid recompiling
+# everything after an update due a change in the order.
+PRODUCT_APEX_BOOT_JARS := $(sort $(PRODUCT_APEX_BOOT_JARS))
+PRODUCT_APEX_SYSTEM_SERVER_JARS := $(sort $(PRODUCT_APEX_SYSTEM_SERVER_JARS))
+
+PRODUCT_STANDALONE_SYSTEM_SERVER_JARS := \
+ $(call qualify-platform-jars,$(PRODUCT_STANDALONE_SYSTEM_SERVER_JARS))
+
ifndef PRODUCT_SYSTEM_NAME
PRODUCT_SYSTEM_NAME := $(PRODUCT_NAME)
endif
diff --git a/core/product_config.rbc b/core/product_config.rbc
index 9876d56..c0bf281 100644
--- a/core/product_config.rbc
+++ b/core/product_config.rbc
@@ -17,7 +17,8 @@
"""Runtime functions."""
_soong_config_namespaces_key = "$SOONG_CONFIG_NAMESPACES"
-def _global_init(version_info):
+_dist_for_goals_key = "$dist_for_goals"
+def _init_globals(version_info):
"""Returns dict created from the runtime environment."""
globals = dict()
@@ -30,7 +31,6 @@
globals[k] = getattr(rblf_cli, k)
globals.setdefault("PRODUCT_SOONG_NAMESPACES", [])
- globals.setdefault(_soong_config_namespaces_key, {})
_envsetup_init(globals, version_info)
# Variables that should be defined.
@@ -50,7 +50,8 @@
def __print_attr(attr, value):
- if not value:
+ # Allow using empty strings to clear variables, but not None values
+ if value == None:
return
if type(value) == "list":
if _options.rearrange:
@@ -74,21 +75,36 @@
__print_attr(attr, val)
if _options.print_globals:
print()
- for attr, val in sorted(globals.items()):
- if attr == _soong_config_namespaces_key:
- __print_attr("SOONG_CONFIG_NAMESPACES", val.keys())
- for nsname, nsvars in sorted(val.items()):
- # Define SOONG_CONFIG_<ns> for Make, othewise
- # it cannot be added to .KATI_READONLY list
- if _options.format == "make":
- print("SOONG_CONFIG_" + nsname, ":=", " ".join(nsvars.keys()))
- for var, val in sorted(nsvars.items()):
- if val:
- __print_attr("SOONG_CONFIG_%s_%s" % (nsname, var), val)
- else:
- print("SOONG_CONFIG_%s_%s :=" % (nsname, var))
- elif attr not in globals_base or globals_base[attr] != val:
- __print_attr(attr, val)
+ _printglobals(globals, globals_base)
+
+def _printglobals(globals, globals_base):
+ for attr, val in sorted(globals.items()):
+ if attr == _soong_config_namespaces_key:
+ __print_attr("SOONG_CONFIG_NAMESPACES", val.keys())
+ for nsname, nsvars in sorted(val.items()):
+ # Define SOONG_CONFIG_<ns> for Make, othewise
+ # it cannot be added to .KATI_READONLY list
+ if _options.format == "make":
+ print("SOONG_CONFIG_" + nsname, ":=", " ".join(nsvars.keys()))
+ for var, val in sorted(nsvars.items()):
+ if val:
+ __print_attr("SOONG_CONFIG_%s_%s" % (nsname, var), val)
+ else:
+ print("SOONG_CONFIG_%s_%s :=" % (nsname, var))
+ elif attr == _dist_for_goals_key:
+ goals = []
+ src_dst_list = []
+ goal_dst_list = []
+ for goal_name, goal_src_dst_list in sorted(val.items()):
+ goals.append(goal_name)
+ for sd in sorted(goal_src_dst_list):
+ src_dst_list.append(":".join(sd))
+ goal_dst_list.append(":".join((goal_name, sd[1])))
+ print("_all_dist_goal_output_pairs:=", " ".join(goal_dst_list))
+ print("_all_dist_goals:=", " ".join(goals))
+ print("_all_dist_src_dst_pairs:=", " ".join(src_dst_list))
+ elif attr not in globals_base or globals_base[attr] != val:
+ __print_attr(attr, val)
def __printvars_rearrange_list(value_list):
"""Rearrange value list: return only distinct elements, maybe sorted."""
@@ -109,7 +125,7 @@
# PCM means "Product Configuration Module", i.e., a Starlark file
# whose body consists of a single init function.
- globals_base = _global_init(version_info)
+ globals_base = _init_globals(version_info)
globals = dict(**globals_base)
config_postfix = [] # Configs in postfix order
@@ -203,6 +219,24 @@
return (globals, configs[top_pcm_name][1], globals_base)
+
+def _dictionary_difference(a, b):
+ result = {}
+ for attr, val in a.items():
+ if attr not in b or b[attr] != val:
+ result[attr] = val
+ return result
+
+def _board_configuration(board_config_init, input_variables_init):
+ globals = {}
+ h = __h_new()
+ input_variables_init(globals, h)
+ cfg_base = dict(**h[0])
+ globals_base = dict(**globals)
+ board_config_init(globals, h)
+ return (globals, _dictionary_difference(h[0], cfg_base), globals_base)
+
+
def _substitute_inherited(configs, pcm_name, cfg):
"""Substitutes inherited values in all the attributes.
@@ -285,10 +319,11 @@
def _soong_config_namespace(g, nsname):
"""Adds given namespace if it does not exist."""
- if g[_soong_config_namespaces_key].get(nsname):
+ old = g.get(_soong_config_namespaces_key, {})
+ if old.get(nsname):
return
+
# A value cannot be updated, so we need to create a new dictionary
- old = g[_soong_config_namespaces_key]
g[_soong_config_namespaces_key] = dict([(k,v) for k,v in old.items()] + [(nsname, {})])
def _soong_config_set(g, nsname, var, value):
@@ -307,6 +342,11 @@
ns[var] += " " + value
+def _soong_config_get(g, nsname, var):
+ """Gets to the value of the variable in the namespace."""
+ return g.get(_soong_config_namespaces_key, {}).get(nsname, {}).get(var, None)
+
+
def _abspath(path):
"""Provided for compatibility, to be removed later."""
return path
@@ -342,7 +382,7 @@
def __words(string_or_list):
if type(string_or_list) == "list":
return string_or_list
- return string_or_list.split()
+ return _mkstrip(string_or_list).split()
# Handle manipulation functions.
# A handle passed to a PCM consists of:
@@ -466,6 +506,13 @@
res.append(w)
return res
+def _notdir(paths):
+ """Equivalent to the GNU make function $(notdir).
+
+ Returns the name of the file at the end of each path in paths.
+ """
+ return " ".join([__base(w) for w in __words(paths)])
+
def __mk2regex(words):
"""Returns regular expression equivalent to Make pattern."""
@@ -487,6 +534,21 @@
"""Expands shell wildcard pattern."""
return rblf_wildcard(pattern)
+def _mkdist_for_goals(g, goal, src_dst_list):
+ """Implements dist-for-goals macro."""
+ goals_map = g.get(_dist_for_goals_key, {})
+ pairs = goals_map.get(goal)
+ if pairs == None:
+ pairs = []
+ g[_dist_for_goals_key] = dict([(k,v) for k,v in goals_map.items()] + [(goal, pairs)])
+ for src_dst in __words(src_dst_list):
+ pair=src_dst.split(":")
+ if len(pair) > 2:
+ fail(src_dst + " should be a :-separated pair")
+ pairs.append((pair[0],pair[1] if len(pair) == 2 and pair[1] else __base(pair[0])))
+ g[_dist_for_goals_key][goal] = pairs
+
+
def _mkerror(file, message = ""):
"""Prints error and stops."""
fail("%s: %s. Stop" % (file, message))
@@ -495,6 +557,18 @@
"""Prints warning."""
rblf_log(file, "warning", message, sep = ':')
+def _mk2rbc_error(loc, message):
+ """Prints a message about conversion error and stops.
+
+ If RBC_MK2RBC_CONTINUE environment variable is set,
+ the execution will continue after the message is printed.
+ """
+ if _options.mk2rbc_continue:
+ rblf_log(loc, message, sep = ':')
+ else:
+ _mkerror(loc, message)
+
+
def _mkinfo(file, message = ""):
"""Prints info."""
rblf_log(message)
@@ -605,6 +679,7 @@
rearrange = "",
trace_modules = False,
trace_variables = [],
+ mk2rbc_continue = False,
)
for x in getattr(rblf_cli, "RBC_OUT", "").split(","):
if x == "sort" or x == "unique":
@@ -622,6 +697,8 @@
settings["trace_modules"] = True
elif x != "":
settings["trace_variables"].append(x)
+ if getattr(rblf_cli, "RBC_MK2RBC_CONTINUE", ""):
+ settings["mk2rbc_continue"] = True
return struct(**settings)
# Settings used during debugging.
@@ -630,6 +707,7 @@
soong_config_namespace = _soong_config_namespace,
soong_config_append = _soong_config_append,
soong_config_set = _soong_config_set,
+ soong_config_get = _soong_config_get,
abspath = _abspath,
addprefix = _addprefix,
addsuffix = _addsuffix,
@@ -645,17 +723,22 @@
filter = _filter,
filter_out = _filter_out,
find_and_copy = _find_and_copy,
- global_init = _global_init,
+ init_globals = _init_globals,
inherit = _inherit,
indirect = _indirect,
+ mk2rbc_error = _mk2rbc_error,
+ mkdist_for_goals = _mkdist_for_goals,
mkinfo = _mkinfo,
mkerror = _mkerror,
mkpatsubst = _mkpatsubst,
mkwarning = _mkwarning,
mkstrip = _mkstrip,
mksubst = _mksubst,
+ notdir = _notdir,
printvars = _printvars,
+ printglobals = _printglobals,
product_configuration = _product_configuration,
+ board_configuration = _board_configuration,
product_copy_files_by_pattern = _product_copy_files_by_pattern,
require_artifacts_in_path = _require_artifacts_in_path,
require_artifacts_in_path_relaxed = _require_artifacts_in_path_relaxed,
diff --git a/core/soong_android_app_set.mk b/core/soong_android_app_set.mk
index f994165..ec3d8c8 100644
--- a/core/soong_android_app_set.mk
+++ b/core/soong_android_app_set.mk
@@ -6,9 +6,8 @@
$(call pretty-error,soong_apk_set.mk may only be used from Soong)
endif
-LOCAL_BUILT_MODULE_STEM := $(LOCAL_APK_SET_INSTALL_FILE)
-LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_APK_SET_INSTALL_FILE)
-
+LOCAL_BUILT_MODULE_STEM := package.apk
+LOCAL_INSTALLED_MODULE_STEM := $(notdir $(LOCAL_PREBUILT_MODULE_FILE))
# Use the Soong output as the checkbuild target instead of LOCAL_BUILT_MODULE
# to avoid checkbuilds making an extra copy of every module.
@@ -18,22 +17,8 @@
include $(BUILD_SYSTEM)/base_rules.mk
#######################################
-## Extract master APK from APK set into given directory
-# $(1) APK set
-# $(2) APK entry to install (e.g., splits/base.apk
+$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
-define extract-install-file-from-apk-set
-$(LOCAL_BUILT_MODULE): $(1)
- @echo "Extracting $$@"
- unzip -pq $$< $(2) >$$@
-endef
-
-$(eval $(call extract-install-file-from-apk-set,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_APK_SET_INSTALL_FILE)))
-# unzip returns 11 it there was nothing to extract, which is expected,
-# $(LOCAL_APK_SET_INSTALL_FILE) has is already there.
-LOCAL_POST_INSTALL_CMD := unzip -qoDD -j -d $(dir $(LOCAL_INSTALLED_MODULE)) \
- $(LOCAL_PREBUILT_MODULE_FILE) -x $(LOCAL_APK_SET_INSTALL_FILE) || [[ $$? -eq 11 ]]
-$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index ee06432..dcb5a2e 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -138,13 +138,6 @@
java-dex: $(LOCAL_SOONG_DEX_JAR)
-my_built_installed := $(foreach f,$(LOCAL_SOONG_BUILT_INSTALLED),\
- $(call word-colon,1,$(f)):$(PRODUCT_OUT)$(call word-colon,2,$(f)))
-my_installed := $(call copy-many-files, $(my_built_installed))
-ALL_MODULES.$(my_register_name).INSTALLED += $(my_installed)
-ALL_MODULES.$(my_register_name).BUILT_INSTALLED += $(my_built_installed)
-$(my_all_targets): $(my_installed)
-
# Copy test suite files.
ifdef LOCAL_COMPATIBILITY_SUITE
my_apks_to_install := $(foreach f,$(filter %.apk %.idsig,$(LOCAL_SOONG_BUILT_INSTALLED)),$(call word-colon,1,$(f)))
diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_rust_prebuilt.mk
similarity index 89%
rename from core/soong_cc_prebuilt.mk
rename to core/soong_cc_rust_prebuilt.mk
index 49345e2..ca52374 100644
--- a/core/soong_cc_prebuilt.mk
+++ b/core/soong_cc_rust_prebuilt.mk
@@ -6,7 +6,7 @@
# LOCAL_SOONG_VNDK_VERSION : means the version of VNDK where this module belongs
ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
- $(call pretty-error,soong_cc_prebuilt.mk may only be used from Soong)
+ $(call pretty-error,soong_cc_rust_prebuilt.mk may only be used from Soong)
endif
ifdef LOCAL_IS_HOST_MODULE
@@ -31,9 +31,9 @@
$(call pretty-error,Unsupported LOCAL_MODULE_$(my_prefix)ARCH=$(LOCAL_MODULE_$(my_prefix)ARCH))
endif
-# Don't install static libraries by default.
+# Don't install static/rlib/proc_macro libraries.
ifndef LOCAL_UNINSTALLABLE_MODULE
- ifeq (STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS))
+ ifneq ($(filter STATIC_LIBRARIES RLIB_LIBRARIES PROC_MACRO_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
LOCAL_UNINSTALLABLE_MODULE := true
endif
endif
@@ -54,7 +54,7 @@
include $(BUILD_SYSTEM)/base_rules.mk
#######################################
-ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES RLIB_LIBRARIES DYLIB_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
# Soong module is a static or shared library
EXPORTS_LIST += $(intermediates)
EXPORTS.$(intermediates).FLAGS := $(LOCAL_EXPORT_CFLAGS)
@@ -113,6 +113,16 @@
$(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
$(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
endif
+ ifdef LOCAL_DYLIB_LIBRARIES
+ my_dylibs := $(LOCAL_DYLIB_LIBRARIES)
+ # Treat these as shared library dependencies for installation purposes.
+ ifdef LOCAL_USE_VNDK
+ my_dylibs := $(foreach l,$(my_dylibs),\
+ $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+ endif
+ $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
+ $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_dylibs))
+ endif
endif
my_check_same_vndk_variants :=
@@ -233,9 +243,9 @@
$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
-# We don't care about installed static libraries, since the libraries have
+# We don't care about installed rlib/static libraries, since the libraries have
# already been linked into the module at that point. We do, however, care
-# about the NOTICE files for any static libraries that we use.
+# about the NOTICE files for any rlib/static libraries that we use.
# (see notice_files.mk)
#
# Filter out some NDK libraries that are not being exported.
@@ -247,6 +257,9 @@
installed_static_library_notice_file_targets := \
$(foreach lib,$(my_static_libraries) $(LOCAL_WHOLE_STATIC_LIBRARIES), \
NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST$(if $(my_host_cross),_CROSS,),TARGET)-STATIC_LIBRARIES-$(lib))
+installed_static_library_notice_file_targets += \
+ $(foreach lib,$(LOCAL_RLIB_LIBRARIES), \
+ NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST$(if $(my_host_cross),_CROSS,),TARGET)-RLIB_LIBRARIES-$(lib))
$(notice_target): | $(installed_static_library_notice_file_targets)
$(LOCAL_INSTALLED_MODULE): | $(notice_target)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 4999464..fd60b71 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -37,7 +37,7 @@
$(call add_json_bool, Allow_missing_dependencies, $(filter true,$(ALLOW_MISSING_DEPENDENCIES)))
$(call add_json_bool, Unbundled_build, $(TARGET_BUILD_UNBUNDLED))
-$(call add_json_bool, Unbundled_build_apps, $(TARGET_BUILD_APPS))
+$(call add_json_list, Unbundled_build_apps, $(TARGET_BUILD_APPS))
$(call add_json_bool, Unbundled_build_image, $(TARGET_BUILD_UNBUNDLED_IMAGE))
$(call add_json_bool, Always_use_prebuilt_sdks, $(TARGET_BUILD_USE_PREBUILT_SDKS))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 2c909ac..801a265 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -154,13 +154,7 @@
endif
endif # LOCAL_SOONG_DEX_JAR
-my_built_installed := $(foreach f,$(LOCAL_SOONG_BUILT_INSTALLED),\
- $(call word-colon,1,$(f)):$(PRODUCT_OUT)$(call word-colon,2,$(f)))
-my_installed := $(call copy-many-files, $(my_built_installed))
-ALL_MODULES.$(my_register_name).INSTALLED += $(my_installed)
-ALL_MODULES.$(my_register_name).BUILT_INSTALLED += $(my_built_installed)
ALL_MODULES.$(my_register_name).CLASSES_JAR := $(full_classes_jar)
-$(my_register_name): $(my_installed)
ifdef LOCAL_SOONG_AAR
ALL_MODULES.$(my_register_name).AAR := $(LOCAL_SOONG_AAR)
diff --git a/core/soong_rust_prebuilt.mk b/core/soong_rust_prebuilt.mk
deleted file mode 100644
index 435a7d8..0000000
--- a/core/soong_rust_prebuilt.mk
+++ /dev/null
@@ -1,187 +0,0 @@
-# Native prebuilt coming from Soong.
-# Extra inputs:
-# LOCAL_SOONG_UNSTRIPPED_BINARY
-
-ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
- $(call pretty-error,soong_rust_prebuilt.mk may only be used from Soong)
-endif
-
-ifdef LOCAL_IS_HOST_MODULE
- ifneq ($(HOST_OS),$(LOCAL_MODULE_HOST_OS))
- my_prefix := HOST_CROSS_
- LOCAL_HOST_PREFIX := $(my_prefix)
- else
- my_prefix := HOST_
- LOCAL_HOST_PREFIX :=
- endif
-else
- my_prefix := TARGET_
-endif
-
-ifeq ($($(my_prefix)ARCH),$(LOCAL_MODULE_$(my_prefix)ARCH))
- # primary arch
- LOCAL_2ND_ARCH_VAR_PREFIX :=
-else ifeq ($($(my_prefix)2ND_ARCH),$(LOCAL_MODULE_$(my_prefix)ARCH))
- # secondary arch
- LOCAL_2ND_ARCH_VAR_PREFIX := $($(my_prefix)2ND_ARCH_VAR_PREFIX)
-else
- $(call pretty-error,Unsupported LOCAL_MODULE_$(my_prefix)ARCH=$(LOCAL_MODULE_$(my_prefix)ARCH))
-endif
-
-# Don't install static/rlib/proc_macro libraries.
-ifndef LOCAL_UNINSTALLABLE_MODULE
- ifneq ($(filter STATIC_LIBRARIES RLIB_LIBRARIES PROC_MACRO_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
- LOCAL_UNINSTALLABLE_MODULE := true
- endif
-endif
-
-# Use the Soong output as the checkbuild target instead of LOCAL_BUILT_MODULE
-# to avoid checkbuilds making an extra copy of every module.
-LOCAL_CHECKED_MODULE := $(LOCAL_PREBUILT_MODULE_FILE)
-
-#######################################
-include $(BUILD_SYSTEM)/base_rules.mk
-#######################################
-
-ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES RLIB_LIBRARIES DYLIB_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
- # Soong module is a static or shared library
- EXPORTS_LIST += $(intermediates)
- EXPORTS.$(intermediates).FLAGS := $(LOCAL_EXPORT_CFLAGS)
- EXPORTS.$(intermediates).DEPS := $(LOCAL_EXPORT_C_INCLUDE_DEPS)
-
- SOONG_ALREADY_CONV += $(LOCAL_MODULE)
-
- my_link_type := $(LOCAL_SOONG_LINK_TYPE)
- my_warn_types :=
- my_allowed_types :=
- my_link_deps :=
- my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
- my_common :=
- include $(BUILD_SYSTEM)/link_type.mk
-endif
-
-
-ifdef LOCAL_USE_VNDK
- ifneq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true)
- name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE))
- ifneq ($(name_without_suffix),$(LOCAL_MODULE))
- SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1
- else
- name_without_suffix := $(patsubst %.product,%,$(LOCAL_MODULE))
- ifneq ($(name_without_suffix),$(LOCAL_MODULE))
- SPLIT_PRODUCT.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1
- endif
- endif
- name_without_suffix :=
- endif
-endif
-
-# The real dependency will be added after all Android.mks are loaded and the install paths
-# of the shared libraries are determined.
-ifdef LOCAL_INSTALLED_MODULE
- ifdef LOCAL_SHARED_LIBRARIES
- my_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
- ifdef LOCAL_USE_VNDK
- my_shared_libraries := $(foreach l,$(my_shared_libraries),\
- $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
- endif
- $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
- $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
- endif
- ifdef LOCAL_DYLIB_LIBRARIES
- my_dylibs := $(LOCAL_DYLIB_LIBRARIES)
- # Treat these as shared library dependencies for installation purposes.
- ifdef LOCAL_USE_VNDK
- my_dylibs := $(foreach l,$(my_dylibs),\
- $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
- endif
- $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
- $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_dylibs))
- endif
-endif
-
-$(LOCAL_BUILT_MODULE): $(LOCAL_PREBUILT_MODULE_FILE)
-ifeq ($(LOCAL_IS_HOST_MODULE) $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),true,),true true)
- $(copy-or-link-prebuilt-to-target)
- ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
- [ -x $@ ] || ( $(call echo-error,$@,Target of symlink is not executable); false )
- endif
-else
- $(transform-prebuilt-to-target)
- ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
- $(hide) chmod +x $@
- endif
-endif
-
-ifndef LOCAL_IS_HOST_MODULE
- ifdef LOCAL_SOONG_UNSTRIPPED_BINARY
- my_symbol_path := $(if $(LOCAL_SOONG_SYMBOL_PATH),$(LOCAL_SOONG_SYMBOL_PATH),$(my_module_path))
- # Store a copy with symbols for symbolic debugging
- my_unstripped_path := $(TARGET_OUT_UNSTRIPPED)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_symbol_path))
- # drop /root as /root is mounted as /
- my_unstripped_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/root/%,$(TARGET_OUT_UNSTRIPPED)/%, $(my_unstripped_path))
- symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
- $(eval $(call copy-one-file,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output)))
- $(LOCAL_BUILT_MODULE): | $(symbolic_output)
- endif
-endif
-
-create_coverage_zip :=
-
-ifeq ($(NATIVE_COVERAGE),true)
- create_coverage_zip := true
-endif
-
-# Until Rust supports LLVM coverage, Soong assumes GCOV coverage in both cases.
-# Therefore we should create the coverage zip with the gcno files in this case as well.
-ifeq ($(CLANG_COVERAGE),true)
- create_coverage_zip := true
-endif
-
-ifdef create_coverage_zip
- ifneq (,$(strip $(LOCAL_PREBUILT_COVERAGE_ARCHIVE)))
- $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(intermediates)/$(LOCAL_MODULE).zip))
- ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
- ifdef LOCAL_IS_HOST_MODULE
- my_coverage_path := $($(my_prefix)OUT_COVERAGE)/$(patsubst $($(my_prefix)OUT)/%,%,$(my_module_path))
- else
- my_coverage_path := $(TARGET_OUT_COVERAGE)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
- endif
- my_coverage_path := $(my_coverage_path)/$(patsubst %.so,%,$(my_installed_module_stem)).zip
- $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(my_coverage_path)))
- $(LOCAL_BUILT_MODULE): $(my_coverage_path)
- endif
- endif
-endif
-
-# A product may be configured to strip everything in some build variants.
-# We do the stripping as a post-install command so that LOCAL_BUILT_MODULE
-# is still with the symbols and we don't need to clean it (and relink) when
-# you switch build variant.
-ifneq ($(filter $(STRIP_EVERYTHING_BUILD_VARIANTS),$(TARGET_BUILD_VARIANT)),)
-$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := \
- $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP) --strip-all $(LOCAL_INSTALLED_MODULE)
-endif
-
-$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
-
-# We don't care about installed rlib/static libraries, since the libraries have
-# already been linked into the module at that point. We do, however, care
-# about the NOTICE files for any rlib/static libraries that we use.
-# (see notice_files.mk)
-#
-# Filter out some NDK libraries that are not being exported.
-my_static_libraries := \
- $(filter-out ndk_libc++_static ndk_libc++abi ndk_libandroid_support ndk_libunwind \
- ndk_libc++_static.native_bridge ndk_libc++abi.native_bridge \
- ndk_libandroid_support.native_bridge ndk_libunwind.native_bridge, \
- $(LOCAL_STATIC_LIBRARIES))
-installed_static_library_notice_file_targets := \
- $(foreach lib,$(my_static_libraries), \
- NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST$(if $(my_host_cross),_CROSS,),TARGET)-STATIC_LIBRARIES-$(lib))
-installed_static_library_notice_file_targets += \
- $(foreach lib,$(LOCAL_RLIB_LIBRARIES), \
- NOTICE-$(if $(LOCAL_IS_HOST_MODULE),HOST$(if $(my_host_cross),_CROSS,),TARGET)-RLIB_LIBRARIES-$(lib))
-
-$(notice_target): | $(installed_static_library_notice_file_targets)
-$(LOCAL_INSTALLED_MODULE): | $(notice_target)
diff --git a/envsetup.sh b/envsetup.sh
index 4301d73..a23bbad 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -252,9 +252,7 @@
esac
ANDROID_BUILD_PATHS=$(get_build_var ANDROID_BUILD_PATHS):$ANDROID_TOOLCHAIN
- if [ -n "$ANDROID_TOOLCHAIN_2ND_ARCH" ]; then
- ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_TOOLCHAIN_2ND_ARCH
- fi
+ ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_TOOLCHAIN_2ND_ARCH
ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ANDROID_DEV_SCRIPTS
# Append llvm binutils prebuilts path to ANDROID_BUILD_PATHS.
@@ -287,8 +285,9 @@
local ACLOUD_PATH="$T/prebuilts/asuite/acloud/$os_arch"
local AIDEGEN_PATH="$T/prebuilts/asuite/aidegen/$os_arch"
local ATEST_PATH="$T/prebuilts/asuite/atest/$os_arch"
- export ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ACLOUD_PATH:$AIDEGEN_PATH:$ATEST_PATH:
+ ANDROID_BUILD_PATHS=$ANDROID_BUILD_PATHS:$ACLOUD_PATH:$AIDEGEN_PATH:$ATEST_PATH
+ export ANDROID_BUILD_PATHS=$(tr -s : <<<"${ANDROID_BUILD_PATHS}:")
export PATH=$ANDROID_BUILD_PATHS$PATH
# out with the duplicate old
@@ -1883,16 +1882,6 @@
fi
}
-# Source necessary setup scripts needed to run the build with Remote Execution.
-function source_rbe() {
- local T=$(gettop)
-
- if [[ "x$USE_RBE" != "x" && "$USE_RBE" != "false" ]]; then
- . $T/build/make/rbesetup.sh --skip-envsetup
- fi
-}
-
validate_current_shell
source_vendorsetup
-source_rbe
addcompletions
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 68dd980..760f8fb 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -362,7 +362,6 @@
adb_keys \
arping \
dmuserd \
- gdbserver \
idlcli \
init-debug.rc \
iotop \
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index 7622a69..5004b85 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -25,6 +25,7 @@
linker.recovery \
otacerts.recovery \
recovery \
+ servicemanager.recovery \
shell_and_utilities_recovery \
watchdogd.recovery \
diff --git a/target/product/core_64_bit_only.mk b/target/product/core_64_bit_only.mk
index 53c9c74..061728f 100644
--- a/target/product/core_64_bit_only.mk
+++ b/target/product/core_64_bit_only.mk
@@ -25,6 +25,9 @@
# Set the zygote property to select the 64-bit script.
# This line must be parsed before the one in core_minimal.mk
PRODUCT_VENDOR_PROPERTIES += ro.zygote=zygote64
+# A 64-bit-only platform does not have dex2oat32, so make sure dex2oat64 is
+# used for dexopt.
+PRODUCT_VENDOR_PROPERTIES += dalvik.vm.dex2oat64.enabled=true
TARGET_SUPPORTS_32_BIT_APPS := false
TARGET_SUPPORTS_64_BIT_APPS := true
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 071edbf..f98f7e2 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -14,6 +14,9 @@
# limitations under the License.
#
+# This file contains product config for the ART module that is common for
+# platform and unbundled builds.
+
ifeq ($(ART_APEX_JARS),)
$(error ART_APEX_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
endif
@@ -62,13 +65,28 @@
com.android.tethering:framework-tethering \
com.android.wifi:framework-wifi
-# APEX system server jars. Keep the list sorted by module names and then library names.
+# List of system_server classpath jars delivered via apex.
+# Keep the list sorted by module names and then library names.
PRODUCT_APEX_SYSTEM_SERVER_JARS := \
com.android.appsearch:service-appsearch \
com.android.art:service-art \
com.android.media:service-media-s \
com.android.permission:service-permission \
+PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION += art/build/boot/boot-image-profile.txt
+
+# List of jars on the platform that system_server loads dynamically using separate classloaders.
+# Keep the list sorted library names.
+PRODUCT_STANDALONE_SYSTEM_SERVER_JARS := \
+
+# List of jars delivered via apex that system_server loads dynamically using separate classloaders.
+# Keep the list sorted by module names and then library names.
+PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS := \
+ com.android.os.statsd:service-statsd \
+ com.android.scheduling:service-scheduling \
+ com.android.tethering:service-connectivity \
+ com.android.wifi:service-wifi \
+
# Minimal configuration for running dex2oat (default argument values).
# PRODUCT_USES_DEFAULT_ART_CONFIG must be true to enable boot image compilation.
PRODUCT_USES_DEFAULT_ART_CONFIG := true
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index 399652c..e5655b9 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -68,6 +68,7 @@
VNDK-core: android.hardware.configstore@1.0.so
VNDK-core: android.hardware.configstore@1.1.so
VNDK-core: android.hardware.confirmationui-support-lib.so
+VNDK-core: android.hardware.dumpstate-V1-ndk.so
VNDK-core: android.hardware.gnss-V1-ndk.so
VNDK-core: android.hardware.gnss-V1-ndk_platform.so
VNDK-core: android.hardware.graphics.allocator@2.0.so
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 301605a..ee63757 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -61,7 +61,7 @@
apex_test_module := art-check-release-apex-gen-fakebin
endif
-ifeq (true,$(SOONG_CONFIG_art_module_source_build)
+ifeq (true,$(call soong_config_get,art_module,source_build))
PRODUCT_HOST_PACKAGES += $(apex_test_module)
endif
@@ -75,6 +75,14 @@
PRODUCT_PACKAGES += \
hiddenapi-package-whitelist.xml \
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
+ # Don't depend on the framework boot image profile in unbundled builds where
+ # frameworks/base may not be present.
+ # TODO(b/179900989): We may not need this check once we stop using full
+ # platform products on the thin ART manifest branch.
+ PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION += frameworks/base/boot/boot-image-profile.txt
+endif
+
# The dalvik.vm.dexopt.thermal-cutoff property must contain one of the values
# listed here:
#
diff --git a/target/product/security/README b/target/product/security/README
index 4ad5236..2b161bb 100644
--- a/target/product/security/README
+++ b/target/product/security/README
@@ -16,7 +16,6 @@
development/tools/make_key shared '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key media '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key cts_uicc_2021 '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
- development/tools/make_key fsverity '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
signing using the openssl commandline (for boot/system images)
--------------------------------------------------------------
diff --git a/target/product/security/fsverity.pk8 b/target/product/security/fsverity.pk8
deleted file mode 100644
index 5bb69dc..0000000
--- a/target/product/security/fsverity.pk8
+++ /dev/null
Binary files differ
diff --git a/target/product/security/fsverity.x509.pem b/target/product/security/fsverity.x509.pem
deleted file mode 100644
index b29c711..0000000
--- a/target/product/security/fsverity.x509.pem
+++ /dev/null
@@ -1,24 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIECzCCAvOgAwIBAgIUDkPsN3C2kwiPnOnNZiHrK5S6oqowDQYJKoZIhvcNAQEL
-BQAwgZQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMRAwDgYDVQQDDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFu
-ZHJvaWQuY29tMB4XDTIxMTAxMjA0MzUyMFoXDTQ5MDIyNzA0MzUyMFowgZQxCzAJ
-BgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFp
-biBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMRAwDgYD
-VQQDDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1N8ro0RTY2Cl91daJvjo
-tDLjHrwrzSAQaVpEXGddPJYs0m8ej3Oh7Hbo4+ju36CIjgH9xDgpOb9LeTUMSXLF
-9Rlkdhz4VJlvaQuYz10FoqkvQo2/IsD2pAq3EktOHexfXCG8fhdCaVkayAuKX5ou
-+RchZWCPwVhBx6fbpZeGhkFg6f7CwPSMEJ5DNtvHUieny8OwIbml0NILQjavP4nU
-GGJxkyKgodUYCdnOSE7FCUv875Op9e0ryTPvUZhKHPoRMe5enEgfq/WXVdqLhifF
-k6gYelcfq1bFRpwBm5KntX1b39V52vYUqXM8gD8Wy5RNo+aF0msJ6aBVcYeQsMlY
-4QIDAQABo1MwUTAdBgNVHQ4EFgQURbNJabjEzJ2CZzqIrX/ppnDM9l4wHwYDVR0j
-BBgwFoAURbNJabjEzJ2CZzqIrX/ppnDM9l4wDwYDVR0TAQH/BAUwAwEB/zANBgkq
-hkiG9w0BAQsFAAOCAQEAl3eEb9xzlwAG31WKorYzflvFLX+LSuVMN3FEcZBcCXsW
-+5QPfyvbJ2AgBzJmuH4XeGH0PebgLQN3PA4p9M0ZgXcHf4KBrSOMfpwUsFiTiD+z
-9KJxr4MTyXyFxO3rVlVCg/za0V8om2cRWsOb2TPRu8qeUSIT4yIj/pOXmz66b4xL
-5fKCuI7khRADCRnwyhPD9/f2/udB6qYx2MvDRchHMLqLvCzHJPS4gjhDTJJSo/st
-/GKqHWspHl5IbpRNlQci1ncc1RLub5gxPwlkIcNlOcziD+eYWeSn5B7v+5uIqxdP
-VY+WltSg4FEEzKFMjzfNpk1Uz+J6h2bi3VS0WZXdXQ==
------END CERTIFICATE-----
diff --git a/tests/conversion_error.rbc b/tests/conversion_error.rbc
new file mode 100644
index 0000000..5212378
--- /dev/null
+++ b/tests/conversion_error.rbc
@@ -0,0 +1,27 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Run test configuration and verify its result.
+# The main configuration file is device.rbc.
+# It inherits part1.rbc and also includes include1.rbc
+# TODO(asmundak): more tests are needed to verify that:
+# * multi-level inheritance works as expected
+# * all runtime functions (wildcard, regex, etc.) work
+
+load("//build/make/core:product_config.rbc", "rblf")
+load(":version_defaults.rbc", "version_defaults")
+load(":device.rbc", "init")
+
+rblf.mk2rbc_error("file.mk:123", "cannot convert")
diff --git a/tests/device.rbc b/tests/device.rbc
index 37c5d0c..9ae6393 100644
--- a/tests/device.rbc
+++ b/tests/device.rbc
@@ -55,6 +55,9 @@
rblf.soong_config_set(g, "NS2", "v3", "abc")
rblf.soong_config_set(g, "NS2", "v3", "xyz")
+ rblf.mkdist_for_goals(g, "goal", "dir1/file1:out1 dir1/file2:out2")
+ rblf.mkdist_for_goals(g, "goal", "dir2/file2:")
+
if rblf.board_platform_in(g, "board1 board2"):
cfg["PRODUCT_PACKAGES"] += ["bad_package"]
g["TARGET_BOARD_PLATFORM"] = "board1"
diff --git a/tests/run.rbc b/tests/run.rbc
index 3bb9b55..31436c5 100644
--- a/tests/run.rbc
+++ b/tests/run.rbc
@@ -52,6 +52,11 @@
assert_eq([], rblf.filter(["a", "", "b"], "f"))
assert_eq(["", "b"], rblf.filter_out(["a", "" ], ["a", "", "b"] ))
+assert_eq("foo.c no_folder", rblf.notdir(["src/foo.c", "no_folder"]))
+assert_eq("foo.c no_folder", rblf.notdir("src/foo.c no_folder"))
+assert_eq("", rblf.notdir("/"))
+assert_eq("", rblf.notdir(""))
+
(globals, config, globals_base) = rblf.product_configuration("test/device", init, version_defaults)
assert_eq(
{
@@ -94,3 +99,14 @@
assert_eq("S", globals["PLATFORM_VERSION"])
assert_eq(30, globals["PLATFORM_SDK_VERSION"])
+
+assert_eq("xyz", rblf.soong_config_get(globals, "NS2", "v3"))
+assert_eq(None, rblf.soong_config_get(globals, "NS2", "nonexistant_var"))
+
+goals = globals["$dist_for_goals"]
+assert_eq(
+ {
+ "goal": [("dir1/file1", "out1"), ("dir1/file2", "out2"), ("dir2/file2", "file2")]
+ },
+ { k:v for k,v in sorted(goals.items()) }
+)
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index fc588e4..a979a8e 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -50,6 +50,7 @@
],
libs: [
"releasetools_common",
+ "releasetools_fsverity_metadata_generator",
"releasetools_verity_utils",
],
required: [
@@ -100,14 +101,6 @@
python_library_host {
name: "ota_metadata_proto",
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: true,
- },
- },
srcs: [
"ota_metadata.proto",
],
@@ -187,29 +180,15 @@
// Host libraries.
//
-python_defaults {
- name: "releasetools_library_defaults",
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: true,
- },
- },
-}
-
python_library_host {
name: "releasetools_add_img_to_target_files",
defaults: [
- "releasetools_library_defaults",
"releasetools_add_img_to_target_files_defaults",
],
}
python_library_host {
name: "releasetools_apex_utils",
- defaults: ["releasetools_library_defaults"],
srcs: [
"apex_utils.py",
],
@@ -223,7 +202,6 @@
python_library_host {
name: "releasetools_build_image",
defaults: [
- "releasetools_library_defaults",
"releasetools_build_image_defaults",
],
}
@@ -231,7 +209,6 @@
python_library_host {
name: "releasetools_build_super_image",
defaults: [
- "releasetools_library_defaults",
"releasetools_build_super_image_defaults",
],
}
@@ -239,14 +216,12 @@
python_library_host {
name: "releasetools_check_target_files_vintf",
defaults: [
- "releasetools_library_defaults",
"releasetools_check_target_files_vintf_defaults",
],
}
python_library_host {
name: "releasetools_common",
- defaults: ["releasetools_library_defaults"],
srcs: [
"blockimgdiff.py",
"common.py",
@@ -274,7 +249,6 @@
python_library_host {
name: "releasetools_img_from_target_files",
defaults: [
- "releasetools_library_defaults",
"releasetools_img_from_target_files_defaults",
],
}
@@ -282,14 +256,22 @@
python_library_host {
name: "releasetools_ota_from_target_files",
defaults: [
- "releasetools_library_defaults",
"releasetools_ota_from_target_files_defaults",
],
}
python_library_host {
+ name: "releasetools_fsverity_metadata_generator",
+ srcs: [
+ "fsverity_metadata_generator.py",
+ ],
+ libs: [
+ "fsverity_digests_proto_python",
+ ],
+}
+
+python_library_host {
name: "releasetools_verity_utils",
- defaults: ["releasetools_library_defaults"],
srcs: [
"verity_utils.py",
],
@@ -308,13 +290,8 @@
python_defaults {
name: "releasetools_binary_defaults",
version: {
- py2: {
- enabled: true,
- embedded_launcher: true,
- },
py3: {
- enabled: false,
- embedded_launcher: false,
+ embedded_launcher: true,
},
},
// TODO (b/140144201) Build imgdiff from releasetools_common
@@ -443,7 +420,6 @@
name: "releasetools_find_shareduid_violation",
defaults: [
"releasetools_find_shareduid_violation_defaults",
- "releasetools_library_defaults",
],
}
@@ -628,39 +604,9 @@
name: "releasetools_test",
defaults: ["releasetools_test_defaults"],
main: "test_utils.py",
- version: {
- py2: {
- enabled: true,
- // When using embedded launcher, atest will try (but may fail) to load libc++.so from
- // host, because the test executable won't be able to find the needed libs via its
- // runpath.
- embedded_launcher: false,
- },
- py3: {
- enabled: false,
- embedded_launcher: false,
- },
- },
- test_options: {
- unit_test: true,
- },
-}
-
-python_test_host {
- name: "releasetools_py3_test",
- defaults: ["releasetools_test_defaults"],
- main: "test_utils.py",
- test_suites: ["general-tests"],
- version: {
- py2: {
- enabled: false,
- embedded_launcher: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: false,
- },
- },
+ // Don't use embedded_launcher, atest will try (but may fail) to load libc++.so from
+ // host, because the test executable won't be able to find the needed libs via its
+ // runpath.
test_options: {
unit_test: true,
},
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 38104af..34aa1a6 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -24,6 +24,7 @@
from __future__ import print_function
+import glob
import logging
import os
import os.path
@@ -34,6 +35,9 @@
import common
import verity_utils
+from fsverity_digests_pb2 import FSVerityDigests
+from fsverity_metadata_generator import FSVerityMetadataGenerator
+
logger = logging.getLogger(__name__)
OPTIONS = common.OPTIONS
@@ -447,6 +451,68 @@
return mkfs_output
+def GenerateFSVerityMetadata(in_dir, fsverity_path, apk_key_path, apk_manifest_path, apk_out_path):
+ """Generates fsverity metadata files.
+
+ By setting PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA := true, fsverity
+ metadata files will be generated. For the input files, see `patterns` below.
+
+ One metadata file per one input file will be generated with the suffix
+ .fsv_meta. e.g. system/framework/foo.jar -> system/framework/foo.jar.fsv_meta
+ Also a mapping file containing fsverity digests will be generated to
+ system/etc/security/fsverity/BuildManifest.apk.
+
+ Args:
+ in_dir: temporary working directory (same as BuildImage)
+ fsverity_path: path to host tool fsverity
+ apk_key_path: path to key (e.g. build/make/target/product/security/platform)
+ apk_manifest_path: path to AndroidManifest.xml for APK
+ apk_out_path: path to the output APK
+
+ Returns:
+ None. The files are generated directly under in_dir.
+ """
+
+ patterns = [
+ "system/framework/*.jar",
+ "system/framework/oat/*/*.oat",
+ "system/framework/oat/*/*.vdex",
+ "system/framework/oat/*/*.art",
+ "system/etc/boot-image.prof",
+ "system/etc/dirty-image-objects",
+ ]
+ files = []
+ for pattern in patterns:
+ files += glob.glob(os.path.join(in_dir, pattern))
+ files = sorted(set(files))
+
+ generator = FSVerityMetadataGenerator(fsverity_path)
+ generator.set_hash_alg("sha256")
+
+ digests = FSVerityDigests()
+ for f in files:
+ generator.generate(f)
+ # f is a full path for now; make it relative so it starts with {mount_point}/
+ digest = digests.digests[os.path.relpath(f, in_dir)]
+ digest.digest = generator.digest(f)
+ digest.hash_alg = "sha256"
+
+ temp_dir = common.MakeTempDir()
+
+ os.mkdir(os.path.join(temp_dir, "assets"))
+ metadata_path = os.path.join(temp_dir, "assets", "build_manifest")
+ with open(metadata_path, "wb") as f:
+ f.write(digests.SerializeToString())
+
+ apk_path = os.path.join(in_dir, apk_out_path)
+
+ common.RunAndCheckOutput(["aapt2", "link",
+ "-A", os.path.join(temp_dir, "assets"),
+ "-o", apk_path,
+ "--manifest", apk_manifest_path])
+ common.RunAndCheckOutput(["apksigner", "sign", "--in", apk_path,
+ "--cert", apk_key_path + ".x509.pem",
+ "--key", apk_key_path + ".pk8"])
def BuildImage(in_dir, prop_dict, out_file, target_out=None):
"""Builds an image for the files under in_dir and writes it to out_file.
@@ -475,6 +541,13 @@
elif fs_type.startswith("f2fs") and prop_dict.get("f2fs_compress") == "true":
fs_spans_partition = False
+ if "fsverity_generate_metadata" in prop_dict:
+ GenerateFSVerityMetadata(in_dir,
+ fsverity_path=prop_dict["fsverity"],
+ apk_key_path=prop_dict["fsverity_apk_key"],
+ apk_manifest_path=prop_dict["fsverity_apk_manifest"],
+ apk_out_path=prop_dict["fsverity_apk_out"])
+
# Get a builder for creating an image that's to be verified by Verified Boot,
# or None if not applicable.
verity_image_builder = verity_utils.CreateVerityImageBuilder(prop_dict)
@@ -578,6 +651,10 @@
if not mkfs_output:
mkfs_output = BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
+ # Update the image (eg filesystem size). This can be different eg if mkfs
+ # rounds the requested size down due to alignment.
+ prop_dict["image_size"] = common.sparse_img.GetImagePartitionSize(out_file)
+
# Check if there's enough headroom space available for ext4 image.
if "partition_headroom" in prop_dict and fs_type.startswith("ext4"):
CheckHeadroom(mkfs_output, prop_dict)
@@ -589,7 +666,6 @@
if verity_image_builder:
verity_image_builder.Build(out_file)
-
def ImagePropFromGlobalDict(glob_dict, mount_point):
"""Build an image property dictionary from the global dictionary.
@@ -725,6 +801,11 @@
copy_prop("system_root_image", "system_root_image")
copy_prop("root_dir", "root_dir")
copy_prop("root_fs_config", "root_fs_config")
+ copy_prop("fsverity", "fsverity")
+ copy_prop("fsverity_generate_metadata", "fsverity_generate_metadata")
+ copy_prop("fsverity_apk_key","fsverity_apk_key")
+ copy_prop("fsverity_apk_manifest","fsverity_apk_manifest")
+ copy_prop("fsverity_apk_out","fsverity_apk_out")
elif mount_point == "data":
# Copy the generic fs type first, override with specific one if available.
copy_prop("flash_logical_block_size", "flash_logical_block_size")
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index a2ddfe7..213ae21 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -132,7 +132,7 @@
'checkvintf',
'--check-compat',
]
- for device_path, real_path in dirmap.items():
+ for device_path, real_path in sorted(dirmap.items()):
common_command += ['--dirmap', '{}:{}'.format(device_path, real_path)]
common_command += kernel_args
common_command += shipping_api_level_args
@@ -165,7 +165,15 @@
def PathToPatterns(path):
if path[-1] == '/':
path += '*'
- for device_path, target_files_rel_paths in DIR_SEARCH_PATHS.items():
+
+ # Loop over all the entries in DIR_SEARCH_PATHS and find one where the key
+ # is a prefix of path. In order to get find the correct prefix, sort the
+ # entries by decreasing length of their keys, so that we check if longer
+ # strings are prefixes before shorter strings. This is so that keys that
+ # are substrings of other keys (like /system vs /system_ext) are checked
+ # later, and we don't mistakenly mark a path that starts with /system_ext
+ # as starting with only /system.
+ for device_path, target_files_rel_paths in sorted(DIR_SEARCH_PATHS.items(), key=lambda i: len(i[0]), reverse=True):
if path.startswith(device_path):
suffix = path[len(device_path):]
return [rel_path + suffix for rel_path in target_files_rel_paths]
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 1937f29..64ac95a 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -68,6 +68,9 @@
self.search_path = os.path.dirname(os.path.dirname(exec_path))
self.signapk_path = "framework/signapk.jar" # Relative to search_path
+ if not os.path.exists(os.path.join(self.search_path, self.signapk_path)):
+ if "ANDROID_HOST_OUT" in os.environ:
+ self.search_path = os.environ["ANDROID_HOST_OUT"]
self.signapk_shared_library_path = "lib64" # Relative to search_path
self.extra_signapk_args = []
self.java_path = "java" # Use the one on the path by default.
@@ -973,6 +976,8 @@
break
except KeyError:
logger.warning('Failed to read %s', prop_file)
+ if data == '':
+ logger.warning("Failed to read build.prop for partition {}".format(name))
return data
@staticmethod
@@ -2105,7 +2110,9 @@
need_passwords = []
key_passwords = {}
devnull = open("/dev/null", "w+b")
- for k in sorted(keylist):
+
+ # sorted() can't compare strings to None, so convert Nones to strings
+ for k in sorted(keylist, key=lambda x: x if x is not None else ""):
# We don't need a password for things that aren't really keys.
if k in SPECIAL_CERT_STRINGS or k is None:
no_passwords.append(k)
diff --git a/tools/releasetools/fsverity_metadata_generator.py b/tools/releasetools/fsverity_metadata_generator.py
new file mode 100644
index 0000000..666efd5
--- /dev/null
+++ b/tools/releasetools/fsverity_metadata_generator.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+#
+# Copyright 2021 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+`fsverity_metadata_generator` generates fsverity metadata and signature to a
+container file
+
+This actually is a simple wrapper around the `fsverity` program. A file is
+signed by the program which produces the PKCS#7 signature file, merkle tree file
+, and the fsverity_descriptor file. Then the files are packed into a single
+output file so that the information about the signing stays together.
+
+Currently, the output of this script is used by `fd_server` which is the host-
+side backend of an authfs filesystem. `fd_server` uses this file in case when
+the underlying filesystem (ext4, etc.) on the device doesn't support the
+fsverity feature natively in which case the information is read directly from
+the filesystem using ioctl.
+"""
+
+import argparse
+import os
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+from struct import *
+
+class TempDirectory(object):
+ def __enter__(self):
+ self.name = tempfile.mkdtemp()
+ return self.name
+
+ def __exit__(self, *unused):
+ shutil.rmtree(self.name)
+
+class FSVerityMetadataGenerator:
+ def __init__(self, fsverity_path):
+ self._fsverity_path = fsverity_path
+
+ # Default values for some properties
+ self.set_hash_alg("sha256")
+ self.set_signature('none')
+
+ def set_key(self, key):
+ self._key = key
+
+ def set_cert(self, cert):
+ self._cert = cert
+
+ def set_hash_alg(self, hash_alg):
+ self._hash_alg = hash_alg
+
+ def set_signature(self, signature):
+ self._signature = signature
+
+ def _raw_signature(pkcs7_sig_file):
+ """ Extracts raw signature from DER formatted PKCS#7 detached signature file
+
+ Do that by parsing the ASN.1 tree to get the location of the signature
+ in the file and then read the portion.
+ """
+
+ # Note: there seems to be no public python API (even in 3p modules) that
+ # provides direct access to the raw signature at this moment. So, `openssl
+ # asn1parse` commandline tool is used instead.
+ cmd = ['openssl', 'asn1parse']
+ cmd.extend(['-inform', 'DER'])
+ cmd.extend(['-in', pkcs7_sig_file])
+ out = subprocess.check_output(cmd, universal_newlines=True)
+
+ # The signature is the last element in the tree
+ last_line = out.splitlines()[-1]
+ m = re.search('(\d+):.*hl=\s*(\d+)\s*l=\s*(\d+)\s*.*OCTET STRING', last_line)
+ if not m:
+ raise RuntimeError("Failed to parse asn1parse output: " + out)
+ offset = int(m.group(1))
+ header_len = int(m.group(2))
+ size = int(m.group(3))
+ with open(pkcs7_sig_file, 'rb') as f:
+ f.seek(offset + header_len)
+ return f.read(size)
+
+ def digest(self, input_file):
+ cmd = [self._fsverity_path, 'digest', input_file]
+ cmd.extend(['--compact'])
+ cmd.extend(['--hash-alg', self._hash_alg])
+ out = subprocess.check_output(cmd, universal_newlines=True).strip()
+ return bytes(bytearray.fromhex(out))
+
+ def generate(self, input_file, output_file=None):
+ if self._signature != 'none':
+ if not self._key:
+ raise RuntimeError("key must be specified.")
+ if not self._cert:
+ raise RuntimeError("cert must be specified.")
+
+ if not output_file:
+ output_file = input_file + '.fsv_meta'
+
+ with TempDirectory() as temp_dir:
+ self._do_generate(input_file, output_file, temp_dir)
+
+ def _do_generate(self, input_file, output_file, work_dir):
+ # temporary files
+ desc_file = os.path.join(work_dir, 'desc')
+ merkletree_file = os.path.join(work_dir, 'merkletree')
+ sig_file = os.path.join(work_dir, 'signature')
+
+ # run the fsverity util to create the temporary files
+ cmd = [self._fsverity_path]
+ if self._signature == 'none':
+ cmd.append('digest')
+ cmd.append(input_file)
+ else:
+ cmd.append('sign')
+ cmd.append(input_file)
+ cmd.append(sig_file)
+
+ # convert DER private key to PEM
+ pem_key = os.path.join(work_dir, 'key.pem')
+ key_cmd = ['openssl', 'pkcs8']
+ key_cmd.extend(['-inform', 'DER'])
+ key_cmd.extend(['-in', self._key])
+ key_cmd.extend(['-nocrypt'])
+ key_cmd.extend(['-out', pem_key])
+ subprocess.check_call(key_cmd)
+
+ cmd.extend(['--key', pem_key])
+ cmd.extend(['--cert', self._cert])
+ cmd.extend(['--hash-alg', self._hash_alg])
+ cmd.extend(['--block-size', '4096'])
+ cmd.extend(['--out-merkle-tree', merkletree_file])
+ cmd.extend(['--out-descriptor', desc_file])
+ subprocess.check_call(cmd, stdout=open(os.devnull, 'w'))
+
+ with open(output_file, 'wb') as out:
+ # 1. version
+ out.write(pack('<I', 1))
+
+ # 2. fsverity_descriptor
+ with open(desc_file, 'rb') as f:
+ out.write(f.read())
+
+ # 3. signature
+ SIG_TYPE_NONE = 0
+ SIG_TYPE_PKCS7 = 1
+ SIG_TYPE_RAW = 2
+ if self._signature == 'raw':
+ out.write(pack('<I', SIG_TYPE_RAW))
+ sig = self._raw_signature(sig_file)
+ out.write(pack('<I', len(sig)))
+ out.write(sig)
+ elif self._signature == 'pkcs7':
+ with open(sig_file, 'rb') as f:
+ out.write(pack('<I', SIG_TYPE_PKCS7))
+ sig = f.read()
+ out.write(pack('<I', len(sig)))
+ out.write(sig)
+ else:
+ out.write(pack('<I', SIG_TYPE_NONE))
+
+ # 4. merkle tree
+ with open(merkletree_file, 'rb') as f:
+ # merkle tree is placed at the next nearest page boundary to make
+ # mmapping possible
+ out.seek(next_page(out.tell()))
+ out.write(f.read())
+
+def next_page(n):
+ """ Returns the next nearest page boundary from `n` """
+ PAGE_SIZE = 4096
+ return (n + PAGE_SIZE - 1) // PAGE_SIZE * PAGE_SIZE
+
+if __name__ == '__main__':
+ p = argparse.ArgumentParser()
+ p.add_argument(
+ '--output',
+ help='output file. If omitted, print to <INPUT>.fsv_meta',
+ metavar='output',
+ default=None)
+ p.add_argument(
+ 'input',
+ help='input file to be signed')
+ p.add_argument(
+ '--key',
+ help='PKCS#8 private key file in DER format')
+ p.add_argument(
+ '--cert',
+ help='x509 certificate file in PEM format')
+ p.add_argument(
+ '--hash-alg',
+ help='hash algorithm to use to build the merkle tree',
+ choices=['sha256', 'sha512'],
+ default='sha256')
+ p.add_argument(
+ '--signature',
+ help='format for signature',
+ choices=['none', 'raw', 'pkcs7'],
+ default='none')
+ p.add_argument(
+ '--fsverity-path',
+ help='path to the fsverity program',
+ required=True)
+ args = p.parse_args(sys.argv[1:])
+
+ generator = FSVerityMetadataGenerator(args.fsverity_path)
+ generator.set_signature(args.signature)
+ if args.signature == 'none':
+ if args.key or args.cert:
+ raise ValueError("When signature is none, key and cert can't be set")
+ else:
+ if not args.key or not args.cert:
+ raise ValueError("To generate signature, key and cert must be set")
+ generator.set_key(args.key)
+ generator.set_cert(args.cert)
+ generator.set_hash_alg(args.hash_alg)
+ generator.generate(args.input, args.output)
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index ec703ab..c21de14 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1331,49 +1331,49 @@
return True
args = common.ParseOptions(argv, __doc__,
- extra_opts="b:k:i:d:e:t:2o:",
- extra_long_opts=[
- "package_key=",
- "incremental_from=",
- "full_radio",
- "full_bootloader",
- "wipe_user_data",
- "downgrade",
- "override_timestamp",
- "extra_script=",
- "worker_threads=",
- "two_step",
- "include_secondary",
- "no_signing",
- "block",
- "binary=",
- "oem_settings=",
- "oem_no_mount",
- "verify",
- "stash_threshold=",
- "log_diff=",
- "payload_signer=",
- "payload_signer_args=",
- "payload_signer_maximum_signature_size=",
- "payload_signer_key_size=",
- "extracted_input_target_files=",
- "skip_postinstall",
- "retrofit_dynamic_partitions",
- "skip_compatibility_check",
- "output_metadata_path=",
- "disable_fec_computation",
- "disable_verity_computation",
- "force_non_ab",
- "boot_variable_file=",
- "partial=",
- "custom_image=",
- "disable_vabc",
- "spl_downgrade",
- "vabc_downgrade",
- "enable_vabc_xor=",
- "force_minor_version=",
- "compressor_types=",
- ], extra_option_handler=option_handler)
+ extra_opts="b:k:i:d:e:t:2o:",
+ extra_long_opts=[
+ "package_key=",
+ "incremental_from=",
+ "full_radio",
+ "full_bootloader",
+ "wipe_user_data",
+ "downgrade",
+ "override_timestamp",
+ "extra_script=",
+ "worker_threads=",
+ "two_step",
+ "include_secondary",
+ "no_signing",
+ "block",
+ "binary=",
+ "oem_settings=",
+ "oem_no_mount",
+ "verify",
+ "stash_threshold=",
+ "log_diff=",
+ "payload_signer=",
+ "payload_signer_args=",
+ "payload_signer_maximum_signature_size=",
+ "payload_signer_key_size=",
+ "extracted_input_target_files=",
+ "skip_postinstall",
+ "retrofit_dynamic_partitions",
+ "skip_compatibility_check",
+ "output_metadata_path=",
+ "disable_fec_computation",
+ "disable_verity_computation",
+ "force_non_ab",
+ "boot_variable_file=",
+ "partial=",
+ "custom_image=",
+ "disable_vabc",
+ "spl_downgrade",
+ "vabc_downgrade",
+ "enable_vabc_xor=",
+ "force_minor_version=",
+ "compressor_types=",
+ ], extra_option_handler=option_handler)
if len(args) != 2:
common.Usage(__doc__)
@@ -1473,13 +1473,23 @@
"build/make/target/product/security/testkey")
# Get signing keys
OPTIONS.key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
- private_key_path = OPTIONS.package_key + OPTIONS.private_key_suffix
- if not os.path.exists(private_key_path):
- raise common.ExternalError(
- "Private key {} doesn't exist. Make sure you passed the"
- " correct key path through -k option".format(
- private_key_path)
- )
+
+ # Only check for existence of key file if using the default signer.
+ # Because the custom signer might not need the key file AT all.
+ # b/191704641
+ if not OPTIONS.payload_signer:
+ private_key_path = OPTIONS.package_key + OPTIONS.private_key_suffix
+ if not os.path.exists(private_key_path):
+ raise common.ExternalError(
+ "Private key {} doesn't exist. Make sure you passed the"
+ " correct key path through -k option".format(
+ private_key_path)
+ )
+ signapk_abs_path = os.path.join(
+ OPTIONS.search_path, OPTIONS.signapk_path)
+ if not os.path.exists(signapk_abs_path):
+ raise common.ExternalError(
+ "Failed to find sign apk binary {} in search path {}. Make sure the correct search path is passed via -p".format(OPTIONS.signapk_path, OPTIONS.search_path))
if OPTIONS.source_info_dict:
source_build_prop = OPTIONS.source_info_dict["build.prop"]
@@ -1531,8 +1541,5 @@
try:
common.CloseInheritedPipes()
main(sys.argv[1:])
- except common.ExternalError:
- logger.exception("\n ERROR:\n")
- sys.exit(1)
finally:
common.Cleanup()
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 5737009..6c5fc05 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -154,7 +154,7 @@
compress_type=zipfile.ZIP_STORED)
return
- with open('{}.pb'.format(output), 'w') as f:
+ with open('{}.pb'.format(output), 'wb') as f:
f.write(metadata_proto.SerializeToString())
with open(output, 'w') as f:
f.write(legacy_metadata)
diff --git a/tools/releasetools/target_files_diff.py b/tools/releasetools/target_files_diff.py
index 4402c8d..fa94c5b 100755
--- a/tools/releasetools/target_files_diff.py
+++ b/tools/releasetools/target_files_diff.py
@@ -82,7 +82,7 @@
skip = True
break
if not skip:
- new.write(line)
+ new.write(line.encode())
def trim_install_recovery(original, new):
@@ -91,7 +91,7 @@
partition.
"""
for line in original:
- new.write(re.sub(r'[0-9a-f]{40}', '0'*40, line))
+ new.write(re.sub(r'[0-9a-f]{40}', '0'*40, line).encode())
def sort_file(original, new):
"""
@@ -101,7 +101,7 @@
lines = original.readlines()
lines.sort()
for line in lines:
- new.write(line)
+ new.write(line.encode())
# Map files to the functions that will modify them for diffing
REWRITE_RULES = {
@@ -148,7 +148,7 @@
if stdout == 'Binary files %s and %s differ' % (f1, f2):
print("%s: Binary files differ" % name, file=out_file)
else:
- for line in stdout.strip().split('\n'):
+ for line in stdout.strip().split(b'\n'):
print("%s: %s" % (name, line), file=out_file)
def recursiveDiff(prefix, dir1, dir2, out_file):
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index 8bf1005..232e119 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -64,12 +64,19 @@
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
import java.security.Key;
import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStore.PrivateKeyEntry;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
+import java.security.UnrecoverableEntryException;
+import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
@@ -286,6 +293,32 @@
}
}
+ private static KeyStore createKeyStore(String keyStoreName, String keyStorePin) throws
+ CertificateException,
+ IOException,
+ KeyStoreException,
+ NoSuchAlgorithmException {
+ KeyStore keyStore = KeyStore.getInstance(keyStoreName);
+ keyStore.load(null, keyStorePin == null ? null : keyStorePin.toCharArray());
+ return keyStore;
+ }
+
+ /** Get a PKCS#11 private key from keyStore */
+ private static PrivateKey loadPrivateKeyFromKeyStore(
+ final KeyStore keyStore, final String keyName, final String password)
+ throws CertificateException, KeyStoreException, NoSuchAlgorithmException,
+ UnrecoverableKeyException, UnrecoverableEntryException {
+ final Key key = keyStore.getKey(keyName, password == null ? null : password.toCharArray());
+ final PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry(keyName, null);
+ if (privateKeyEntry == null) {
+ throw new Error(
+ "Key "
+ + keyName
+ + " not found in the token provided by PKCS11 library!");
+ }
+ return privateKeyEntry.getPrivateKey();
+ }
+
/**
* Add a copy of the public key to the archive; this should
* exactly match one of the files in
@@ -1022,6 +1055,8 @@
"[-a <alignment>] " +
"[--align-file-size] " +
"[-providerClass <className>] " +
+ "[-loadPrivateKeysFromKeyStore <keyStoreName>]" +
+ "[-keyStorePin <pin>]" +
"[--min-sdk-version <n>] " +
"[--disable-v2] " +
"[--enable-v4] " +
@@ -1044,6 +1079,8 @@
boolean signWholeFile = false;
String providerClass = null;
+ String keyStoreName = null;
+ String keyStorePin = null;
int alignment = 4;
boolean alignFileSize = false;
Integer minSdkVersionOverride = null;
@@ -1062,6 +1099,18 @@
}
providerClass = args[++argstart];
++argstart;
+ } else if ("-loadPrivateKeysFromKeyStore".equals(args[argstart])) {
+ if (argstart + 1 >= args.length) {
+ usage();
+ }
+ keyStoreName = args[++argstart];
+ ++argstart;
+ } else if ("-keyStorePin".equals(args[argstart])) {
+ if (argstart + 1 >= args.length) {
+ usage();
+ }
+ keyStorePin = args[++argstart];
+ ++argstart;
} else if ("-a".equals(args[argstart])) {
alignment = Integer.parseInt(args[++argstart]);
++argstart;
@@ -1142,11 +1191,21 @@
// timestamp using the current timezone. We thus adjust the milliseconds since epoch
// value to end up with MS-DOS timestamp of Jan 1 2009 00:00:00.
timestamp -= TimeZone.getDefault().getOffset(timestamp);
-
+ KeyStore keyStore = null;
+ if (keyStoreName != null) {
+ keyStore = createKeyStore(keyStoreName, keyStorePin);
+ }
PrivateKey[] privateKey = new PrivateKey[numKeys];
for (int i = 0; i < numKeys; ++i) {
int argNum = argstart + i*2 + 1;
- privateKey[i] = readPrivateKey(new File(args[argNum]));
+ if (keyStore == null) {
+ privateKey[i] = readPrivateKey(new File(args[argNum]));
+ } else {
+ String[] splits = args[argNum].split(":", 2);
+ final String keyAlias = splits[0];
+ final String password = splits.length > 1 ? splits[1] : null;
+ privateKey[i] = loadPrivateKeyFromKeyStore(keyStore, keyAlias, password);
+ }
}
inputJar = new JarFile(new File(inputFilename), false); // Don't verify.