Merge changes from topic "servicemanager-recovery"
* changes:
Add servicemanager.recovery to base_vendor.mk.
Add recovery service_contexts.
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 639c4ef..dd5c476 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -760,6 +760,15 @@
# 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))
+
# ************************************************
# 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/common/strings.mk b/common/strings.mk
index e560bf0..768d061 100644
--- a/common/strings.mk
+++ b/common/strings.mk
@@ -88,6 +88,24 @@
endef
###########################################################
+## Read a colon-separated sublist out of a colon-separated
+## list of words.
+## This has similar behavior to the built-in function
+## $(wordlist s,e,str) except both the input and output
+## word lists are colon-separated.
+##
+## The individual words may not contain spaces.
+##
+## $(1): 1 based index start
+## $(2): 1 based index end (can be 0)
+## $(3): value of the form a:b:c...
+###########################################################
+
+define wordlist-colon
+$(subst $(space),:,$(wordlist $(1),$(2),$(subst :,$(space),$(3))))
+endef
+
+###########################################################
## Convert "a=b c= d e = f = g h=" into "a=b c=d e= f=g h="
##
## $(1): list to collapse
diff --git a/core/Makefile b/core/Makefile
index 163a205..6498a47 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 $@
@@ -778,7 +790,7 @@
$(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
ifeq ($(HOST_OS),linux)
-$(call dist-for-goals, sdk win_sdk sdk_addon, $(INSTALLED_FILES_FILE_ROOT))
+$(call dist-for-goals, sdk sdk_addon, $(INSTALLED_FILES_FILE_ROOT))
endif
#------------------------------------------------------------------
@@ -1291,6 +1303,9 @@
$(hide) $(MINIGZIP) -9 < $< > $@
$(installed_notice_html_or_xml_gz): $(target_notice_file_html_gz)
$(copy-file-to-target)
+
+$(call declare-0p-target,$(target_notice_file_html_gz))
+$(call declare-0p-target,$(installed_notice_html_or_xml_gz))
else
target_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE.xml
target_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE.xml.gz
@@ -1474,6 +1489,28 @@
$(installed_odm_dlkm_notice_xml_gz): $(target_odm_dlkm_notice_file_xml_gz)
$(copy-file-to-target)
+$(call declare-0p-target,$(target_notice_file_xml))
+$(call declare-0p-target,$(target_notice_file_xml_gz))
+$(call declare-0p-target,$(target_vendor_notice_file_xml))
+$(call declare-0p-target,$(target_vendor_notice_file_xml_gz))
+$(call declare-0p-target,$(target_product_notice_file_xml))
+$(call declare-0p-target,$(target_product_notice_file_xml_gz))
+$(call declare-0p-target,$(target_system_ext_notice_file_xml))
+$(call declare-0p-target,$(target_system_ext_notice_file_xml_gz))
+$(call declare-0p-target,$(target_odm_notice_file_xml))
+$(call declare-0p-target,$(target_odm_notice_file_xml_gz))
+$(call declare-0p-target,$(target_vendor_dlkm_notice_file_xml))
+$(call declare-0p-target,$(target_vendor_dlkm_notice_file_xml_gz))
+$(call declare-0p-target,$(target_odm_dlkm_notice_file_xml))
+$(call declare-0p-target,$(target_odm_dlkm_notice_file_xml_gz))
+$(call declare-0p-target,$(installed_notice_html_or_xml_gz))
+$(call declare-0p-target,$(installed_vendor_notice_xml_gz))
+$(call declare-0p-target,$(installed_product_notice_xml_gz))
+$(call declare-0p-target,$(installed_system_ext_notice_xml_gz))
+$(call declare-0p-target,$(installed_odm_notice_xml_gz))
+$(call declare-0p-target,$(installed_vendor_dlkm_notice_xml_gz))
+$(call declare-0p-target,$(installed_odm_dlkm_notice_xml_gz))
+
ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_or_xml_gz)
ALL_DEFAULT_INSTALLED_MODULES += $(installed_vendor_notice_xml_gz)
ALL_DEFAULT_INSTALLED_MODULES += $(installed_product_notice_xml_gz)
@@ -1617,7 +1654,8 @@
# $(2) the image prop file
define add-common-ro-flags-to-image-props
$(eval _var := $(call to-upper,$(1)))
-$(if $(BOARD_$(_var)IMAGE_EROFS_COMPRESSOR),$(hide) echo "$(1)_erofs_compressor"$(BOARD_$(_var)IMAGE_EROFS_COMPRESSOR)" >> $(2))
+$(if $(BOARD_$(_var)IMAGE_EROFS_COMPRESSOR),$(hide) echo "$(1)_erofs_compressor=$(BOARD_$(_var)IMAGE_EROFS_COMPRESSOR)" >> $(2))
+$(if $(BOARD_$(_var)IMAGE_EROFS_PCLUSTER_SIZE),$(hide) echo "$(1)_erofs_pcluster_size=$(BOARD_$(_var)IMAGE_EROFS_PCLUSTER_SIZE)" >> $(2))
$(if $(BOARD_$(_var)IMAGE_EXTFS_INODE_COUNT),$(hide) echo "$(1)_extfs_inode_count=$(BOARD_$(_var)IMAGE_EXTFS_INODE_COUNT)" >> $(2))
$(if $(BOARD_$(_var)IMAGE_EXTFS_RSV_PCT),$(hide) echo "$(1)_extfs_rsv_pct=$(BOARD_$(_var)IMAGE_EXTFS_RSV_PCT)" >> $(2))
$(if $(BOARD_$(_var)IMAGE_F2FS_SLOAD_COMPRESS_FLAGS),$(hide) echo "$(1)_f2fs_sldc_flags=$(BOARD_$(_var)IMAGE_F2FS_SLOAD_COMPRESS_FLAGS)" >> $(2))
@@ -1634,6 +1672,8 @@
$(eval _size := $(BOARD_$(_var)IMAGE_PARTITION_SIZE))
$(eval _reserved := $(BOARD_$(_var)IMAGE_PARTITION_RESERVED_SIZE))
$(eval _headroom := $(PRODUCT_$(_var)_HEADROOM))
+$(if $(or $(_size), $(_reserved), $(_headroom)),,
+ $(hide) echo "$(1)_disable_sparse=true" >> $(2))
$(call add-common-flags-to-image-props,$(1),$(2))
endef
@@ -1644,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),\
@@ -1697,6 +1742,8 @@
$(if $(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG),$(hide) echo "squashfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG)" >> $(1))
$(if $(INTERNAL_USERIMAGES_SPARSE_F2FS_FLAG),$(hide) echo "f2fs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_F2FS_FLAG)" >> $(1))
$(if $(BOARD_EROFS_COMPRESSOR),$(hide) echo "erofs_default_compressor=$(BOARD_EROFS_COMPRESSOR)" >> $(1))
+$(if $(BOARD_EROFS_PCLUSTER_SIZE),$(hide) echo "erofs_pcluster_size=$(BOARD_EROFS_PCLUSTER_SIZE)" >> $(1))
+$(if $(BOARD_EROFS_SHARE_DUP_BLOCKS),$(hide) echo "erofs_share_dup_blocks=$(BOARD_EROFS_SHARE_DUP_BLOCKS)" >> $(1))
$(if $(BOARD_EXT4_SHARE_DUP_BLOCKS),$(hide) echo "ext4_share_dup_blocks=$(BOARD_EXT4_SHARE_DUP_BLOCKS)" >> $(1))
$(if $(BOARD_FLASH_LOGICAL_BLOCK_SIZE), $(hide) echo "flash_logical_block_size=$(BOARD_FLASH_LOGICAL_BLOCK_SIZE)" >> $(1))
$(if $(BOARD_FLASH_ERASE_BLOCK_SIZE), $(hide) echo "flash_erase_block_size=$(BOARD_FLASH_ERASE_BLOCK_SIZE)" >> $(1))
@@ -2293,18 +2340,44 @@
# Build debug ramdisk and debug boot image.
ifneq ($(BUILDING_DEBUG_BOOT_IMAGE)$(BUILDING_DEBUG_VENDOR_BOOT_IMAGE),)
+INTERNAL_DEBUG_RAMDISK_FILES := $(filter $(TARGET_DEBUG_RAMDISK_OUT)/%, \
+ $(ALL_GENERATED_SOURCES) \
+ $(ALL_DEFAULT_INSTALLED_MODULES))
+
+# Directories to be picked into the debug ramdisk.
+# As these directories are all merged into one single cpio archive, the order
+# matters. If there are multiple files with the same pathname, then the last one
+# wins.
+#
# ramdisk-debug.img will merge the content from either ramdisk.img or
# ramdisk-recovery.img, depending on whether BOARD_USES_RECOVERY_AS_BOOT
# is set or not.
-# INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP would ensure INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR is created.
ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
- INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR := $(TARGET_RECOVERY_ROOT_OUT)
- INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP := $(recovery_ramdisk)
+ INTERNAL_DEBUG_RAMDISK_SRC_DIRS := $(TARGET_RECOVERY_ROOT_OUT)
+ INTERNAL_DEBUG_RAMDISK_SRC_RAMDISK_TARGET := $(recovery_ramdisk)
else # BOARD_USES_RECOVERY_AS_BOOT == true
- INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR := $(TARGET_RAMDISK_OUT)
- INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP := $(INSTALLED_RAMDISK_TARGET)
+ INTERNAL_DEBUG_RAMDISK_SRC_DIRS := $(TARGET_RAMDISK_OUT)
+ INTERNAL_DEBUG_RAMDISK_SRC_RAMDISK_TARGET := $(INSTALLED_RAMDISK_TARGET)
endif # BOARD_USES_RECOVERY_AS_BOOT != true
+INTERNAL_DEBUG_RAMDISK_SRC_DIRS += $(TARGET_DEBUG_RAMDISK_OUT)
+INTERNAL_DEBUG_RAMDISK_SRC_DEPS := $(INTERNAL_DEBUG_RAMDISK_SRC_RAMDISK_TARGET) $(INTERNAL_DEBUG_RAMDISK_FILES)
+
+# INSTALLED_FILES_FILE_DEBUG_RAMDISK would ensure TARGET_DEBUG_RAMDISK_OUT is created.
+INSTALLED_FILES_FILE_DEBUG_RAMDISK := $(PRODUCT_OUT)/installed-files-ramdisk-debug.txt
+INSTALLED_FILES_JSON_DEBUG_RAMDISK := $(INSTALLED_FILES_FILE_DEBUG_RAMDISK:.txt=.json)
+$(INSTALLED_FILES_FILE_DEBUG_RAMDISK): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_DEBUG_RAMDISK)
+$(INSTALLED_FILES_FILE_DEBUG_RAMDISK): $(INTERNAL_DEBUG_RAMDISK_SRC_DEPS)
+$(INSTALLED_FILES_FILE_DEBUG_RAMDISK): $(FILESLIST) $(FILESLIST_UTIL)
+ @echo "Installed file list: $@"
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@) $(TARGET_DEBUG_RAMDISK_OUT)
+ touch $(TARGET_DEBUG_RAMDISK_OUT)/force_debuggable
+ $(FILESLIST) $(INTERNAL_DEBUG_RAMDISK_SRC_DIRS) > $(@:.txt=.json)
+ $(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
+
+ifdef BUILDING_DEBUG_BOOT_IMAGE
+
# -----------------------------------------------------------------
# the debug ramdisk, which is the original ramdisk plus additional
# files: force_debuggable, adb_debug.prop and userdebug sepolicy.
@@ -2312,57 +2385,38 @@
# and property files to allow adb root, if the device is unlocked.
INSTALLED_DEBUG_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk-debug.img
-INTERNAL_DEBUG_RAMDISK_FILES := $(filter $(TARGET_DEBUG_RAMDISK_OUT)/%, \
- $(ALL_GENERATED_SOURCES) \
- $(ALL_DEFAULT_INSTALLED_MODULES))
-
-# INSTALLED_FILES_FILE_DEBUG_RAMDISK would ensure TARGET_DEBUG_RAMDISK_OUT is created.
-INSTALLED_FILES_FILE_DEBUG_RAMDISK := $(PRODUCT_OUT)/installed-files-ramdisk-debug.txt
-INSTALLED_FILES_JSON_DEBUG_RAMDISK := $(INSTALLED_FILES_FILE_DEBUG_RAMDISK:.txt=.json)
-$(INSTALLED_FILES_FILE_DEBUG_RAMDISK): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_DEBUG_RAMDISK)
-$(INSTALLED_FILES_FILE_DEBUG_RAMDISK): $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP)
-$(INSTALLED_FILES_FILE_DEBUG_RAMDISK) : $(INTERNAL_DEBUG_RAMDISK_FILES) $(FILESLIST) $(FILESLIST_UTIL)
- @echo Installed file list: $@
- mkdir -p $(dir $@)
- rm -f $@
- $(FILESLIST) $(TARGET_DEBUG_RAMDISK_OUT) $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR) > $(@:.txt=.json)
- $(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
-
$(INSTALLED_DEBUG_RAMDISK_TARGET): $(INSTALLED_FILES_FILE_DEBUG_RAMDISK)
-$(INSTALLED_DEBUG_RAMDISK_TARGET): $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP)
-$(INSTALLED_DEBUG_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_DEBUG_RAMDISK_FILES) | $(COMPRESSION_COMMAND_DEPS)
- $(call pretty,"Target debug ramdisk: $@")
- mkdir -p $(TARGET_DEBUG_RAMDISK_OUT)
- touch $(TARGET_DEBUG_RAMDISK_OUT)/force_debuggable
- $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_DEBUG_RAMDISK_OUT) $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR) | $(COMPRESSION_COMMAND) > $@
+$(INSTALLED_DEBUG_RAMDISK_TARGET): $(MKBOOTFS) | $(COMPRESSION_COMMAND_DEPS)
+ @echo "Target debug ramdisk: $@"
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@)
+ $(MKBOOTFS) -d $(TARGET_OUT) $(INTERNAL_DEBUG_RAMDISK_SRC_DIRS) | $(COMPRESSION_COMMAND) > $@
.PHONY: ramdisk_debug-nodeps
ramdisk_debug-nodeps: $(MKBOOTFS) | $(COMPRESSION_COMMAND_DEPS)
- echo "make $@: ignoring dependencies"
- mkdir -p $(TARGET_DEBUG_RAMDISK_OUT) $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR)
- touch $(TARGET_DEBUG_RAMDISK_OUT)/force_debuggable
- $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_DEBUG_RAMDISK_OUT) $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR) | $(COMPRESSION_COMMAND) > $(INSTALLED_DEBUG_RAMDISK_TARGET)
+ @echo "make $@: ignoring dependencies"
+ $(hide) rm -f $(INSTALLED_DEBUG_RAMDISK_TARGET)
+ $(hide) mkdir -p $(dir $(INSTALLED_DEBUG_RAMDISK_TARGET)) $(INTERNAL_DEBUG_RAMDISK_SRC_DIRS)
+ $(MKBOOTFS) -d $(TARGET_OUT) $(INTERNAL_DEBUG_RAMDISK_SRC_DIRS) | $(COMPRESSION_COMMAND) > $(INSTALLED_DEBUG_RAMDISK_TARGET)
# -----------------------------------------------------------------
# the boot-debug.img, which is the kernel plus ramdisk-debug.img
#
# Note: it's intentional to skip signing for boot-debug.img, because it
# can only be used if the device is unlocked with verification error.
-ifdef BUILDING_DEBUG_BOOT_IMAGE
-
ifneq ($(strip $(BOARD_KERNEL_BINARIES)),)
- INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(foreach k,$(subst kernel,$(DEBUG_RAMDISK_BOOT_IMAGE_NAME),$(BOARD_KERNEL_BINARIES)), \
+ INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(foreach k,$(subst kernel,boot-debug,$(BOARD_KERNEL_BINARIES)), \
$(PRODUCT_OUT)/$(k).img)
else
- INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/$(DEBUG_RAMDISK_BOOT_IMAGE_NAME).img
+ INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot-debug.img
endif
# Replace ramdisk.img in $(MKBOOTIMG) ARGS with ramdisk-debug.img to build boot-debug.img
$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(INSTALLED_DEBUG_RAMDISK_TARGET)
ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
- INTERNAL_DEBUG_BOOTIMAGE_ARGS := $(subst $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP),$(INSTALLED_DEBUG_RAMDISK_TARGET),$(INTERNAL_RECOVERYIMAGE_ARGS))
+ INTERNAL_DEBUG_BOOTIMAGE_ARGS := $(subst $(INTERNAL_DEBUG_RAMDISK_SRC_RAMDISK_TARGET),$(INSTALLED_DEBUG_RAMDISK_TARGET),$(INTERNAL_RECOVERYIMAGE_ARGS))
else
- INTERNAL_DEBUG_BOOTIMAGE_ARGS := $(subst $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP),$(INSTALLED_DEBUG_RAMDISK_TARGET),$(INTERNAL_BOOTIMAGE_ARGS))
+ INTERNAL_DEBUG_BOOTIMAGE_ARGS := $(subst $(INTERNAL_DEBUG_RAMDISK_SRC_RAMDISK_TARGET),$(INSTALLED_DEBUG_RAMDISK_TARGET),$(INTERNAL_BOOTIMAGE_ARGS))
endif
# If boot.img is chained but boot-debug.img is not signed, libavb in bootloader
@@ -2389,10 +2443,10 @@
# $(1): output file
define build-debug-bootimage-target
- $(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst $(DEBUG_RAMDISK_BOOT_IMAGE_NAME),kernel,$(notdir $(1)))) \
+ $(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-debug,kernel,$(notdir $(1)))) \
$(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
$(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1
- $(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$1,$(DEBUG_RAMDISK_BOOT_IMAGE_NAME)))
+ $(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$1,boot-debug))
endef
# Depends on original boot.img and ramdisk-debug.img, to build the new boot-debug.img
@@ -2416,35 +2470,41 @@
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES))
-INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK := $(PRODUCT_OUT)/installed-files-vendor-ramdisk-debug.txt
-INSTALLED_FILES_JSON_VENDOR_DEBUG_RAMDISK := $(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK:.txt=.json)
-$(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_VENDOR_DEBUG_RAMDISK)
-$(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK): $(INTERNAL_VENDOR_RAMDISK_TARGET) $(INSTALLED_DEBUG_RAMDISK_TARGET)
-$(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK): $(INTERNAL_VENDOR_DEBUG_RAMDISK_FILES) $(FILESLIST) $(FILESLIST_UTIL)
- @echo Installed file list: $@
- mkdir -p $(dir $@)
- rm -f $@
- mkdir -p $(TARGET_VENDOR_DEBUG_RAMDISK_OUT) # The dir might not be created if no modules are installed here.
- $(FILESLIST) $(TARGET_VENDOR_RAMDISK_OUT) $(TARGET_DEBUG_RAMDISK_OUT) $(TARGET_VENDOR_DEBUG_RAMDISK_OUT) > $(@:.txt=.json)
- $(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
-
-INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET := $(call intermediates-dir-for,PACKAGING,vendor_boot-debug)/vendor_ramdisk-debug.cpio$(RAMDISK_EXT)
+# The debug vendor ramdisk combines vendor ramdisk and debug ramdisk.
+INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DIRS := $(TARGET_VENDOR_RAMDISK_OUT)
+INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DEPS := $(INTERNAL_VENDOR_RAMDISK_TARGET)
# Exclude recovery files in the default vendor ramdisk if including a standalone
# recovery ramdisk in vendor_boot.
ifeq (true,$(BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT))
-ifneq (true,$(BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT))
-$(INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET): $(INTERNAL_RECOVERY_RAMDISK_FILES_TIMESTAMP)
-$(INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET): PRIVATE_ADDITIONAL_DIR := $(TARGET_RECOVERY_ROOT_OUT)
-endif
-endif
+ ifneq (true,$(BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT))
+ INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DIRS += $(TARGET_RECOVERY_ROOT_OUT)
+ INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DEPS += $(INTERNAL_RECOVERY_RAMDISK_FILES_TIMESTAMP)
+ endif # BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT != true
+endif # BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT == true
-# The vendor debug ramdisk combines vendor ramdisk and debug ramdisk.
-$(INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET): $(INTERNAL_VENDOR_RAMDISK_TARGET) $(INSTALLED_DEBUG_RAMDISK_TARGET)
+INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DIRS += $(TARGET_VENDOR_DEBUG_RAMDISK_OUT) $(TARGET_DEBUG_RAMDISK_OUT)
+INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DEPS += $(INTERNAL_VENDOR_DEBUG_RAMDISK_FILES) $(INSTALLED_FILES_FILE_DEBUG_RAMDISK)
+
+# INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK would ensure TARGET_VENDOR_DEBUG_RAMDISK_OUT is created.
+INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK := $(PRODUCT_OUT)/installed-files-vendor-ramdisk-debug.txt
+INSTALLED_FILES_JSON_VENDOR_DEBUG_RAMDISK := $(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK:.txt=.json)
+$(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_VENDOR_DEBUG_RAMDISK)
+$(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK): $(INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DEPS)
+$(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK): $(FILESLIST) $(FILESLIST_UTIL)
+ @echo "Installed file list: $@"
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@) $(TARGET_VENDOR_DEBUG_RAMDISK_OUT)
+ $(FILESLIST) $(INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DIRS) > $(@:.txt=.json)
+ $(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
+
+INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET := $(call intermediates-dir-for,PACKAGING,vendor_boot-debug)/vendor_ramdisk-debug.cpio$(RAMDISK_EXT)
+
$(INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET): $(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK)
-$(INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_VENDOR_DEBUG_RAMDISK_FILES) | $(COMPRESSION_COMMAND_DEPS)
- mkdir -p $(TARGET_VENDOR_DEBUG_RAMDISK_OUT)
- $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_VENDOR_RAMDISK_OUT) $(TARGET_DEBUG_RAMDISK_OUT) $(TARGET_VENDOR_DEBUG_RAMDISK_OUT) $(PRIVATE_ADDITIONAL_DIR) | $(COMPRESSION_COMMAND) > $@
+$(INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET): $(MKBOOTFS) | $(COMPRESSION_COMMAND_DEPS)
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@)
+ $(MKBOOTFS) -d $(TARGET_OUT) $(INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DIRS) | $(COMPRESSION_COMMAND) > $@
INSTALLED_VENDOR_DEBUG_RAMDISK_TARGET := $(PRODUCT_OUT)/vendor_ramdisk-debug.img
$(INSTALLED_VENDOR_DEBUG_RAMDISK_TARGET): $(INTERNAL_VENDOR_DEBUG_RAMDISK_TARGET)
@@ -2483,53 +2543,62 @@
endif # BUILDING_DEBUG_VENDOR_BOOT_IMAGE
+# Appends a few test harness specific properties into the adb_debug.prop.
+ADDITIONAL_TEST_HARNESS_PROPERTIES := ro.audio.silent=1
+ADDITIONAL_TEST_HARNESS_PROPERTIES += ro.test_harness=1
+
+INTERNAL_DEBUG_RAMDISK_ADB_DEBUG_PROP_TARGET := $(strip $(filter $(TARGET_DEBUG_RAMDISK_OUT)/adb_debug.prop,$(INTERNAL_DEBUG_RAMDISK_FILES)))
+INTERNAL_TEST_HARNESS_RAMDISK_ADB_DEBUG_PROP_TARGET := $(TARGET_TEST_HARNESS_RAMDISK_OUT)/adb_debug.prop
+$(INTERNAL_TEST_HARNESS_RAMDISK_ADB_DEBUG_PROP_TARGET): $(INTERNAL_DEBUG_RAMDISK_ADB_DEBUG_PROP_TARGET)
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@)
+ifdef INTERNAL_DEBUG_RAMDISK_ADB_DEBUG_PROP_TARGET
+ $(hide) cp $(INTERNAL_DEBUG_RAMDISK_ADB_DEBUG_PROP_TARGET) $@
+endif
+ $(hide) echo "" >> $@
+ $(hide) echo "#" >> $@
+ $(hide) echo "# ADDITIONAL TEST HARNESS PROPERTIES" >> $@
+ $(hide) echo "#" >> $@
+ $(hide) $(foreach line,$(ADDITIONAL_TEST_HARNESS_PROPERTIES), \
+ echo "$(line)" >> $@;)
+
+INTERNAL_TEST_HARNESS_RAMDISK_FILES := $(filter $(TARGET_TEST_HARNESS_RAMDISK_OUT)/%, \
+ $(INTERNAL_TEST_HARNESS_RAMDISK_ADB_DEBUG_PROP_TARGET) \
+ $(ALL_GENERATED_SOURCES) \
+ $(ALL_DEFAULT_INSTALLED_MODULES))
+
+# The order is important here. The test harness ramdisk staging directory has to
+# come last so that it can override the adb_debug.prop in the debug ramdisk
+# staging directory.
+INTERNAL_TEST_HARNESS_RAMDISK_SRC_DIRS := $(INTERNAL_DEBUG_RAMDISK_SRC_DIRS) $(TARGET_TEST_HARNESS_RAMDISK_OUT)
+INTERNAL_TEST_HARNESS_RAMDISK_SRC_DEPS := $(INSTALLED_FILES_FILE_DEBUG_RAMDISK) $(INTERNAL_TEST_HARNESS_RAMDISK_FILES)
+
+ifdef BUILDING_DEBUG_BOOT_IMAGE
+
# -----------------------------------------------------------------
# The test harness ramdisk, which is based off debug_ramdisk, plus a
# few additional test-harness-specific properties in adb_debug.prop.
INSTALLED_TEST_HARNESS_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk-test-harness.img
-# Appends a few test harness specific properties into the adb_debug.prop.
-TEST_HARNESS_PROP_TARGET := $(TARGET_TEST_HARNESS_RAMDISK_OUT)/adb_debug.prop
-ADDITIONAL_TEST_HARNESS_PROPERTIES := ro.audio.silent=1
-ADDITIONAL_TEST_HARNESS_PROPERTIES += ro.test_harness=1
-
-# $(1): a list of key=value pairs for additional property assignments
-# $(2): the target .prop file to append the properties from $(1)
-define append-test-harness-props
- echo "#" >> $(2); \
- echo "# ADDITIONAL TEST HARNESS_PROPERTIES" >> $(2); \
- echo "#" >> $(2);
- $(foreach line,$(1), echo "$(line)" >> $(2);)
-endef
-
-INTERNAL_TEST_HARNESS_RAMDISK_FILES := $(filter $(TARGET_TEST_HARNESS_RAMDISK_OUT)/%, \
- $(ALL_GENERATED_SOURCES) \
- $(ALL_DEFAULT_INSTALLED_MODULES))
-
-# The test harness ramdisk will rsync the files from the debug ramdisk, then appends some props.
-$(INSTALLED_TEST_HARNESS_RAMDISK_TARGET): $(INSTALLED_DEBUG_RAMDISK_TARGET)
-$(INSTALLED_TEST_HARNESS_RAMDISK_TARGET): $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DEP)
-$(INSTALLED_TEST_HARNESS_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_TEST_HARNESS_RAMDISK_FILES) | $(COMPRESSION_COMMAND_DEPS)
- $(call pretty,"Target test harness ramdisk: $@")
- rsync --chmod=u+w -a $(TARGET_DEBUG_RAMDISK_OUT)/ $(TARGET_TEST_HARNESS_RAMDISK_OUT)
- $(call append-test-harness-props,$(ADDITIONAL_TEST_HARNESS_PROPERTIES),$(TEST_HARNESS_PROP_TARGET))
- $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_TEST_HARNESS_RAMDISK_OUT) $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR) | $(COMPRESSION_COMMAND) > $@
+$(INSTALLED_TEST_HARNESS_RAMDISK_TARGET): $(INTERNAL_TEST_HARNESS_RAMDISK_SRC_DEPS)
+$(INSTALLED_TEST_HARNESS_RAMDISK_TARGET): $(MKBOOTFS) | $(COMPRESSION_COMMAND_DEPS)
+ @echo "Target test harness ramdisk: $@"
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@)
+ $(MKBOOTFS) -d $(TARGET_OUT) $(INTERNAL_TEST_HARNESS_RAMDISK_SRC_DIRS) | $(COMPRESSION_COMMAND) > $@
.PHONY: ramdisk_test_harness-nodeps
ramdisk_test_harness-nodeps: $(MKBOOTFS) | $(COMPRESSION_COMMAND_DEPS)
- echo "make $@: ignoring dependencies"
- rsync --chmod=u+w -a $(TARGET_DEBUG_RAMDISK_OUT)/ $(TARGET_TEST_HARNESS_RAMDISK_OUT)
- $(call append-test-harness-props,$(ADDITIONAL_TEST_HARNESS_PROPERTIES),$(TEST_HARNESS_PROP_TARGET))
- mkdir -p $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR)
- $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_TEST_HARNESS_RAMDISK_OUT) $(INTERNAL_DEBUG_RAMDISK_ADDITIONAL_DIR) | $(COMPRESSION_COMMAND) > $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)
+ @echo "make $@: ignoring dependencies"
+ $(hide) rm -f $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)
+ $(hide) mkdir -p $(dir $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)) $(INTERNAL_TEST_HARNESS_RAMDISK_SRC_DIRS)
+ $(MKBOOTFS) -d $(TARGET_OUT) $(INTERNAL_TEST_HARNESS_RAMDISK_SRC_DIRS) | $(COMPRESSION_COMMAND) > $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)
# -----------------------------------------------------------------
# the boot-test-harness.img, which is the kernel plus ramdisk-test-harness.img
#
# Note: it's intentional to skip signing for boot-test-harness.img, because it
# can only be used if the device is unlocked with verification error.
-ifdef BUILDING_DEBUG_BOOT_IMAGE
-
ifneq ($(strip $(BOARD_KERNEL_BINARIES)),)
INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET := $(foreach k,$(subst kernel,boot-test-harness,$(BOARD_KERNEL_BINARIES)), \
$(PRODUCT_OUT)/$(k).img)
@@ -2538,6 +2607,7 @@
endif
# Replace ramdisk-debug.img in $(MKBOOTIMG) ARGS with ramdisk-test-harness.img to build boot-test-harness.img
+$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)
INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS := $(subst $(INSTALLED_DEBUG_RAMDISK_TARGET),$(INSTALLED_TEST_HARNESS_RAMDISK_TARGET),$(INTERNAL_DEBUG_BOOTIMAGE_ARGS))
# If boot.img is chained but boot-test-harness.img is not signed, libavb in bootloader
@@ -2557,8 +2627,7 @@
endef
# Build the new boot-test-harness.img, based on boot-debug.img and ramdisk-test-harness.img.
-$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET) \
-$(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
$(call pretty,"Target boot test harness image: $@")
$(call build-boot-test-harness-target,$@)
@@ -2576,19 +2645,17 @@
INTERNAL_VENDOR_TEST_HARNESS_RAMDISK_TARGET := $(call intermediates-dir-for,PACKAGING,vendor_boot-test-harness)/vendor_ramdisk-test-harness.cpio$(RAMDISK_EXT)
-# Exclude recovery files in the default vendor ramdisk if including a standalone
-# recovery ramdisk in vendor_boot.
-ifeq (true,$(BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT))
-ifneq (true,$(BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT))
-$(INTERNAL_VENDOR_TEST_HARNESS_RAMDISK_TARGET): $(INTERNAL_RECOVERY_RAMDISK_FILES_TIMESTAMP)
-$(INTERNAL_VENDOR_TEST_HARNESS_RAMDISK_TARGET): PRIVATE_ADDITIONAL_DIR := $(TARGET_RECOVERY_ROOT_OUT)
-endif
-endif
+# The order is important here. The test harness ramdisk staging directory has to
+# come last so that it can override the adb_debug.prop in the debug ramdisk
+# staging directory.
+INTERNAL_TEST_HARNESS_VENDOR_RAMDISK_SRC_DIRS := $(INTERNAL_DEBUG_VENDOR_RAMDISK_SRC_DIRS) $(TARGET_TEST_HARNESS_RAMDISK_OUT)
+INTERNAL_TEST_HARNESS_VENDOR_RAMDISK_SRC_DEPS := $(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK) $(INTERNAL_TEST_HARNESS_RAMDISK_FILES)
-# The vendor test harness ramdisk combines vendor ramdisk and test harness ramdisk.
-$(INTERNAL_VENDOR_TEST_HARNESS_RAMDISK_TARGET): $(INTERNAL_VENDOR_RAMDISK_TARGET) $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)
+$(INTERNAL_VENDOR_TEST_HARNESS_RAMDISK_TARGET): $(INTERNAL_TEST_HARNESS_VENDOR_RAMDISK_SRC_DEPS)
$(INTERNAL_VENDOR_TEST_HARNESS_RAMDISK_TARGET): $(MKBOOTFS) | $(COMPRESSION_COMMAND_DEPS)
- $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_VENDOR_RAMDISK_OUT) $(TARGET_TEST_HARNESS_RAMDISK_OUT) $(PRIVATE_ADDITIONAL_DIR) | $(COMPRESSION_COMMAND) > $@
+ $(hide) rm -f $@
+ $(hide) mkdir -p $(dir $@)
+ $(MKBOOTFS) -d $(TARGET_OUT) $(INTERNAL_TEST_HARNESS_VENDOR_RAMDISK_SRC_DIRS) | $(COMPRESSION_COMMAND) > $@
INSTALLED_VENDOR_TEST_HARNESS_RAMDISK_TARGET := $(PRODUCT_OUT)/vendor_ramdisk-test-harness.img
$(INSTALLED_VENDOR_TEST_HARNESS_RAMDISK_TARGET): $(INTERNAL_VENDOR_TEST_HARNESS_RAMDISK_TARGET)
@@ -2703,7 +2770,7 @@
installed-file-list: $(INSTALLED_FILES_FILE)
ifeq ($(HOST_OS),linux)
-$(call dist-for-goals, sdk win_sdk sdk_addon, $(INSTALLED_FILES_FILE))
+$(call dist-for-goals, sdk sdk_addon, $(INSTALLED_FILES_FILE))
endif
systemimage_intermediates := \
@@ -2727,9 +2794,16 @@
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,$@)
+$(call declare-1p-container,$(BUILT_SYSTEMIMAGE),system/extras)
+$(call declare-container-license-deps,$(BUILT_SYSTEMIMAGE),$(FULL_SYSTEMIMAGE_DEPS),$(PRODUCT_OUT)/:)
+
INSTALLED_SYSTEMIMAGE_TARGET := $(PRODUCT_OUT)/system.img
SYSTEMIMAGE_SOURCE_DIR := $(TARGET_OUT)
@@ -2771,8 +2845,14 @@
$(copy-file-to-target)
$(hide) $(call assert-max-image-size,$@,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
+$(call declare-1p-container,$(INSTALLED_SYSTEMIMAGE_TARGET),)
+$(call declare-container-license-deps,$(INSTALLED_SYSTEMIMAGE_TARGET),$(BUILT_SYSTEMIMAGE),$(BUILT_SYSTEMIMAGE):/)
+
systemimage: $(INSTALLED_SYSTEMIMAGE_TARGET)
+.PHONY: systemlicense
+systemlicense: $(call license-metadata-dir)/$(INSTALLED_SYSTEMIMAGE_TARGET).meta_lic reportmissinglicenses
+
.PHONY: systemimage-nodeps snod
systemimage-nodeps snod: $(filter-out systemimage-nodeps snod,$(MAKECMDGOALS)) \
| $(INTERNAL_USERIMAGES_DEPS)
@@ -3380,7 +3460,7 @@
cp $(BUILT_PVMFWIMAGE_TARGET) $@
$(AVBTOOL) add_hash_footer \
--image $@ \
- --partition_size $(BOARD_PVMFWIMG_PARTITION_SIZE) \
+ --partition_size $(BOARD_PVMFWIMAGE_PARTITION_SIZE) \
--partition_name pvmfw $(INTERNAL_AVB_PVMFW_SIGNING_ARGS) \
$(BOARD_AVB_PVMFW_ADD_HASH_FOOTER_ARGS)
else
@@ -4302,6 +4382,7 @@
shflags \
sign_apex \
sign_target_files_apks \
+ sign_virt_apex \
signapk \
simg2img \
sload_f2fs \
@@ -4565,7 +4646,7 @@
ifeq ($(BOARD_USES_PVMFWIMAGE),true)
$(hide) echo "has_pvmfw=true" >> $@
ifeq ($(BOARD_AVB_ENABLE),true)
- $(hide) echo "pvmfw_size=$(BOARD_PVMFWIMG_PARTITION_SIZE)" >> $@
+ $(hide) echo "pvmfw_size=$(BOARD_PVMFWIMAGE_PARTITION_SIZE)" >> $@
$(hide) echo "avb_pvmfw_add_hash_footer_args=$(BOARD_AVB_PVMFW_ADD_HASH_FOOTER_ARGS)" >> $@
ifdef BOARD_AVB_PVMFW_KEY_PATH
$(hide) echo "avb_pvmfw_key_path=$(BOARD_AVB_PVMFW_KEY_PATH)" >> $@
@@ -5185,7 +5266,10 @@
ifdef BOARD_PREBUILT_PVMFWIMAGE
$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
$(hide) cp $(INSTALLED_PVMFWIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
-endif # BOARD_PREBUILT_PVMFWIMAGE
+else ifeq ($(BUILDING_PVMFW_IMAGE),true)
+ $(hide) mkdir -p $(zip_root)/IMAGES
+ $(hide) cp $(INSTALLED_PVMFWIMAGE_TARGET) $(zip_root)/IMAGES/
+endif
ifdef BOARD_PREBUILT_BOOTLOADER
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_BOOTLOADER_MODULE) $(zip_root)/IMAGES/
@@ -5374,6 +5458,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)
@@ -5836,6 +5922,8 @@
# -----------------------------------------------------------------
# The SDK
+ifneq ($(filter sdk,$(MAKECMDGOALS)),)
+
# The SDK includes host-specific components, so it belongs under HOST_OUT.
sdk_dir := $(HOST_OUT)/sdk/$(TARGET_PRODUCT)
@@ -5845,15 +5933,11 @@
# darwin-x86 --> android-sdk_12345_mac-x86
# windows-x86 --> android-sdk_12345_windows
#
+ifneq ($(HOST_OS),linux)
+ $(error Building the monolithic SDK is only supported on Linux)
+endif
sdk_name := android-sdk_$(FILE_NAME_TAG)
-ifeq ($(HOST_OS),darwin)
- INTERNAL_SDK_HOST_OS_NAME := mac
-else
- INTERNAL_SDK_HOST_OS_NAME := $(HOST_OS)
-endif
-ifneq ($(HOST_OS),windows)
- INTERNAL_SDK_HOST_OS_NAME := $(INTERNAL_SDK_HOST_OS_NAME)-$(SDK_HOST_ARCH)
-endif
+INTERNAL_SDK_HOST_OS_NAME := linux-$(SDK_HOST_ARCH)
sdk_name := $(sdk_name)_$(INTERNAL_SDK_HOST_OS_NAME)
sdk_dep_file := $(sdk_dir)/sdk_deps.mk
@@ -5873,9 +5957,7 @@
atree_dir := development/build
-sdk_atree_files := \
- $(atree_dir)/sdk.exclude.atree \
- $(atree_dir)/sdk-$(HOST_OS)-$(SDK_HOST_ARCH).atree
+sdk_atree_files := $(atree_dir)/sdk.exclude.atree
# development/build/sdk-android-<abi>.atree is used to differentiate
# between architecture models (e.g. ARMv5TE versus ARMv7) when copying
@@ -5957,22 +6039,16 @@
-o $(PRIVATE_DIR) && \
cp -f $(target_notice_file_txt) \
$(PRIVATE_DIR)/system-images/android-$(PLATFORM_VERSION)/$(TARGET_CPU_ABI)/NOTICE.txt && \
- cp -f $(tools_notice_file_txt) $(PRIVATE_DIR)/platform-tools/NOTICE.txt && \
HOST_OUT_EXECUTABLES=$(HOST_OUT_EXECUTABLES) HOST_OS=$(HOST_OS) \
development/build/tools/sdk_clean.sh $(PRIVATE_DIR) && \
chmod -R ug+rwX $(PRIVATE_DIR) && \
cd $(dir $@) && zip -rqX $(notdir $@) $(PRIVATE_NAME) \
) || ( rm -rf $(PRIVATE_DIR) $@ && exit 44 )
-
-# Is a Windows SDK requested? If so, we need some definitions from here
-# in order to find the Linux SDK used to create the Windows one.
-MAIN_SDK_NAME := $(sdk_name)
MAIN_SDK_DIR := $(sdk_dir)
MAIN_SDK_ZIP := $(INTERNAL_SDK_TARGET)
-ifneq ($(filter win_sdk winsdk-tools,$(MAKECMDGOALS)),)
-include $(TOPDIR)development/build/tools/windows_sdk.mk
-endif
+
+endif # sdk in MAKECMDGOALS
# -----------------------------------------------------------------
# Findbugs
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index c55b2f3..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 (,$(filter 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,
@@ -54,7 +59,7 @@
# Always build from source for the module targets. This ought to be covered by
# the TARGET_BUILD_APPS check above, but there are test builds that don't set it.
SOONG_CONFIG_art_module_source_build := true
-else ifdef MODULE_BUILD_FROM_SOURCE
+else ifeq (true,$(MODULE_BUILD_FROM_SOURCE))
# Build from source if other Mainline modules are.
SOONG_CONFIG_art_module_source_build := true
else ifneq (,$(filter true,$(NATIVE_COVERAGE) $(CLANG_COVERAGE)))
@@ -73,7 +78,7 @@
else ifneq (,$(filter dex2oatds dex2oats,$(PRODUCT_HOST_PACKAGES)))
# Some products depend on host tools that aren't available as prebuilts.
SOONG_CONFIG_art_module_source_build := true
-else ifeq (,$(filter com.google.android.art,$(PRODUCT_PACKAGES)))
+else ifeq (,$(findstring com.google.android.art,$(PRODUCT_PACKAGES)))
# TODO(b/192006406): There is currently no good way to control which prebuilt
# APEX (com.google.android.art or com.android.art) gets picked for deapexing
# to provide dex jars for hiddenapi and dexpreopting. Instead the AOSP APEX is
@@ -91,6 +96,6 @@
$(call add_soong_config_var_value,ANDROID,library_linking_strategy,prefer_static)
endif
-ifdef MODULE_BUILD_FROM_SOURCE
+ifeq (true,$(MODULE_BUILD_FROM_SOURCE))
$(call add_soong_config_var_value,ANDROID,module_build_from_source,true)
endif
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 1b7a279..134cb8f 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -373,7 +373,13 @@
LOCAL_BUILT_MODULE := $(intermediates)/$(my_built_module_stem)
-ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
+ifneq (,$(LOCAL_SOONG_INSTALLED_MODULE))
+ ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ $(call pretty-error, LOCAL_SOONG_INSTALLED_MODULE can only be used from $(SOONG_ANDROID_MK))
+ endif
+ # Use the install path requested by Soong.
+ LOCAL_INSTALLED_MODULE := $(LOCAL_SOONG_INSTALLED_MODULE)
+else ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
# Apk and its attachments reside in its own subdir.
ifeq ($(LOCAL_MODULE_CLASS),APPS)
# framework-res.apk doesn't like the additional layer.
@@ -507,91 +513,98 @@
## Module installation rule
###########################################################
-my_init_rc_installed :=
-my_init_rc_path :=
-my_init_rc_pairs :=
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 (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)
+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))
+ $(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
+ endif
$(PRIVATE_POST_INSTALL_CMD)
-endif
-ifndef LOCAL_IS_HOST_MODULE
-# Rule to install the module's companion init.rc.
-ifneq ($(strip $(LOCAL_FULL_INIT_RC)),)
-my_init_rc := $(LOCAL_FULL_INIT_RC)
-else
-my_init_rc := $(foreach rc,$(LOCAL_INIT_RC_$(my_32_64_bit_suffix)) $(LOCAL_INIT_RC),$(LOCAL_PATH)/$(rc))
-endif
-ifneq ($(strip $(my_init_rc)),)
-# Make doesn't support recovery as an output partition, but some Soong modules installed in recovery
-# have init.rc files that need to be installed alongside them. Manually handle the case where the
-# output file is in the recovery partition.
-my_init_rc_path := $(if $(filter $(TARGET_RECOVERY_ROOT_OUT)/%,$(my_module_path)),$(TARGET_RECOVERY_ROOT_OUT)/system/etc,$(TARGET_OUT$(partition_tag)_ETC))
-my_init_rc_pairs := $(foreach rc,$(my_init_rc),$(rc):$(my_init_rc_path)/init/$(notdir $(rc)))
-my_init_rc_installed := $(foreach rc,$(my_init_rc_pairs),$(call word-colon,2,$(rc)))
+ # 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)))
+ $(foreach symlink,$(my_installed_symlinks),\
+ $(call symlink-file,$(LOCAL_INSTALLED_MODULE),$(my_installed_module_stem),$(symlink))\
+ $(call declare-0p-target,$(symlink)))
-# Make sure we only set up the copy rules once, even if another arch variant
-# shares a common LOCAL_INIT_RC.
-my_init_rc_new_pairs := $(filter-out $(ALL_INIT_RC_INSTALLED_PAIRS),$(my_init_rc_pairs))
-my_init_rc_new_installed := $(call copy-many-init-script-files-checked,$(my_init_rc_new_pairs))
-ALL_INIT_RC_INSTALLED_PAIRS += $(my_init_rc_new_pairs)
-
-$(my_all_targets) : $(my_init_rc_installed)
-endif # my_init_rc
-endif # !LOCAL_IS_HOST_MODULE
-
-# 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)))
-$(foreach symlink,$(my_installed_symlinks),\
- $(call symlink-file,$(LOCAL_INSTALLED_MODULE),$(my_installed_module_stem),$(symlink)))
-
-$(my_all_targets) : | $(my_installed_symlinks)
+ $(my_all_targets) : | $(my_installed_symlinks)
endif # !LOCAL_UNINSTALLABLE_MODULE
###########################################################
-## VINTF manifest fragment goals
+## VINTF manifest fragment and init.rc goals
###########################################################
my_vintf_installed:=
+my_vintf_path:=
my_vintf_pairs:=
+my_init_rc_installed :=
+my_init_rc_path :=
+my_init_rc_pairs :=
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
-ifndef LOCAL_IS_HOST_MODULE
-ifneq ($(strip $(LOCAL_FULL_VINTF_FRAGMENTS)),)
-my_vintf_fragments := $(LOCAL_FULL_VINTF_FRAGMENTS)
-else
-my_vintf_fragments := $(foreach xml,$(LOCAL_VINTF_FRAGMENTS),$(LOCAL_PATH)/$(xml))
-endif
-ifneq ($(strip $(my_vintf_fragments)),)
+ ifndef LOCAL_IS_HOST_MODULE
+ # Rule to install the module's companion vintf fragments.
+ ifneq ($(strip $(LOCAL_FULL_VINTF_FRAGMENTS)),)
+ my_vintf_fragments := $(LOCAL_FULL_VINTF_FRAGMENTS)
+ else
+ my_vintf_fragments := $(foreach xml,$(LOCAL_VINTF_FRAGMENTS),$(LOCAL_PATH)/$(xml))
+ endif
+ ifneq ($(strip $(my_vintf_fragments)),)
+ # Make doesn't support recovery as an output partition, but some Soong modules installed in recovery
+ # have init.rc files that need to be installed alongside them. Manually handle the case where the
+ # output file is in the recovery partition.
+ my_vintf_path := $(if $(filter $(TARGET_RECOVERY_ROOT_OUT)/%,$(my_module_path)),$(TARGET_RECOVERY_ROOT_OUT)/system/etc,$(TARGET_OUT$(partition_tag)_ETC))
+ my_vintf_pairs := $(foreach xml,$(my_vintf_fragments),$(xml):$(my_vintf_path)/vintf/manifest/$(notdir $(xml)))
+ my_vintf_installed := $(foreach xml,$(my_vintf_pairs),$(call word-colon,2,$(xml)))
-my_vintf_pairs := $(foreach xml,$(my_vintf_fragments),$(xml):$(TARGET_OUT$(partition_tag)_ETC)/vintf/manifest/$(notdir $(xml)))
-my_vintf_installed := $(foreach xml,$(my_vintf_pairs),$(call word-colon,2,$(xml)))
+ # Only set up copy rules once, even if another arch variant shares it
+ my_vintf_new_pairs := $(filter-out $(ALL_VINTF_MANIFEST_FRAGMENTS_LIST),$(my_vintf_pairs))
+ my_vintf_new_installed := $(call copy-many-vintf-manifest-files-checked,$(my_vintf_new_pairs))
-# Only set up copy rules once, even if another arch variant shares it
-my_vintf_new_pairs := $(filter-out $(ALL_VINTF_MANIFEST_FRAGMENTS_LIST),$(my_vintf_pairs))
-my_vintf_new_installed := $(call copy-many-vintf-manifest-files-checked,$(my_vintf_new_pairs))
+ ALL_VINTF_MANIFEST_FRAGMENTS_LIST += $(my_vintf_new_pairs)
-ALL_VINTF_MANIFEST_FRAGMENTS_LIST += $(my_vintf_new_pairs)
+ $(my_all_targets) : $(my_vintf_new_installed)
+ endif # my_vintf_fragments
-$(my_all_targets) : $(my_vintf_new_installed)
-endif # LOCAL_VINTF_FRAGMENTS
-endif # !LOCAL_IS_HOST_MODULE
+ # Rule to install the module's companion init.rc.
+ ifneq ($(strip $(LOCAL_FULL_INIT_RC)),)
+ my_init_rc := $(LOCAL_FULL_INIT_RC)
+ else
+ my_init_rc := $(foreach rc,$(LOCAL_INIT_RC_$(my_32_64_bit_suffix)) $(LOCAL_INIT_RC),$(LOCAL_PATH)/$(rc))
+ endif
+ ifneq ($(strip $(my_init_rc)),)
+ # Make doesn't support recovery as an output partition, but some Soong modules installed in recovery
+ # have init.rc files that need to be installed alongside them. Manually handle the case where the
+ # output file is in the recovery partition.
+ my_init_rc_path := $(if $(filter $(TARGET_RECOVERY_ROOT_OUT)/%,$(my_module_path)),$(TARGET_RECOVERY_ROOT_OUT)/system/etc,$(TARGET_OUT$(partition_tag)_ETC))
+ my_init_rc_pairs := $(foreach rc,$(my_init_rc),$(rc):$(my_init_rc_path)/init/$(notdir $(rc)))
+ my_init_rc_installed := $(foreach rc,$(my_init_rc_pairs),$(call word-colon,2,$(rc)))
+
+ # Make sure we only set up the copy rules once, even if another arch variant
+ # shares a common LOCAL_INIT_RC.
+ my_init_rc_new_pairs := $(filter-out $(ALL_INIT_RC_INSTALLED_PAIRS),$(my_init_rc_pairs))
+ my_init_rc_new_installed := $(call copy-many-init-script-files-checked,$(my_init_rc_new_pairs))
+
+ ALL_INIT_RC_INSTALLED_PAIRS += $(my_init_rc_new_pairs)
+
+ $(my_all_targets) : $(my_init_rc_installed)
+ endif # my_init_rc
+
+ endif # !LOCAL_IS_HOST_MODULE
endif # !LOCAL_UNINSTALLABLE_MODULE
###########################################################
@@ -718,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) := ))
@@ -902,12 +916,38 @@
ALL_MODULES.$(my_register_name).TARGET_BUILT := \
$(ALL_MODULES.$(my_register_name).TARGET_BUILT) $(LOCAL_BUILT_MODULE)
endif
-ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
-ALL_MODULES.$(my_register_name).INSTALLED := \
+ifneq (,$(LOCAL_SOONG_INSTALLED_MODULE))
+ # Store the list of paths to installed locations of files provided by this
+ # module. Used as dependencies of the image packaging rules when the module
+ # is installed by the current product.
+ ALL_MODULES.$(my_register_name).INSTALLED := \
+ $(strip $(ALL_MODULES.$(my_register_name).INSTALLED) \
+ $(foreach f, $(LOCAL_SOONG_INSTALL_PAIRS),\
+ $(word 2,$(subst :,$(space),$(f)))) \
+ $(LOCAL_SOONG_INSTALL_SYMLINKS) \
+ $(my_init_rc_installed) \
+ $(my_installed_test_data) \
+ $(my_vintf_installed))
+ # Store the list of colon-separated pairs of the built and installed locations
+ # 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) \
+ $(patsubst $(LOCAL_PREBUILT_MODULE_FILE):%,$(LOCAL_BUILT_MODULE):%,$(LOCAL_SOONG_INSTALL_PAIRS)) \
+ $(my_init_rc_pairs) \
+ $(my_test_data_pairs) \
+ $(my_vintf_pairs))
+else ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
+ ALL_MODULES.$(my_register_name).INSTALLED := \
$(strip $(ALL_MODULES.$(my_register_name).INSTALLED) \
$(LOCAL_INSTALLED_MODULE) $(my_init_rc_installed) $(my_installed_symlinks) \
$(my_installed_test_data) $(my_vintf_installed))
-ALL_MODULES.$(my_register_name).BUILT_INSTALLED := \
+ ALL_MODULES.$(my_register_name).BUILT_INSTALLED := \
$(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED) \
$(LOCAL_BUILT_MODULE):$(LOCAL_INSTALLED_MODULE) \
$(my_init_rc_pairs) $(my_test_data_pairs) $(my_vintf_pairs))
@@ -935,6 +975,12 @@
my_required_modules += $(LOCAL_REQUIRED_MODULES_$($(my_prefix)OS))
endif
+ALL_MODULES.$(my_register_name).SHARED_LIBS := \
+ $(ALL_MODULES.$(my_register_name).SHARED_LIBS) $(LOCAL_SHARED_LIBRARIES)
+
+ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS := \
+ $(ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS) $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+
##########################################################################
## When compiling against the VNDK, add the .vendor or .product suffix to
## required modules.
@@ -1026,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) \
@@ -1043,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 816b176..b3e6957 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -84,6 +84,7 @@
_board_strip_readonly_list += BOARD_VENDOR_DLKMIMAGE_FILE_SYSTEM_TYPE
_board_strip_readonly_list += BOARD_ODM_DLKMIMAGE_PARTITION_SIZE
_board_strip_readonly_list += BOARD_ODM_DLKMIMAGE_FILE_SYSTEM_TYPE
+_board_strip_readonly_list += BOARD_PVMFWIMAGE_PARTITION_SIZE
# Logical partitions related variables.
_board_strip_readonly_list += BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE
@@ -184,19 +185,44 @@
.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_"),\
+$(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 $(OUT_DIR)/soong/rbcrun \
+ RBC_OUT="make,global" \
+ $(OUT_DIR)/rbc/boardlauncher.rbc \
+ >$(OUT_DIR)/rbc/rbc_board_config_results.mk)
+ 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)))
@@ -410,12 +436,6 @@
endif
.KATI_READONLY := BUILDING_BOOT_IMAGE
-DEBUG_RAMDISK_BOOT_IMAGE_NAME := boot-debug
-ifneq ($(PRODUCT_DEBUG_RAMDISK_BOOT_IMAGE_NAME),)
- DEBUG_RAMDISK_BOOT_IMAGE_NAME := $(PRODUCT_DEBUG_RAMDISK_BOOT_IMAGE_NAME)
-endif
-.KATI_READONLY := DEBUG_RAMDISK_BOOT_IMAGE_NAME
-
# Are we building a recovery image
BUILDING_RECOVERY_IMAGE :=
ifeq ($(PRODUCT_BUILD_RECOVERY_IMAGE),)
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index a67cca6..15db9a8 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -187,6 +187,7 @@
LOCAL_MODULE_TAGS:=
LOCAL_MODULE_TARGET_ARCH:=
LOCAL_MODULE_TARGET_ARCH_WARN:=
+LOCAL_MODULE_TYPE:=
LOCAL_MODULE_UNSUPPORTED_HOST_ARCH:=
LOCAL_MODULE_UNSUPPORTED_HOST_ARCH_WARN:=
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH:=
@@ -283,6 +284,9 @@
LOCAL_SOONG_DEXPREOPT_CONFIG :=
LOCAL_SOONG_EXPORT_PROGUARD_FLAGS :=
LOCAL_SOONG_HEADER_JAR :=
+LOCAL_SOONG_INSTALL_PAIRS :=
+LOCAL_SOONG_INSTALL_SYMLINKS :=
+LOCAL_SOONG_INSTALLED_MODULE :=
LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=
LOCAL_SOONG_LINK_TYPE :=
LOCAL_SOONG_LINT_REPORTS :=
diff --git a/core/config.mk b/core/config.mk
index 9165925..7c93610 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -252,6 +252,10 @@
# Initialize SOONG_CONFIG_NAMESPACES so that it isn't recursive.
SOONG_CONFIG_NAMESPACES :=
+# TODO(asmundak): remove add_soong_config_namespace, add_soong_config_var,
+# and add_soong_config_var_value once all their usages are replaced with
+# soong_config_set/soong_config_append.
+
# The add_soong_config_namespace function adds a namespace and initializes it
# to be empty.
# $1 is the namespace.
@@ -282,6 +286,40 @@
$(call add_soong_config_var,$1,$2)
endef
+# Soong config namespace variables manipulation.
+#
+# internal utility to define a namespace and a variable in it.
+define soong_config_define_internal
+$(if $(filter $1,$(SOONG_CONFIG_NAMESPACES)),,$(eval SOONG_CONFIG_NAMESPACES:=$(SOONG_CONFIG_NAMESPACES) $1)) \
+$(if $(filter $2,$(SOONG_CONFIG_$(strip $1))),,$(eval SOONG_CONFIG_$(strip $1):=$(SOONG_CONFIG_$(strip $1)) $2))
+endef
+
+# soong_config_set defines the variable in the given Soong config namespace
+# and sets its value. If the namespace does not exist, it will be defined.
+# $1 is the namespace. $2 is the variable name. $3 is the variable value.
+# Ex: $(call soong_config_set,acme,COOL_FEATURE,true)
+define soong_config_set
+$(call soong_config_define_internal,$1,$2) \
+$(eval SOONG_CONFIG_$(strip $1)_$(strip $2):=$3)
+endef
+
+# soong_config_append appends to the value of the variable in the given Soong
+# 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
+$(call soong_config_define_internal,$1,$2) \
+$(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
@@ -509,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.
@@ -723,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)
@@ -1182,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/definitions.mk b/core/definitions.mk
index c7172ca..38b572b 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -37,6 +37,10 @@
# sub-variables.
ALL_MODULES:=
+# The relative paths of the non-module targets in the system.
+ALL_NON_MODULES:=
+NON_MODULES_WITHOUT_LICENSE_METADATA:=
+
# Full paths to targets that should be added to the "make droid"
# set of installed targets.
ALL_DEFAULT_INSTALLED_MODULES:=
@@ -539,7 +543,7 @@
$(eval _all_module_refs := \
$(sort \
$(foreach m,$(sort $(ALL_MODULES)), \
- $(ALL_MODULES.$(m).NOTICE_DEPS) \
+ $(call word-colon,1,$(ALL_MODULES.$(m).NOTICE_DEPS)) \
) \
) \
) \
@@ -557,7 +561,7 @@
$(eval ALL_MODULES.$(m).NOTICE_DEPS := \
$(sort \
$(foreach d,$(sort $(ALL_MODULES.$(m).NOTICE_DEPS)), \
- $(_lookup.$(d)) \
+ $(foreach n,$(_lookup.$(call word-colon,1,$(d))),$(n):$(call wordlist-colon,2,9999,$(d))) \
) \
) \
) \
@@ -573,35 +577,56 @@
endef
###########################################################
-## License metadata build rule for my_register_name $1
+## License metadata build rule for my_register_name $(1)
###########################################################
define license-metadata-rule
$(strip $(eval _dir := $(call license-metadata-dir)))
-$(strip $(eval _deps := $(sort $(filter-out $(_dir)/$(1).meta_lic,$(foreach d,$(ALL_MODULES.$(1).NOTICE_DEPS), $(_dir)/$(d).meta_lic)))))
+$(strip $(eval _srcs := $(strip $(foreach d,$(ALL_MODULES.$(1).NOTICE_DEPS),$(if $(strip $(ALL_MODULES.$(call word-colon,1,$(d)).INSTALLED)), $(ALL_MODULES.$(call word-colon,1,$(d)).INSTALLED),$(if $(strip $(ALL_MODULES.$(call word-colon,1,$(d)).BUILT)), $(ALL_MODULES.$(call word-colon,1,$(d)).BUILT), $(call word-colon,1,$d)))))))
+$(strip $(eval _deps := $(sort $(filter-out $(_dir)/$(1).meta_lic%,$(foreach d,$(ALL_MODULES.$(1).NOTICE_DEPS), $(_dir)/$(call word-colon,1,$(d)).meta_lic:$(call wordlist-colon,2,9999,$d))))))
$(strip $(eval _notices := $(sort $(ALL_MODULES.$(1).NOTICES))))
-$(strip $(eval _tgts := $(sort $(ALL_MODULES.$(1).BUILT) $(ALL_MODULES.$(1).INSTALLED))))
-$(foreach b,$(_tgts),
-$(_dir)/$(b).meta_module ::
- mkdir -p $$(dir $$@)
- echo $(_dir)/$(1).meta_lic >> $$@
- sort -u $$@ -o $$@
+$(strip $(eval _tgts := $(sort $(ALL_MODULES.$(1).BUILT))))
+$(strip $(eval _inst := $(sort $(ALL_MODULES.$(1).INSTALLED))))
+$(strip $(eval _path := $(sort $(ALL_MODULES.$(1).PATH))))
+$(strip $(eval _map := $(strip $(foreach _m,$(sort $(ALL_MODULES.$(1).LICENSE_INSTALL_MAP)), \
+ $(eval _s := $(call word-colon,1,$(_m))) \
+ $(eval _d := $(call word-colon,2,$(_m))) \
+ $(eval _ns := $(if $(strip $(ALL_MODULES.$(_s).INSTALLED)),$(ALL_MODULES.$(_s).INSTALLED),$(if $(strip $(ALL_MODULES.$(_s).BUILT)),$(ALL_MODULES.$(_s).BUILT),$(_s)))) \
+ $(foreach ns,$(_ns),$(ns):$(_d) ) \
+))))
-)
$(_dir)/$(1).meta_lic: PRIVATE_KINDS := $(sort $(ALL_MODULES.$(1).LICENSE_KINDS))
$(_dir)/$(1).meta_lic: PRIVATE_CONDITIONS := $(sort $(ALL_MODULES.$(1).LICENSE_CONDITIONS))
$(_dir)/$(1).meta_lic: PRIVATE_NOTICES := $(_notices)
$(_dir)/$(1).meta_lic: PRIVATE_NOTICE_DEPS := $(_deps)
+$(_dir)/$(1).meta_lic: PRIVATE_SOURCES := $(_srcs)
$(_dir)/$(1).meta_lic: PRIVATE_TARGETS := $(_tgts)
+$(_dir)/$(1).meta_lic: PRIVATE_INSTALLED := $(_inst)
+$(_dir)/$(1).meta_lic: PRIVATE_PATH := $(_path)
$(_dir)/$(1).meta_lic: PRIVATE_IS_CONTAINER := $(ALL_MODULES.$(1).IS_CONTAINER)
$(_dir)/$(1).meta_lic: PRIVATE_PACKAGE_NAME := $(strip $(ALL_MODULES.$(1).LICENSE_PACKAGE_NAME))
-$(_dir)/$(1).meta_lic: PRIVATE_INSTALL_MAP := $(sort $(ALL_MODULES.$(1).LICENSE_INSTALL_MAP))
-$(_dir)/$(1).meta_lic : $(_deps) $(_notices) $(foreach b,$(_tgts), $(_dir)/$(b).meta_module) build/make/tools/build-license-metadata.sh
+$(_dir)/$(1).meta_lic: PRIVATE_INSTALL_MAP := $(_map)
+$(_dir)/$(1).meta_lic: PRIVATE_MODULE_TYPE := $(ALL_MODULES.$(1).MODULE_TYPE)
+$(_dir)/$(1).meta_lic: PRIVATE_MODULE_CLASS := $(ALL_MODULES.$(1).MODULE_CLASS)
+$(_dir)/$(1).meta_lic: PRIVATE_INSTALL_MAP := $(_map)
+$(_dir)/$(1).meta_lic: $(BUILD_LICENSE_METADATA)
+$(_dir)/$(1).meta_lic : $(foreach d,$(_deps),$(call word-colon,1,$(d))) $(foreach n,$(_notices),$(call word-colon,1,$(n)) )
rm -f $$@
mkdir -p $$(dir $$@)
- build/make/tools/build-license-metadata.sh -k $$(PRIVATE_KINDS) -c $$(PRIVATE_CONDITIONS) -n $$(PRIVATE_NOTICES) -d $$(PRIVATE_NOTICE_DEPS) -m $$(PRIVATE_INSTALL_MAP) -t $$(PRIVATE_TARGETS) $$(if $$(PRIVATE_IS_CONTAINER),-is_container) -p '$$(PRIVATE_PACKAGE_NAME)' -o $$@
-
-.PHONY: $(1).meta_lic
-$(1).meta_lic : $(_dir)/$(1).meta_lic
+ $(BUILD_LICENSE_METADATA) \
+ $$(addprefix -mt ,$$(PRIVATE_MODULE_TYPE)) \
+ $$(addprefix -mc ,$$(PRIVATE_MODULE_CLASS)) \
+ $$(addprefix -k ,$$(PRIVATE_KINDS)) \
+ $$(addprefix -c ,$$(PRIVATE_CONDITIONS)) \
+ $$(addprefix -n ,$$(PRIVATE_NOTICES)) \
+ $$(addprefix -d ,$$(PRIVATE_NOTICE_DEPS)) \
+ $$(addprefix -s ,$$(PRIVATE_SOURCES)) \
+ $$(addprefix -m ,$$(PRIVATE_INSTALL_MAP)) \
+ $$(addprefix -t ,$$(PRIVATE_TARGETS)) \
+ $$(addprefix -i ,$$(PRIVATE_INSTALLED)) \
+ $$(if $$(PRIVATE_IS_CONTAINER),-is_container) \
+ -p '$$(PRIVATE_PACKAGE_NAME)' \
+ $$(addprefix -r ,$$(PRIVATE_PATH)) \
+ -o $$@
$(strip $(eval _mifs := $(sort $(ALL_MODULES.$(1).MODULE_INSTALLED_FILENAMES))))
$(strip $(eval _infs := $(sort $(ALL_MODULES.$(1).INSTALLED_NOTICE_FILE))))
@@ -613,9 +638,9 @@
$(inf) : $(_dir)/$(1).meta_lic
$(inf): PRIVATE_INSTALLED_MODULE := $(_mif)
-$(inf) : PRIVATE_NOTICES := $(_notices)
+$(inf) : PRIVATE_NOTICES := $(sort $(foreach n,$(_notices),$(call word-colon,1,$(n) )))
-$(inf): $(_notices)
+$(inf): $(foreach n,$(_notices),$(call word-colon,1,$(n)) )
@echo Notice file: $$< -- $$@
mkdir -p $$(dir $$@)
awk 'FNR==1 && NR > 1 {print "\n"} {print}' $$(PRIVATE_NOTICES) > $$@
@@ -625,10 +650,195 @@
endef
###########################################################
+## License metadata build rule for non-module target $(1)
+###########################################################
+define non-module-license-metadata-rule
+$(strip $(eval _dir := $(call license-metadata-dir)))
+$(strip $(eval _tgt := $(strip $(1))))
+$(strip $(eval _deps := $(sort $(filter-out 0p: :,$(foreach d,$(strip $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES)),$(ALL_TARGETS.$(call word-colon,1,$(d)).META_LIC):$(call wordlist-colon,2,9999,$(d)))))))
+$(strip $(eval _notices := $(sort $(ALL_NON_MODULES.$(_tgt).NOTICES))))
+$(strip $(eval _path := $(sort $(ALL_NON_MODULES.$(_tgt).PATH))))
+$(strip $(eval _install_map := $(ALL_NON_MODULES.$(_tgt).ROOT_MAPPINGS)))
+$(strip \
+ $(foreach d,$(strip $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES)), \
+ $(if $(strip $(ALL_TARGETS.$(d).META_LIC)), \
+ , \
+ $(eval NON_MODULES_WITHOUT_LICENSE_METADATA += $(d))) \
+ ) \
+)
+
+$(_dir)/$(_tgt).meta_lic: PRIVATE_KINDS := $(sort $(ALL_NON_MODULES.$(_tgt).LICENSE_KINDS))
+$(_dir)/$(_tgt).meta_lic: PRIVATE_CONDITIONS := $(sort $(ALL_NON_MODULES.$(_tgt).LICENSE_CONDITIONS))
+$(_dir)/$(_tgt).meta_lic: PRIVATE_NOTICES := $(_notices)
+$(_dir)/$(_tgt).meta_lic: PRIVATE_NOTICE_DEPS := $(_deps)
+$(_dir)/$(_tgt).meta_lic: PRIVATE_SOURCES := $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES)
+$(_dir)/$(_tgt).meta_lic: PRIVATE_TARGETS := $(_tgt)
+$(_dir)/$(_tgt).meta_lic: PRIVATE_PATH := $(_path)
+$(_dir)/$(_tgt).meta_lic: PRIVATE_IS_CONTAINER := $(ALL_NON_MODULES.$(_tgt).IS_CONTAINER)
+$(_dir)/$(_tgt).meta_lic: PRIVATE_PACKAGE_NAME := $(strip $(ALL_NON_MODULES.$(_tgt).LICENSE_PACKAGE_NAME))
+$(_dir)/$(_tgt).meta_lic: PRIVATE_INSTALL_MAP := $(strip $(_install_map))
+$(_dir)/$(_tgt).meta_lic: $(BUILD_LICENSE_METADATA)
+$(_dir)/$(_tgt).meta_lic : $(foreach d,$(_deps),$(call word-colon,1,$(d))) $(foreach n,$(_notices),$(call word-colon,1,$(n)) )
+ rm -f $$@
+ mkdir -p $$(dir $$@)
+ $(BUILD_LICENSE_METADATA) \
+ -mt raw -mc unknown \
+ $$(addprefix -k ,$$(PRIVATE_KINDS)) \
+ $$(addprefix -c ,$$(PRIVATE_CONDITIONS)) \
+ $$(addprefix -n ,$$(PRIVATE_NOTICES)) \
+ $$(addprefix -d ,$$(PRIVATE_NOTICE_DEPS)) \
+ $$(addprefix -s ,$$(PRIVATE_SOURCES)) \
+ $$(addprefix -m ,$$(PRIVATE_INSTALL_MAP)) \
+ $$(addprefix -t ,$$(PRIVATE_TARGETS)) \
+ $$(if $$(PRIVATE_IS_CONTAINER),-is_container) \
+ -p '$$(PRIVATE_PACKAGE_NAME)' \
+ $$(addprefix -r ,$$(PRIVATE_PATH)) \
+ -o $$@
+
+endef
+
+###########################################################
+## Declare the license metadata for non-module target $(1).
+##
+## $(2) -- license kinds e.g. SPDX-license-identifier-Apache-2.0
+## $(3) -- license conditions e.g. notice by_exception_only
+## $(4) -- license text filenames (notices)
+## $(5) -- package name
+## $(6) -- project path
+###########################################################
+define declare-license-metadata
+$(strip \
+ $(eval _tgt := $(strip $(1))) \
+ $(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_NON_MODULES.$(_tgt).LICENSE_KINDS := $(strip $(2))) \
+ $(eval ALL_NON_MODULES.$(_tgt).LICENSE_CONDITIONS := $(strip $(3))) \
+ $(eval ALL_NON_MODULES.$(_tgt).NOTICES := $(strip $(4))) \
+ $(eval ALL_NON_MODULES.$(_tgt).LICENSE_PACKAGE_NAME := $(strip $(5))) \
+ $(eval ALL_NON_MODULES.$(_tgt).PATH := $(strip $(6))) \
+)
+endef
+
+###########################################################
+## Declare the license metadata for non-module container-type target $(1).
+##
+## Container-type targets are targets like .zip files that
+## merely aggregate other files.
+##
+## $(2) -- license kinds e.g. SPDX-license-identifier-Apache-2.0
+## $(3) -- license conditions e.g. notice by_exception_only
+## $(4) -- license text filenames (notices)
+## $(5) -- package name
+## $(6) -- project path
+###########################################################
+define declare-container-license-metadata
+$(strip \
+ $(eval _tgt := $(strip $(1))) \
+ $(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_NON_MODULES.$(_tgt).LICENSE_KINDS := $(strip $(2))) \
+ $(eval ALL_NON_MODULES.$(_tgt).LICENSE_CONDITIONS := $(strip $(3))) \
+ $(eval ALL_NON_MODULES.$(_tgt).NOTICES := $(strip $(4))) \
+ $(eval ALL_NON_MODULES.$(_tgt).LICENSE_PACKAGE_NAME := $(strip $(5))) \
+ $(eval ALL_NON_MODULES.$(_tgt).PATH := $(strip $(6))) \
+ $(eval ALL_NON_MODULES.$(_tgt).IS_CONTAINER := true) \
+)
+endef
+
+###########################################################
+## Declare that non-module target $(1) is a non-copyrightable file.
+##
+## e.g. an information-only file merely listing other files.
+###########################################################
+define declare-0p-target
+$(strip \
+ $(eval _tgt := $(strip $(1))) \
+ $(eval ALL_0P_TARGETS += $(_tgt)) \
+)
+endef
+
+###########################################################
+## Declare non-module target $(1) to have a first-party license
+## (Android Apache 2.0)
+##
+## $(2) -- project path
+###########################################################
+define declare-1p-target
+$(call declare-license-metadata,$(1),SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,Android,$(2))
+endef
+
+###########################################################
+## Declare non-module container-type target $(1) to have a
+## first-party license (Android Apache 2.0).
+##
+## Container-type targets are targets like .zip files that
+## merely aggregate other files.
+##
+## $92) -- project path
+###########################################################
+define declare-1p-container
+$(call declare-container-license-metadata,$(1),SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,Android,$(2))
+endef
+
+###########################################################
+## Declare license dependencies $(2) for non-module target $(1)
+###########################################################
+define declare-license-deps
+$(strip \
+ $(eval _tgt := $(strip $(1))) \
+ $(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_NON_MODULES.$(_tgt).DEPENDENCIES := $(strip $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES) $(2))) \
+)
+endef
+
+###########################################################
+## Declare license dependencies $(2) for non-module container-type target $(1)
+##
+## Container-type targets are targets like .zip files that
+## merely aggregate other files.
+##
+## $(3) -- root mappings space-separated source:target
+###########################################################
+define declare-container-license-deps
+$(strip \
+ $(eval _tgt := $(strip $(1))) \
+ $(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_NON_MODULES.$(_tgt).DEPENDENCIES := $(strip $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES) $(2))) \
+ $(eval ALL_NON_MODULES.$(_tgt).IS_CONTAINER := true) \
+ $(eval ALL_NON_MODULES.$(_tgt).ROOT_MAPPINGS := $(strip $(ALL_NON_MODULES.$(_tgt).ROOT_MAPPINGS) $(3))) \
+)
+endef
+
+###########################################################
+## Declares the rule to report targets with no license metadata.
+###########################################################
+define report-missing-licenses-rule
+.PHONY: reportmissinglicenses
+reportmissinglicenses: PRIVATE_NON_MODULES:=$(sort $(NON_MODULES_WITHOUT_LICENSE_METADATA))
+reportmissinglicenses:
+ @echo Reporting $$(words $$(PRIVATE_NON_MODULES)) targets without license metadata
+ $$(foreach t,$$(PRIVATE_NON_MODULES),if ! [ -h $$(t) ]; then echo No license metadata for $$(t) >&2; fi;)
+
+endef
+
+###########################################################
## Declares a license metadata build rule for ALL_MODULES
###########################################################
define build-license-metadata
-$(foreach m,$(sort $(ALL_MODULES)),$(eval $(call license-metadata-rule,$(m))))
+$(strip \
+ $(strip $(eval _dir := $(call license-metadata-dir))) \
+ $(foreach t,$(sort $(ALL_0P_TARGETS)), \
+ $(eval ALL_TARGETS.$(t).META_LIC := 0p) \
+ ) \
+ $(foreach t,$(sort $(ALL_NON_MODULES)), \
+ $(eval ALL_TARGETS.$(t).META_LIC := $(_dir)/$(t).meta_lic) \
+ ) \
+ $(foreach m,$(sort $(ALL_MODULES)), \
+ $(foreach d,$(sort $(ALL_MODULES.$(m).BUILT) $(ALL_MODULES.$(m).INSTALLED)), \
+ $(eval ALL_TARGETS.$(d).META_LIC := $(_dir)/$(m).meta_lic) \
+ ) \
+ ) \
+)$(foreach t,$(sort $(ALL_NON_MODULES)),$(eval $(call non-module-license-metadata-rule,$(t))))$(strip \
+)$(foreach m,$(sort $(ALL_MODULES)),$(eval $(call license-metadata-rule,$(m))))$(strip \
+)$(eval $(call report-missing-licenses-rule))
endef
###########################################################
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 7655b42..ea50313 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -423,6 +423,15 @@
$(LOCAL_INSTALLED_MODULE): $(my_dexpreopt_config_for_postprocessing)
+# 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
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 e3aa996..f7cf8de 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -359,7 +359,7 @@
is_sdk_build :=
-ifneq ($(filter sdk win_sdk sdk_addon,$(MAKECMDGOALS)),)
+ifneq ($(filter sdk sdk_addon,$(MAKECMDGOALS)),)
is_sdk_build := true
endif
@@ -534,7 +534,12 @@
# Include all of the makefiles in the system
#
-subdir_makefiles := $(SOONG_ANDROID_MK) $(file <$(OUT_DIR)/.module_paths/Android.mk.list) $(SOONG_OUT_DIR)/late-$(TARGET_PRODUCT).mk
+subdir_makefiles := $(SOONG_OUT_DIR)/installs-$(TARGET_PRODUCT).mk $(SOONG_ANDROID_MK)
+# Android.mk files are only used on Linux builds, Mac only supports Android.bp
+ifeq ($(HOST_OS),linux)
+ subdir_makefiles += $(file <$(OUT_DIR)/.module_paths/Android.mk.list)
+endif
+subdir_makefiles += $(SOONG_OUT_DIR)/late-$(TARGET_PRODUCT).mk
subdir_makefiles_total := $(words int $(subdir_makefiles) post finish)
.KATI_READONLY := subdir_makefiles_total
@@ -1310,7 +1315,11 @@
)
endef
-ifdef FULL_BUILD
+ifeq ($(HOST_OS),darwin)
+ # Target builds are not supported on Mac
+ product_target_FILES :=
+ product_host_FILES := $(call host-installed-files,$(INTERNAL_PRODUCT))
+else ifdef FULL_BUILD
ifneq (true,$(ALLOW_MISSING_DEPENDENCIES))
# Check to ensure that all modules in PRODUCT_PACKAGES exist (opt in per product)
ifeq (true,$(PRODUCT_ENFORCE_PACKAGES_EXIST))
@@ -1370,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
@@ -1466,7 +1475,9 @@
# contains everything that's built during the current make, but it also further
# extends ALL_DEFAULT_INSTALLED_MODULES.
ALL_DEFAULT_INSTALLED_MODULES := $(modules_to_install)
-include $(BUILD_SYSTEM)/Makefile
+ifeq ($(HOST_OS),linux)
+ include $(BUILD_SYSTEM)/Makefile
+endif
modules_to_install := $(sort $(ALL_DEFAULT_INSTALLED_MODULES))
ALL_DEFAULT_INSTALLED_MODULES :=
@@ -1687,7 +1698,11 @@
endif
.PHONY: apps_only
-ifneq ($(TARGET_BUILD_APPS),)
+ifeq ($(HOST_OS),darwin)
+ # Mac only supports building host modules
+ droid_targets: $(filter $(HOST_OUT_ROOT)/%,$(modules_to_install)) dist_files
+
+else ifneq ($(TARGET_BUILD_APPS),)
# If this build is just for apps, only build apps and not the full system by default.
unbundled_build_modules :=
@@ -1914,11 +1929,11 @@
.PHONY: docs
docs: $(ALL_DOCS)
-.PHONY: sdk win_sdk winsdk-tools sdk_addon
+.PHONY: sdk sdk_addon
ifeq ($(HOST_OS),linux)
ALL_SDK_TARGETS := $(INTERNAL_SDK_TARGET)
sdk: $(ALL_SDK_TARGETS)
-$(call dist-for-goals,sdk win_sdk, \
+$(call dist-for-goals,sdk, \
$(ALL_SDK_TARGETS) \
$(SYMBOLS_ZIP) \
$(COVERAGE_ZIP) \
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
index 2e1bd69..2157c9e 100644
--- a/core/ninja_config.mk
+++ b/core/ninja_config.mk
@@ -38,15 +38,19 @@
test-art% \
user \
userdataimage \
- userdebug \
- win_sdk \
- winsdk-tools
+ userdebug
include $(wildcard vendor/*/build/ninja_config.mk)
# Any Android goals that need to be built.
ANDROID_GOALS := $(filter-out $(KATI_OUTPUT_PATTERNS),\
$(sort $(ORIGINAL_MAKECMDGOALS) $(MAKECMDGOALS)))
+# Temporary compatibility support until the build server configs are updated
+ANDROID_GOALS := $(patsubst win_sdk,sdk,$(ANDROID_GOALS))
+ifneq ($(HOST_OS),linux)
+ ANDROID_GOALS := $(filter-out sdk,$(ANDROID_GOALS))
+ ANDROID_GOALS := $(patsubst sdk_repo,sdk-repo-build-tools sdk-repo-platform-tools,$(ANDROID_GOALS))
+endif
# Goals we need to pass to Ninja.
NINJA_GOALS := $(filter-out $(NINJA_EXCLUDE_GOALS), $(ANDROID_GOALS))
ifndef NINJA_GOALS
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/notice_files.mk b/core/notice_files.mk
index 9678380..36f2c8f 100644
--- a/core/notice_files.mk
+++ b/core/notice_files.mk
@@ -81,43 +81,60 @@
# Include shared libraries' notices for "container" types, but not for binaries etc.
notice_deps := \
$(strip \
- $(LOCAL_REQUIRED_MODULES) \
- $(LOCAL_STATIC_LIBRARIES) \
- $(LOCAL_WHOLE_STATIC_LIBRARIES) \
- $(LOCAL_SHARED_LIBRARIES) \
- $(LOCAL_DYLIB_LIBRARIES) \
- $(LOCAL_RLIB_LIBRARIES) \
- $(LOCAL_PROC_MACRO_LIBRARIES) \
- $(LOCAL_HEADER_LIBRARIES) \
- $(LOCAL_STATIC_JAVA_LIBRARIES) \
- $(LOCAL_JAVA_LIBRARIES) \
- $(LOCAL_JNI_SHARED_LIBRARIES) \
+ $(foreach d, \
+ $(LOCAL_REQUIRED_MODULES) \
+ $(LOCAL_STATIC_LIBRARIES) \
+ $(LOCAL_WHOLE_STATIC_LIBRARIES) \
+ $(LOCAL_SHARED_LIBRARIES) \
+ $(LOCAL_DYLIB_LIBRARIES) \
+ $(LOCAL_RLIB_LIBRARIES) \
+ $(LOCAL_PROC_MACRO_LIBRARIES) \
+ $(LOCAL_HEADER_LIBRARIES) \
+ $(LOCAL_STATIC_JAVA_LIBRARIES) \
+ $(LOCAL_JAVA_LIBRARIES) \
+ $(LOCAL_JNI_SHARED_LIBRARIES) \
+ ,$(subst :,_,$(d)):static \
+ ) \
)
else
notice_deps := \
$(strip \
- $(LOCAL_REQUIRED_MODULES) \
- $(LOCAL_STATIC_LIBRARIES) \
- $(LOCAL_WHOLE_STATIC_LIBRARIES) \
- $(LOCAL_RLIB_LIBRARIES) \
- $(LOCAL_PROC_MACRO_LIBRARIES) \
- $(LOCAL_HEADER_LIBRARIES) \
- $(LOCAL_STATIC_JAVA_LIBRARIES) \
+ $(foreach d, \
+ $(LOCAL_REQUIRED_MODULES) \
+ $(LOCAL_STATIC_LIBRARIES) \
+ $(LOCAL_WHOLE_STATIC_LIBRARIES) \
+ $(LOCAL_RLIB_LIBRARIES) \
+ $(LOCAL_PROC_MACRO_LIBRARIES) \
+ $(LOCAL_HEADER_LIBRARIES) \
+ $(LOCAL_STATIC_JAVA_LIBRARIES) \
+ ,$(subst :,_,$(d)):static \
+ )$(foreach d, \
+ $(LOCAL_SHARED_LIBRARIES) \
+ $(LOCAL_DYLIB_LIBRARIES) \
+ $(LOCAL_JAVA_LIBRARIES) \
+ $(LOCAL_JNI_SHARED_LIBRARIES) \
+ ,$(subst :,_,$(d)):dynamic \
+ ) \
)
endif
ifeq ($(LOCAL_IS_HOST_MODULE),true)
-notice_deps := $(strip $(notice_deps) $(LOCAL_HOST_REQUIRED_MODULES))
+notice_deps := $(strip $(notice_deps) $(foreach d,$(LOCAL_HOST_REQUIRED_MODULES),$(subst :,_,$(d)):static))
else
-notice_deps := $(strip $(notice_deps) $(LOCAL_TARGET_REQUIRED_MODULES))
+notice_deps := $(strip $(notice_deps) $(foreach d,$(LOCAL_TARGET_REQUIRED_MODULES),$(subst :,_,$(d)):static))
endif
+local_path := $(LOCAL_PATH)
+
ifdef my_register_name
ALL_MODULES.$(my_register_name).LICENSE_PACKAGE_NAME := $(strip $(license_package_name))
+ALL_MODULES.$(my_register_name).MODULE_TYPE := $(strip $(ALL_MODULES.$(my_register_name).MODULE_TYPE) $(LOCAL_MODULE_TYPE))
+ALL_MODULES.$(my_register_name).MODULE_CLASS := $(strip $(ALL_MODULES.$(my_register_name).MODULE_CLASS) $(LOCAL_MODULE_CLASS))
ALL_MODULES.$(my_register_name).LICENSE_KINDS := $(ALL_MODULES.$(my_register_name).LICENSE_KINDS) $(license_kinds)
ALL_MODULES.$(my_register_name).LICENSE_CONDITIONS := $(ALL_MODULES.$(my_register_name).LICENSE_CONDITIONS) $(license_conditions)
ALL_MODULES.$(my_register_name).LICENSE_INSTALL_MAP := $(ALL_MODULES.$(my_register_name).LICENSE_INSTALL_MAP) $(install_map)
ALL_MODULES.$(my_register_name).NOTICE_DEPS := $(ALL_MODULES.$(my_register_name).NOTICE_DEPS) $(notice_deps)
ALL_MODULES.$(my_register_name).IS_CONTAINER := $(strip $(filter-out false,$(ALL_MODULES.$(my_register_name).IS_CONTAINER) $(is_container)))
+ALL_MODULES.$(my_register_name).PATH := $(strip $(ALL_MODULES.$(my_register_name).PATH) $(local_path))
endif
ifdef notice_file
@@ -185,9 +202,9 @@
INSTALLED_NOTICE_FILES.$(installed_notice_file).MODULE := $(my_register_name)
else
$(installed_notice_file): PRIVATE_INSTALLED_MODULE := $(module_installed_filename)
-$(installed_notice_file) : PRIVATE_NOTICES := $(notice_file)
+$(installed_notice_file) : PRIVATE_NOTICES := $(sort $(foreach n,$(notice_file),$(if $(filter %:%,$(n)), $(call word-colon,1,$(n)), $(n))))
-$(installed_notice_file): $(notice_file)
+$(installed_notice_file): $(foreach n,$(notice_file),$(if $(filter %:%,$(n)), $(call word-colon,1,$(n)), $(n)))
@echo Notice file: $< -- $@
$(hide) mkdir -p $(dir $@)
$(hide) awk 'FNR==1 && NR > 1 {print "\n"} {print}' $(PRIVATE_NOTICES) > $@
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 db7e2a8..683c429 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -237,6 +237,8 @@
_product_list_vars += PRODUCT_APEX_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.
+_product_single_value_vars += PRODUCT_BROKEN_DEPRECATED_MK_SYSTEM_SERVER_JARS
# Additional system server jars to be appended at the end of the common list.
# This is necessary to avoid jars reordering due to makefile inheritance order.
@@ -279,9 +281,6 @@
PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION \
PRODUCT_USES_DEFAULT_ART_CONFIG \
-# The file name for the boot image with a debug ramdisk.
-_product_single_value_vars += PRODUCT_DEBUG_RAMDISK_BOOT_IMAGE_NAME
-
_product_single_value_vars += PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
# Per-module sanitizer configs
_product_list_vars += PRODUCT_SANITIZER_MODULE_CONFIGS
@@ -441,6 +440,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 200c3ab..6588b8e 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -110,6 +110,13 @@
$(filter $(1),$(TARGET_BOARD_PLATFORM))
endef
+# Return empty unless the board is QCOM
+define is-vendor-board-qcom
+$(if $(strip $(TARGET_BOARD_PLATFORM) $(QCOM_BOARD_PLATFORMS)),\
+ $(filter $(TARGET_BOARD_PLATFORM),$(QCOM_BOARD_PLATFORMS)),\
+ $(error both TARGET_BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) and QCOM_BOARD_PLATFORMS=$(QCOM_BOARD_PLATFORMS)))
+endef
+
# ---------------------------------------------------------------
# Check for obsolete PRODUCT- and APP- goals
ifeq ($(CALLED_FROM_SETUP),true)
@@ -199,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/rbc-run $(current_product_makefile) \
+ >$(OUT_DIR)/rbctemp.mk)
+ ifneq ($(.SHELLSTATUS),0)
+ $(error product configuration converter failed: $(.SHELLSTATUS))
endif
include $(OUT_DIR)/rbctemp.mk
PRODUCTS += $(current_product_makefile)
diff --git a/core/product_config.rbc b/core/product_config.rbc
index 5219751..c32db76 100644
--- a/core/product_config.rbc
+++ b/core/product_config.rbc
@@ -17,7 +17,7 @@
"""Runtime functions."""
_soong_config_namespaces_key = "$SOONG_CONFIG_NAMESPACES"
-def _global_init(version_info):
+def _init_globals(version_info):
"""Returns dict created from the runtime environment."""
globals = dict()
@@ -30,7 +30,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 +49,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,18 +74,24 @@
__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()):
+ _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)
- elif attr not in globals_base or globals_base[attr] != val:
- __print_attr(attr, val)
+ else:
+ print("SOONG_CONFIG_%s_%s :=" % (nsname, var))
+ 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."""
@@ -106,7 +112,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
@@ -200,6 +206,16 @@
return (globals, configs[top_pcm_name][1], globals_base)
+
+def _board_configuration(board_config_init, input_variables_init):
+ globals = {}
+ h = __h_new()
+ input_variables_init(globals, h)
+ globals_base = dict(**globals)
+ board_config_init(globals, h)
+ return (globals, h[1], globals_base)
+
+
def _substitute_inherited(configs, pcm_name, cfg):
"""Substitutes inherited values in all the attributes.
@@ -279,19 +295,41 @@
"""Returns configuration item for the inherited module."""
return (pcm_name,)
-def _add_soong_config_namespace(g, nsname):
- """Adds given namespace."""
+def _soong_config_namespace(g, nsname):
+ """Adds given namespace if it does not exist."""
+
+ 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 _add_soong_config_var_value(g, nsname, var, value):
- """Defines a variable and adds it to the given namespace."""
- ns = g[_soong_config_namespaces_key].get(nsname)
- if ns == None:
- fail("no such namespace: " + nsname)
- ns[var] = value
+def _soong_config_set(g, nsname, var, value):
+ """Assigns the value to the variable in the namespace."""
+ _soong_config_namespace(g, nsname)
+ g[_soong_config_namespaces_key][nsname][var]=value
+
+def _soong_config_append(g, nsname, var, value):
+ """Appends to the value of the variable in the namespace."""
+ _soong_config_namespace(g, nsname)
+ ns = g[_soong_config_namespaces_key][nsname]
+ oldv = ns.get(var)
+ if oldv == None:
+ ns[var] = value
+ else:
+ 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
+
def _addprefix(prefix, string_or_list):
"""Adds prefix and returns a list.
@@ -323,7 +361,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:
@@ -377,6 +415,18 @@
"""Returns basename."""
return path.rsplit("/",1)[-1]
+def _board_platform_in(g, string_or_list):
+ """Returns true if board is in the list."""
+ board = g.get("TARGET_BOARD_PLATFORM","")
+ if not board:
+ return False
+ return board in __words(string_or_list)
+
+
+def _board_platform_is(g, s):
+ """True if board is the same as argument."""
+ return g.get("TARGET_BOARD_PLATFORM","") == s
+
def _copy_files(l, outdir):
"""Generate <item>:<outdir>/item for each item."""
@@ -435,6 +485,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."""
@@ -596,10 +653,15 @@
# Settings used during debugging.
_options = __get_options()
rblf = struct(
- add_soong_config_namespace = _add_soong_config_namespace,
- add_soong_config_var_value = _add_soong_config_var_value,
+ 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,
+ board_platform_in = _board_platform_in,
+ board_platform_is = _board_platform_is,
copy_files = _copy_files,
copy_if_exists = _copy_if_exists,
cfg = __h_cfg,
@@ -610,7 +672,7 @@
filter = _filter,
filter_out = _filter_out,
find_and_copy = _find_and_copy,
- global_init = _global_init,
+ init_globals = _init_globals,
inherit = _inherit,
indirect = _indirect,
mkinfo = _mkinfo,
@@ -619,8 +681,11 @@
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 ef9eace..f994165 100644
--- a/core/soong_android_app_set.mk
+++ b/core/soong_android_app_set.mk
@@ -9,6 +9,11 @@
LOCAL_BUILT_MODULE_STEM := $(LOCAL_APK_SET_INSTALL_FILE)
LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_APK_SET_INSTALL_FILE)
+
+# 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
#######################################
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index eeac9aa..dcb5a2e 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -28,6 +28,17 @@
full_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
+
+# 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)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_CLASSES_JAR)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_HEADER_JAR)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_FULL_MANIFEST_FILE)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_DEXPREOPT_CONFIG)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_DEX_JAR)
+
#######################################
include $(BUILD_SYSTEM)/base_rules.mk
#######################################
@@ -127,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 87%
rename from core/soong_cc_prebuilt.mk
rename to core/soong_cc_rust_prebuilt.mk
index 4d7b614..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
@@ -45,11 +45,16 @@
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 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)
@@ -108,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 :=
@@ -228,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.
@@ -242,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_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 1b93be2..801a265 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -25,6 +25,15 @@
LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_AAR)
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)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_HEADER_JAR)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_FULL_MANIFEST_FILE)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_DEXPREOPT_CONFIG)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE)
+LOCAL_ADDITIONAL_CHECKED_MODULE += $(LOCAL_SOONG_DEX_JAR)
+
#######################################
include $(BUILD_SYSTEM)/base_rules.mk
#######################################
@@ -145,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 26c099b..0000000
--- a/core/soong_rust_prebuilt.mk
+++ /dev/null
@@ -1,184 +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
-
-
-#######################################
-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/core/tasks/dex_preopt_check.mk b/core/tasks/dex_preopt_check.mk
new file mode 100644
index 0000000..bfa1ec5
--- /dev/null
+++ b/core/tasks/dex_preopt_check.mk
@@ -0,0 +1,18 @@
+# Checks that some critical dexpreopt output files are installed.
+
+# Inputs:
+# DISABLE_DEXPREOPT_CHECK: True if the check should be disabled.
+# PRODUCT_PACKAGES: The list of packages to be installed for the product.
+# ALL_DEFAULT_INSTALLED_MODULES: The full list of modules going to be installed.
+# DEXPREOPT_SYSTEMSERVER_ARTIFACTS: The list of compilation artifacts of system server jars, which
+# is generated by Soong in dexpreopt_check.go.
+
+ifneq (true,$(DISABLE_DEXPREOPT_CHECK))
+ # Skip the check if the system server is not installed for the product.
+ ifneq (,$(filter services,$(PRODUCT_PACKAGES)))
+ $(call maybe-print-list-and-error,\
+ $(filter-out $(ALL_DEFAULT_INSTALLED_MODULES),$(DEXPREOPT_SYSTEMSERVER_ARTIFACTS)),\
+ Missing compilation artifacts. Dexpreopting is not working for some system server jars \
+ )
+ endif
+endif
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index c838264..5d5bfa8 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -16,6 +16,8 @@
'"module_name": "$(ALL_MODULES.$(m).MODULE_NAME)", ' \
'"test_config": [$(foreach w,$(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS)),"$(w)", )], ' \
'"dependencies": [$(foreach w,$(sort $(ALL_DEPS.$(m).ALL_DEPS)),"$(w)", )], ' \
+ '"shared_libs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SHARED_LIBS)),"$(w)", )], ' \
+ '"system_shared_libs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SYSTEM_SHARED_LIBS)),"$(w)", )], ' \
'"srcs": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCS)),"$(w)", )], ' \
'"srcjars": [$(foreach w,$(sort $(ALL_MODULES.$(m).SRCJARS)),"$(w)", )], ' \
'"classes_jar": [$(foreach w,$(sort $(ALL_MODULES.$(m).CLASSES_JAR)),"$(w)", )], ' \
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 006dff0..1f1ec3f 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -85,7 +85,7 @@
# It must be of the form "YYYY-MM-DD" on production devices.
# It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
- PLATFORM_SECURITY_PATCH := 2021-10-05
+ PLATFORM_SECURITY_PATCH := 2021-11-05
endif
.KATI_READONLY := PLATFORM_SECURITY_PATCH
diff --git a/envsetup.sh b/envsetup.sh
index b5dc847..1687309 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1459,7 +1459,7 @@
> $ANDROID_PRODUCT_OUT/module-info.json.build.log 2>&1
}
-# Verifies that module-info.txt exists, creating it if it doesn't.
+# Verifies that module-info.txt exists, returning nonzero if it doesn't.
function verifymodinfo() {
if [ ! "$ANDROID_PRODUCT_OUT" ]; then
if [ "$QUIET_VERIFYMODINFO" != "true" ] ; then
@@ -1470,7 +1470,7 @@
if [ ! -f "$ANDROID_PRODUCT_OUT/module-info.json" ]; then
if [ "$QUIET_VERIFYMODINFO" != "true" ] ; then
- echo "Could not find module-info.json. It will only be built once, and it can be updated with 'refreshmod'" >&2
+ echo "Could not find module-info.json. Please run 'refreshmod' first." >&2
fi
return 1
fi
@@ -1589,6 +1589,10 @@
function installmod() {
if [[ $# -eq 0 ]]; then
echo "usage: installmod [adb install arguments] <module>" >&2
+ echo "" >&2
+ echo "Only flags to be passed after the \"install\" in adb install are supported," >&2
+ echo "with the exception of -s. If -s is passed it will be placed before the \"install\"." >&2
+ echo "-s must be the first flag passed if it exists." >&2
return 1
fi
@@ -1603,9 +1607,18 @@
echo "Module '$1' does not produce a file ending with .apk (try 'refreshmod' if there have been build changes?)" >&2
return 1
fi
+ local serial_device=""
+ if [[ "$1" == "-s" ]]; then
+ if [[ $# -le 2 ]]; then
+ echo "-s requires an argument" >&2
+ return 1
+ fi
+ serial_device="-s $2"
+ shift 2
+ fi
local length=$(( $# - 1 ))
- echo adb install ${@:1:$length} $_path
- adb install ${@:1:$length} $_path
+ echo adb $serial_device install ${@:1:$length} $_path
+ adb $serial_device install ${@:1:$length} $_path
}
function _complete_android_module_names() {
@@ -1870,16 +1883,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/board/BoardConfigModuleCommon.mk b/target/board/BoardConfigModuleCommon.mk
index 9832474..24c01a5 100644
--- a/target/board/BoardConfigModuleCommon.mk
+++ b/target/board/BoardConfigModuleCommon.mk
@@ -4,7 +4,3 @@
# Required for all module devices.
TARGET_USES_64_BIT_BINDER := true
-
-# Necessary to make modules able to use the VNDK via 'use_vendor: true'
-# TODO(b/185769808): look into whether this is still used.
-BOARD_VNDK_VERSION := current
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 13b3417..68dd980 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -327,7 +327,6 @@
incident_report \
ld.mc \
lpdump \
- mdnsd \
minigzip \
mke2fs \
resize2fs \
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index 285c8c7..399652c 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -75,6 +75,7 @@
VNDK-core: android.hardware.graphics.allocator@4.0.so
VNDK-core: android.hardware.graphics.bufferqueue@1.0.so
VNDK-core: android.hardware.graphics.bufferqueue@2.0.so
+VNDK-core: android.hardware.health-V1-ndk.so
VNDK-core: android.hardware.health.storage-V1-ndk.so
VNDK-core: android.hardware.health.storage-V1-ndk_platform.so
VNDK-core: android.hardware.identity-V3-ndk.so
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index d0a98c0..94917f5 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -67,6 +67,8 @@
# Do not build non-GSI partition images.
PRODUCT_BUILD_CACHE_IMAGE := false
+PRODUCT_BUILD_DEBUG_BOOT_IMAGE := false
+PRODUCT_BUILD_DEBUG_VENDOR_BOOT_IMAGE := false
PRODUCT_BUILD_USERDATA_IMAGE := false
PRODUCT_BUILD_VENDOR_IMAGE := false
PRODUCT_BUILD_SUPER_PARTITION := false
@@ -79,7 +81,3 @@
# Additional settings used in all GSI builds
PRODUCT_PRODUCT_PROPERTIES += \
ro.crypto.metadata_init_delete_all_keys.enabled=false \
-
-# Renames boot-debug-*.img to boot-with-debug-ramdisk-*.img to avoid confusion
-# with GKI boot images.
-PRODUCT_DEBUG_RAMDISK_BOOT_IMAGE_NAME := boot-with-debug-ramdisk
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 301605a..43fb8fc 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
diff --git a/target/product/sdk_phone_arm64.mk b/target/product/sdk_phone_arm64.mk
index 0831b54..4203d45 100644
--- a/target/product/sdk_phone_arm64.mk
+++ b/target/product/sdk_phone_arm64.mk
@@ -50,10 +50,6 @@
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_arm64/device.mk)
-# Define the host tools and libs that are parts of the SDK.
-$(call inherit-product, sdk/build/product_sdk.mk)
-$(call inherit-product, development/build/product_sdk.mk)
-
# keep this apk for sdk targets for now
PRODUCT_PACKAGES += \
EmulatorSmokeTests
diff --git a/target/product/sdk_phone_armv7.mk b/target/product/sdk_phone_armv7.mk
index f649980..6c88b44 100644
--- a/target/product/sdk_phone_armv7.mk
+++ b/target/product/sdk_phone_armv7.mk
@@ -49,10 +49,6 @@
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_arm/device.mk)
-# Define the host tools and libs that are parts of the SDK.
-$(call inherit-product, sdk/build/product_sdk.mk)
-$(call inherit-product, development/build/product_sdk.mk)
-
# keep this apk for sdk targets for now
PRODUCT_PACKAGES += \
EmulatorSmokeTests
diff --git a/target/product/sdk_phone_x86.mk b/target/product/sdk_phone_x86.mk
index 0e1bca4..a324e5f 100644
--- a/target/product/sdk_phone_x86.mk
+++ b/target/product/sdk_phone_x86.mk
@@ -49,10 +49,6 @@
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_x86/device.mk)
-# Define the host tools and libs that are parts of the SDK.
-$(call inherit-product-if-exists, sdk/build/product_sdk.mk)
-$(call inherit-product-if-exists, development/build/product_sdk.mk)
-
# Overrides
PRODUCT_BRAND := Android
PRODUCT_NAME := sdk_phone_x86
diff --git a/target/product/sdk_phone_x86_64.mk b/target/product/sdk_phone_x86_64.mk
index fffac04..ff9018d 100644
--- a/target/product/sdk_phone_x86_64.mk
+++ b/target/product/sdk_phone_x86_64.mk
@@ -50,10 +50,6 @@
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_x86_64/device.mk)
-# Define the host tools and libs that are parts of the SDK.
-$(call inherit-product-if-exists, sdk/build/product_sdk.mk)
-$(call inherit-product-if-exists, development/build/product_sdk.mk)
-
# Overrides
PRODUCT_BRAND := Android
PRODUCT_NAME := sdk_phone_x86_64
diff --git a/target/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk b/target/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk
index bc81b33..de1f07d 100644
--- a/target/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk
+++ b/target/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk
@@ -24,3 +24,4 @@
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
e2fsck.vendor_ramdisk \
+ fsck.f2fs.vendor_ramdisk \
diff --git a/tests/device.rbc b/tests/device.rbc
index feefcf7..37c5d0c 100644
--- a/tests/device.rbc
+++ b/tests/device.rbc
@@ -23,12 +23,11 @@
### PRODUCT_PACKAGES += dev_after
### PRODUCT_COPY_FILES += $(call find-copy-subdir-files,audio_platform_info*.xml,device/google/redfin/audio,$(TARGET_COPY_OUT_VENDOR)/etc) xyz:/etc/xyz
### PRODUCT_COPY_FILES += $(call copy-files,x.xml y.xml,/etc)
-### $(call add_soong_namespace,NS1)
-### $(call add_soong_config_var_value,NS1,v1,abc)
-### $(call add_soong_config_var_value,NS1,v2,def)
-### $(call add_soong_namespace,NS2)
+### $(call add_soong_config_namespace,NS1)
+### $(call soong_config_append,NS1,v1,abc)
+### $(call soong_config_append,NS1,v2,def)
### $(call add_soong_config_var_value,NS2,v3,abc)
-### $(call add_soong_config_var_value,NS2,v3,xyz)
+### $(call soong_config_set,NS2,v3,xyz)
load("//build/make/core:product_config.rbc", "rblf")
load(":part1.rbc", _part1_init = "init")
@@ -50,10 +49,20 @@
cfg["PRODUCT_COPY_FILES"] += rblf.copy_files("x.xml y.xml", "/etc")
cfg["PRODUCT_COPY_FILES"] += rblf.copy_files(["from/sub/x", "from/sub/y"], "to")
- rblf.add_soong_config_namespace(g, "NS1")
- rblf.add_soong_config_var_value(g, "NS1", "v1", "abc")
- rblf.add_soong_config_var_value(g, "NS1", "v2", "def")
- rblf.add_soong_config_namespace(g, "NS2")
- rblf.add_soong_config_var_value(g, "NS2", "v3", "abc")
- rblf.add_soong_config_var_value(g, "NS2", "v3", "xyz")
+ rblf.soong_config_namespace(g, "NS1")
+ rblf.soong_config_append(g, "NS1", "v1", "abc")
+ rblf.soong_config_append(g, "NS1", "v2", "def")
+ rblf.soong_config_set(g, "NS2", "v3", "abc")
+ rblf.soong_config_set(g, "NS2", "v3", "xyz")
+ if rblf.board_platform_in(g, "board1 board2"):
+ cfg["PRODUCT_PACKAGES"] += ["bad_package"]
+ g["TARGET_BOARD_PLATFORM"] = "board1"
+ if rblf.board_platform_in(g, "board1 board2"):
+ cfg["PRODUCT_PACKAGES"] += ["board1_in"]
+ if rblf.board_platform_in(g, ["board3","board2"]):
+ cfg["PRODUCT_PACKAGES"] += ["bad_board_in"]
+ if rblf.board_platform_is(g, "board1"):
+ cfg["PRODUCT_PACKAGES"] += ["board1_is"]
+ if rblf.board_platform_is(g, "board2"):
+ cfg["PRODUCT_PACKAGES"] += ["bad_board1_is"]
diff --git a/tests/part1.rbc b/tests/part1.rbc
index 3e50751..ae79d32 100644
--- a/tests/part1.rbc
+++ b/tests/part1.rbc
@@ -26,3 +26,5 @@
cfg["PRODUCT_COPY_FILES"] += ["part_from:part_to"]
rblf.setdefault(handle, "PRODUCT_PRODUCT_PROPERTIES")
cfg["PRODUCT_PRODUCT_PROPERTIES"] += ["part_properties"]
+ rblf.soong_config_namespace(g, "NS1")
+ rblf.soong_config_append(g, "NS1", "v1", "abc_part1")
diff --git a/tests/run.rbc b/tests/run.rbc
index eef217b..d222341 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(
{
@@ -69,7 +74,9 @@
"PRODUCT_PACKAGES": [
"dev",
"inc",
- "dev_after"
+ "dev_after",
+ "board1_in",
+ "board1_is",
],
"PRODUCT_PRODUCT_PROPERTIES": ["part_properties"]
},
@@ -80,7 +87,7 @@
assert_eq(
{
"NS1": {
- "v1": "abc",
+ "v1": "abc abc_part1",
"v2": "def"
},
"NS2": {
@@ -92,3 +99,6 @@
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"))
diff --git a/tools/build-license-metadata.sh b/tools/build-license-metadata.sh
deleted file mode 100755
index a138dbe..0000000
--- a/tools/build-license-metadata.sh
+++ /dev/null
@@ -1,313 +0,0 @@
-#!/bin/sh
-
-set -u
-
-ME=$(basename $0)
-
-USAGE="Usage: ${ME} {options}
-
-Builds a license metadata specification and outputs it to stdout or {outfile}.
-
-The available options are:
-
--k kind... license kinds
--c condition... license conditions
--p package... license package name
--n notice... license notice file
--d dependency... license metadata file dependency
--t target... targets
--m target:installed... map dependent targets to their installed names
--is_container preserved dependent target name when given
--o outfile output file
-"
-
-# Global flag variables
-license_kinds=
-license_conditions=
-license_package_name=
-license_notice=
-license_deps=
-targets=
-installmap=
-is_container=false
-ofile=
-
-# Global variables
-depfiles=" "
-effective_conditions=
-
-
-# Exits with a message.
-#
-# When the exit status is 2, assumes a usage error and outputs the usage message
-# to stderr before outputting the specific error message to stderr.
-#
-# Parameters:
-# Optional numeric exit status (defaults to 2, i.e. a usage error.)
-# Remaining args treated as an error message sent to stderr.
-die() {
- lstatus=2
- case "${1:-}" in *[^0-9]*) ;; *) lstatus="$1"; shift ;; esac
- case "${lstatus}" in 2) echo "${USAGE}" >&2; echo >&2 ;; esac
- if [ -n "$*" ]; then
- echo -e "$*\n" >&2
- fi
- exit $lstatus
-}
-
-
-# Sets the flag variables based on the command-line.
-#
-# invoke with: process_args "$@"
-process_args() {
- lcurr_flag=
- while [ "$#" -gt '0' ]; do
- case "${1}" in
- -h)
- echo "${USAGE}"
- exit 0
- ;;
- -k)
- lcurr_flag=kind
- ;;
- -c)
- lcurr_flag=condition
- ;;
- -p)
- lcurr_flag=package
- ;;
- -n)
- lcurr_flag=notice
- ;;
- -d)
- lcurr_flag=dependency
- ;;
- -t)
- lcurr_flag=target
- ;;
- -m)
- lcurr_flag=installmap
- ;;
- -o)
- lcurr_flag=ofile
- ;;
- -is_container)
- lcurr_flag=
- is_container=true
- ;;
- -*)
- die "Unknown flag: \"${1}\""
- ;;
- *)
- case "${lcurr_flag}" in
- kind)
- license_kinds="${license_kinds}${license_kinds:+ }${1}"
- ;;
- condition)
- license_conditions="${license_conditions}${license_conditions:+ }${1}"
- ;;
- package)
- license_package_name="${license_package_name}${license_package_name:+ }${1}"
- ;;
- notice)
- license_notice="${license_notice}${license_notice:+ }${1}"
- ;;
- dependency)
- license_deps="${license_deps}${license_deps:+ }${1}"
- ;;
- target)
- targets="${targets}${targets:+ }${1}"
- ;;
- installmap)
- installmap="${installmap}${installmap:+ }${1}"
- ;;
- ofile)
- if [ -n "${ofile}" ]; then
- die "Output file -o appears twice as \"${ofile}\" and \"${1}\""
- fi
- ofile="${1}"
- ;;
- *)
- die "Must precede argument \"${1}\" with type flag."
- ;;
- esac
- ;;
- esac
- shift
- done
-}
-
-# Reads a license metadata file from stdin, and outputs the named dependencies.
-#
-# No parameters.
-extract_deps() {
- awk '$1 == "dep_name:" { sub(/^"/, "", $2); sub(/"$/, "", $2); print $2; }'
-}
-
-# Populates the depfiles variable identifying dependency files.
-#
-# Starting with the dependencies enumerated in license_deps, calculates the
-# transitive closure of all dependencies.
-#
-# Dependency names ending in .meta_module indirectly reference license
-# metadata with 1 license metadata filename per line.
-#
-# No parameters; no output.
-read_deps() {
- lnewdeps=
- for d in ${license_deps}; do
- case "${d}" in
- *.meta_module)
- lnewdeps="${lnewdeps}${lnewdeps:+ }"$(cat "${d}") ;;
- *)
- lnewdeps="${lnewdeps}${lnewdeps:+ }${d}" ;;
- esac
- done
- lnewdeps=$(echo "${lnewdeps}" | tr ' ' '\n' | sort -u)
- lalldeps=
- ldeps=
- lmod=
- ldep=
- while [ "${#lnewdeps}" -gt '0' ]; do
- ldeps="${lnewdeps}"
- lnewdeps=
- for ldep in ${ldeps}; do
- depfiles="${depfiles}${ldep} "
- lalldeps="${lalldeps}${lalldeps:+ }"$(cat "${ldep}" | extract_deps)
- done
- lalldeps=$(for d in ${lalldeps}; do echo "${d}"; done | sort -u)
- for d in ${lalldeps}; do
- ldeps="${d}"
- case "${d}" in *.meta_module) ldeps=$(cat "${d}") ;; esac
- for lmod in ${ldeps}; do
- if ! expr "${depfiles}" : ".* ${lmod} .*" >/dev/null 2>&1; then
- lnewdeps="${lnewdeps}${lnewdeps:+ }${lmod}"
- fi
- done
- done
- lalldeps=
- done
-}
-
-# Returns the effective license conditions for the current license metadata.
-#
-# If a module is restricted or links in a restricted module, the effective
-# license has a restricted condition.
-calculate_effective_conditions() {
- lconditions="${license_conditions}"
- case "${license_conditions}" in
- *restricted*) : do nothing ;;
- *)
- for d in ${depfiles}; do
- if cat "${d}" | egrep -q 'effective_condition\s*:.*restricted' ; then
- lconditions="${lconditions}${lconditions:+ }restricted"
- break
- fi
- done
- ;;
- esac
- echo "${lconditions}"
-}
-
-
-process_args "$@"
-
-if [ -n "${ofile}" ]; then
- # truncate the output file before appending results
- : >"${ofile}"
-else
- ofile=/dev/stdout
-fi
-
-# spit out the license metadata file content
-(
- echo 'license_package_name: "'${license_package_name}'"'
- for kind in ${license_kinds}; do
- echo 'license_kind: "'${kind}'"'
- done
- for condition in ${license_conditions}; do
- echo 'license_condition: "'${condition}'"'
- done
- for f in ${license_notice}; do
- echo 'license_text: "'${f}'"'
- done
- echo "is_container: ${is_container}"
- for t in ${targets}; do
- echo 'target: "'${t}'"'
- done
- for m in ${installmap}; do
- echo 'install_map: "'${m}'"'
- done
-) >>"${ofile}"
-read_deps
-effective_conditions=$(calculate_effective_conditions)
-for condition in ${effective_conditions}; do
- echo 'effective_condition: "'${condition}'"'
-done >>"${ofile}"
-for dep in ${depfiles}; do
- echo 'dep {'
- cat "${dep}" | \
- awk -v name="${dep}" '
- function strip_type() {
- $1 = ""
- sub(/^\s*/, "")
- }
- BEGIN {
- print " dep_name: " name
- }
- $1 == "license_package_name:" {
- strip_type()
- print " dep_package_name: "$0
- }
- $1 == "dep_name:" {
- print " dep_sub_dep: "$2
- }
- $1 == "license_kind:" {
- print " dep_license_kind: "$2
- }
- $1 == "license_condition:" {
- print " dep_license_condition: "$2
- }
- $1 == "is_container:" {
- print " dep_is_container: "$2
- }
- $1 == "license_text:" {
- strip_type()
- print " dep_license_text: "$0
- }
- $1 == "target:" {
- print " dep_target: "$2
- }
- $1 == "install_map:" {
- print " dep_install_map: "$2
- }
- '
- # The restricted license kind is contagious to all linked dependencies.
- dep_conditions=$(echo $(
- cat "${dep}" | awk '
- $1 == "effective_condition:" {
- $1 = ""
- sub(/^\s*/, "")
- gsub(/"/, "")
- print
- }
- '
- ))
- for condition in ${dep_conditions}; do
- echo ' dep_effective_condition: "'${condition}'"'
- done
- if ! ${is_container}; then
- case "${dep_conditions}" in
- *restricted*) : already restricted -- nothing to inherit ;;
- *)
- case "${effective_conditions}" in
- *restricted*)
- # "contagious" restricted infects everything linked to restricted
- echo ' dep_effective_condition: "restricted"'
- ;;
- esac
- ;;
- esac
- fi
- echo '}'
-done >>"${ofile}"
diff --git a/tools/canoninja/README.md b/tools/canoninja/README.md
new file mode 100644
index 0000000..506acf7
--- /dev/null
+++ b/tools/canoninja/README.md
@@ -0,0 +1,151 @@
+# Ninja File Canonicalizer
+
+Suppose we have a tool that generates a Ninja file from some other description (think Kati and makefiles), and during
+the testing we discovered a regression. Furthermore, suppose that the generated Ninja file is large (think millions of
+lines). And, the new Ninja file has build statements and rules in a slightly different order. As the tool generates the
+rule names, the real differences in the output of the `diff` command are drowned in noise. Enter Canoninja.
+
+Canoninja renames each Ninja rule to the hash of its contents. After that, we can just sort the build statements, and a
+simple `comm` command immediately reveal the essential difference between the files.
+
+## Example
+
+Consider the following makefile
+
+```makefile
+second :=
+first: foo
+foo:
+ @echo foo
+second: bar
+bar:
+ @echo bar
+```
+
+Depending on Kati version converting it to Ninja file will yield either:
+
+```
+$ cat /tmp/1.ninja
+# Generated by kati 06f2569b2d16628608c000a76e3d495a5a5528cb
+
+pool local_pool
+ depth = 72
+
+build _kati_always_build_: phony
+
+build first: phony foo
+rule rule0
+ description = build $out
+ command = /bin/sh -c "echo foo"
+build foo: rule0
+build second: phony bar
+rule rule1
+ description = build $out
+ command = /bin/sh -c "echo bar"
+build bar: rule1
+
+default first
+```
+
+or
+
+```
+$ cat 2.ninja
+# Generated by kati 371194da71b3e191fea6f2ccceb7b061bd0de310
+
+pool local_pool
+ depth = 72
+
+build _kati_always_build_: phony
+
+build second: phony bar
+rule rule0
+ description = build $out
+ command = /bin/sh -c "echo bar"
+build bar: rule0
+build first: phony foo
+rule rule1
+ description = build $out
+ command = /bin/sh -c "echo foo"
+build foo: rule1
+
+default first
+```
+
+This is a quirk in Kati, see https://github.com/google/kati/issues/238
+
+Trying to find out the difference between the targets even after sorting them isn't too helpful:
+
+```
+diff <(grep '^build' /tmp/1.ninja|sort) <(grep '^build' /tmp/2.ninja | sort)
+1c1
+< build bar: rule1
+---
+> build bar: rule0
+3c3
+< build foo: rule0
+---
+> build foo: rule1
+```
+
+However, running these files through `canoninja` yields
+
+```
+$ canoninja /tmp/1.ninja
+# Generated by kati 06f2569b2d16628608c000a76e3d495a5a5528cb
+
+pool local_pool
+ depth = 72
+
+build _kati_always_build_: phony
+
+build first: phony foo
+rule R2f9981d3c152fc255370dc67028244f7bed72a03
+ description = build $out
+ command = /bin/sh -c "echo foo"
+build foo: R2f9981d3c152fc255370dc67028244f7bed72a03
+build second: phony bar
+rule R62640f3f9095cf2da5b9d9e2a82f746cc710c94c
+ description = build $out
+ command = /bin/sh -c "echo bar"
+build bar: R62640f3f9095cf2da5b9d9e2a82f746cc710c94c
+
+default first
+```
+
+and
+
+```
+~/go/bin/canoninja /tmp/2.ninja
+# Generated by kati 371194da71b3e191fea6f2ccceb7b061bd0de310
+
+pool local_pool
+ depth = 72
+
+build _kati_always_build_: phony
+
+build second: phony bar
+rule R62640f3f9095cf2da5b9d9e2a82f746cc710c94c
+ description = build $out
+ command = /bin/sh -c "echo bar"
+build bar: R62640f3f9095cf2da5b9d9e2a82f746cc710c94c
+build first: phony foo
+rule R2f9981d3c152fc255370dc67028244f7bed72a03
+ description = build $out
+ command = /bin/sh -c "echo foo"
+build foo: R2f9981d3c152fc255370dc67028244f7bed72a03
+
+default first
+```
+
+and when we extract only build statements and sort them, we see that both Ninja files define the same graph:
+
+```shell
+$ diff <(~/go/bin/canoninja /tmp/1.ninja | grep '^build' | sort) \
+ <(~/go/bin/canoninja /tmp/2.ninja | grep '^build' | sort)
+```
+
+# Todo
+
+* Optionally output only the build statements, optionally sorted
+* Handle continuation lines correctly
diff --git a/tools/canoninja/canoninja.go b/tools/canoninja/canoninja.go
new file mode 100644
index 0000000..681a694
--- /dev/null
+++ b/tools/canoninja/canoninja.go
@@ -0,0 +1,130 @@
+package canoninja
+
+import (
+ "bytes"
+ "crypto/sha1"
+ "encoding/hex"
+ "fmt"
+ "io"
+)
+
+var (
+ rulePrefix = []byte("rule ")
+ buildPrefix = []byte("build ")
+ phonyRule = []byte("phony")
+)
+
+func Generate(path string, buffer []byte, sink io.Writer) error {
+ // Break file into lines
+ from := 0
+ var lines [][]byte
+ for from < len(buffer) {
+ line := getLine(buffer[from:])
+ lines = append(lines, line)
+ from += len(line)
+ }
+
+ // FOr each rule, calculate and remember its digest
+ ruleDigest := make(map[string]string)
+ for i := 0; i < len(lines); {
+ if bytes.HasPrefix(lines[i], rulePrefix) {
+ // Find ruleName
+ rn := ruleName(lines[i])
+ if len(rn) == 0 {
+ return fmt.Errorf("%s:%d: rule name is missing or on the next line", path, i+1)
+ }
+ sRuleName := string(rn)
+ if _, ok := ruleDigest[sRuleName]; ok {
+ return fmt.Errorf("%s:%d: the rule %s has been already defined", path, i+1, sRuleName)
+ }
+ // Calculate rule text digest as a digests of line digests.
+ var digests []byte
+ doDigest := func(b []byte) {
+ h := sha1.New()
+ h.Write(b)
+ digests = h.Sum(digests)
+
+ }
+ // For the first line, digest everything after rule's name
+ doDigest(lines[i][cap(lines[i])+len(rn)-cap(rn):])
+ for i++; i < len(lines) && lines[i][0] == ' '; i++ {
+ doDigest(lines[i])
+ }
+ h := sha1.New()
+ h.Write(digests)
+ ruleDigest[sRuleName] = "R" + hex.EncodeToString(h.Sum(nil))
+
+ } else {
+ i++
+ }
+ }
+
+ // Rewrite rule names.
+ for i, line := range lines {
+ if bytes.HasPrefix(line, buildPrefix) {
+ brn := getBuildRuleName(line)
+ if bytes.Equal(brn, phonyRule) {
+ sink.Write(line)
+ continue
+ }
+ if len(brn) == 0 {
+ return fmt.Errorf("%s:%d: build statement lacks rule name", path, i+1)
+ }
+ sink.Write(line[0 : cap(line)-cap(brn)])
+ if digest, ok := ruleDigest[string(brn)]; ok {
+ sink.Write([]byte(digest))
+ } else {
+ return fmt.Errorf("%s:%d: no rule for this build target", path, i+1)
+ }
+ sink.Write(line[cap(line)+len(brn)-cap(brn):])
+ } else if bytes.HasPrefix(line, rulePrefix) {
+ rn := ruleName(line)
+ // Write everything before it
+ sink.Write(line[0 : cap(line)-cap(rn)])
+ sink.Write([]byte(ruleDigest[string(rn)]))
+ sink.Write(line[cap(line)+len(rn)-cap(rn):])
+ } else {
+ //goland:noinspection GoUnhandledErrorResult
+ sink.Write(line)
+ }
+ }
+ return nil
+}
+
+func getLine(b []byte) []byte {
+ if n := bytes.IndexByte(b, '\n'); n >= 0 {
+ return b[:n+1]
+ }
+ return b
+}
+
+// Returns build statement's rule name
+func getBuildRuleName(line []byte) []byte {
+ n := bytes.IndexByte(line, ':')
+ if n <= 0 {
+ return nil
+ }
+ ruleName := line[n+1:]
+ if ruleName[0] == ' ' {
+ ruleName = bytes.TrimLeft(ruleName, " ")
+ }
+ if n := bytes.IndexAny(ruleName, " \t\r\n"); n >= 0 {
+ ruleName = ruleName[0:n]
+ }
+ return ruleName
+}
+
+// Returns rule statement's rule name
+func ruleName(lineAfterRule []byte) []byte {
+ ruleName := lineAfterRule[len(rulePrefix):]
+ if len(ruleName) == 0 {
+ return ruleName
+ }
+ if ruleName[0] == ' ' {
+ ruleName = bytes.TrimLeft(ruleName, " ")
+ }
+ if n := bytes.IndexAny(ruleName, " \t\r\n"); n >= 0 {
+ ruleName = ruleName[0:n]
+ }
+ return ruleName
+}
diff --git a/tools/canoninja/canoninja_test.go b/tools/canoninja/canoninja_test.go
new file mode 100644
index 0000000..3c45f8c
--- /dev/null
+++ b/tools/canoninja/canoninja_test.go
@@ -0,0 +1,47 @@
+package canoninja
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestGenerate(t *testing.T) {
+ tests := []struct {
+ name string
+ in []byte
+ wantSink string
+ wantErr bool
+ }{
+ {
+ name: "1",
+ in: []byte(`
+rule rule1
+ abcd
+rule rule2
+ abcd
+build x: rule1
+`),
+ wantSink: `
+rule R9c97aba7f61994be6862f5ea9a62d26130c7f48b
+ abcd
+rule R9c97aba7f61994be6862f5ea9a62d26130c7f48b
+ abcd
+build x: R9c97aba7f61994be6862f5ea9a62d26130c7f48b
+`,
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ sink := &bytes.Buffer{}
+ err := Generate("<file>", tt.in, sink)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if gotSink := sink.String(); gotSink != tt.wantSink {
+ t.Errorf("Generate() gotSink = %v, want %v", gotSink, tt.wantSink)
+ }
+ })
+ }
+}
diff --git a/tools/canoninja/cmd/canoninja.go b/tools/canoninja/cmd/canoninja.go
new file mode 100644
index 0000000..71802ef
--- /dev/null
+++ b/tools/canoninja/cmd/canoninja.go
@@ -0,0 +1,36 @@
+package main
+
+/*
+ Canoninja reads a Ninja file and changes the rule names to be the digest of the rule contents.
+ Feed it to a filter that extracts only build statements, sort them, and you will have a crude
+ but effective tool to find small differences between two Ninja files.
+*/
+
+import (
+ "canoninja"
+ "flag"
+ "fmt"
+ "os"
+)
+
+func main() {
+ flag.Parse()
+ files := flag.Args()
+ if len(files) == 0 {
+ files = []string{"/dev/stdin"}
+ }
+ rc := 0
+ for _, f := range files {
+ if buffer, err := os.ReadFile(f); err == nil {
+ err = canoninja.Generate(f, buffer, os.Stdout)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ rc = 1
+ }
+ } else {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", f, err)
+ rc = 1
+ }
+ }
+ os.Exit(rc)
+}
diff --git a/tools/canoninja/go.mod b/tools/canoninja/go.mod
new file mode 100644
index 0000000..c5a924e
--- /dev/null
+++ b/tools/canoninja/go.mod
@@ -0,0 +1 @@
+module canoninja
diff --git a/tools/rbcrun/cmd/rbcrun.go b/tools/rbcrun/cmd/rbcrun.go
index 7848562..4db6a0b 100644
--- a/tools/rbcrun/cmd/rbcrun.go
+++ b/tools/rbcrun/cmd/rbcrun.go
@@ -93,6 +93,6 @@
}
func quit(format string, s ...interface{}) {
- fmt.Fprintln(os.Stderr, format, s)
+ fmt.Fprintf(os.Stderr, format, s...)
os.Exit(2)
}
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/apex_utils.py b/tools/releasetools/apex_utils.py
index 51ec434..ee0feae 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -52,9 +52,9 @@
class ApexApkSigner(object):
- """Class to sign the apk files in a apex payload image and repack the apex"""
+ """Class to sign the apk files and other files in an apex payload image and repack the apex"""
- def __init__(self, apex_path, key_passwords, codename_to_api_level_map):
+ def __init__(self, apex_path, key_passwords, codename_to_api_level_map, avbtool=None, sign_tool=None):
self.apex_path = apex_path
if not key_passwords:
self.key_passwords = dict()
@@ -63,9 +63,11 @@
self.codename_to_api_level_map = codename_to_api_level_map
self.debugfs_path = os.path.join(
OPTIONS.search_path, "bin", "debugfs_static")
+ self.avbtool = avbtool if avbtool else "avbtool"
+ self.sign_tool = sign_tool
def ProcessApexFile(self, apk_keys, payload_key, signing_args=None):
- """Scans and signs the apk files and repack the apex
+ """Scans and signs the payload files and repack the apex
Args:
apk_keys: A dict that holds the signing keys for apk files.
@@ -84,7 +86,7 @@
apk_entries = [name for name in entries_names if name.endswith('.apk')]
# No need to sign and repack, return the original apex path.
- if not apk_entries:
+ if not apk_entries and self.sign_tool is None:
logger.info('No apk file to sign in %s', self.apex_path)
return self.apex_path
@@ -99,15 +101,15 @@
logger.warning('Apk path does not contain the intended directory name:'
' %s', entry)
- payload_dir, has_signed_apk = self.ExtractApexPayloadAndSignApks(
- apk_entries, apk_keys)
- if not has_signed_apk:
- logger.info('No apk file has been signed in %s', self.apex_path)
+ payload_dir, has_signed_content = self.ExtractApexPayloadAndSignContents(
+ apk_entries, apk_keys, payload_key)
+ if not has_signed_content:
+ logger.info('No contents has been signed in %s', self.apex_path)
return self.apex_path
return self.RepackApexPayload(payload_dir, payload_key, signing_args)
- def ExtractApexPayloadAndSignApks(self, apk_entries, apk_keys):
+ def ExtractApexPayloadAndSignContents(self, apk_entries, apk_keys, payload_key):
"""Extracts the payload image and signs the containing apk files."""
if not os.path.exists(self.debugfs_path):
raise ApexSigningError(
@@ -119,7 +121,7 @@
self.debugfs_path, 'extract', self.apex_path, payload_dir]
common.RunAndCheckOutput(extract_cmd)
- has_signed_apk = False
+ has_signed_content = False
for entry in apk_entries:
apk_path = os.path.join(payload_dir, entry)
assert os.path.exists(self.apex_path)
@@ -137,8 +139,15 @@
common.SignFile(
unsigned_apk, apk_path, key_name, self.key_passwords.get(key_name),
codename_to_api_level_map=self.codename_to_api_level_map)
- has_signed_apk = True
- return payload_dir, has_signed_apk
+ has_signed_content = True
+
+ if self.sign_tool:
+ logger.info('Signing payload contents in apex %s with %s', self.apex_path, self.sign_tool)
+ cmd = [self.sign_tool, '--avbtool', self.avbtool, payload_key, payload_dir]
+ common.RunAndCheckOutput(cmd)
+ has_signed_content = True
+
+ return payload_dir, has_signed_content
def RepackApexPayload(self, payload_dir, payload_key, signing_args=None):
"""Rebuilds the apex file with the updated payload directory."""
@@ -310,7 +319,7 @@
def SignUncompressedApex(avbtool, apex_file, payload_key, container_key,
container_pw, apk_keys, codename_to_api_level_map,
- no_hashtree, signing_args=None):
+ no_hashtree, signing_args=None, sign_tool=None):
"""Signs the current uncompressed APEX with the given payload/container keys.
Args:
@@ -322,14 +331,16 @@
codename_to_api_level_map: A dict that maps from codename to API level.
no_hashtree: Don't include hashtree in the signed APEX.
signing_args: Additional args to be passed to the payload signer.
+ sign_tool: A tool to sign the contents of the APEX.
Returns:
The path to the signed APEX file.
"""
- # 1. Extract the apex payload image and sign the containing apk files. Repack
+ # 1. Extract the apex payload image and sign the files (e.g. APKs). Repack
# the apex file after signing.
apk_signer = ApexApkSigner(apex_file, container_pw,
- codename_to_api_level_map)
+ codename_to_api_level_map,
+ avbtool, sign_tool)
apex_file = apk_signer.ProcessApexFile(apk_keys, payload_key, signing_args)
# 2a. Extract and sign the APEX_PAYLOAD_IMAGE entry with the given
@@ -384,7 +395,7 @@
def SignCompressedApex(avbtool, apex_file, payload_key, container_key,
container_pw, apk_keys, codename_to_api_level_map,
- no_hashtree, signing_args=None):
+ no_hashtree, signing_args=None, sign_tool=None):
"""Signs the current compressed APEX with the given payload/container keys.
Args:
@@ -421,7 +432,8 @@
apk_keys,
codename_to_api_level_map,
no_hashtree,
- signing_args)
+ signing_args,
+ sign_tool)
# 3. Compress signed original apex.
compressed_apex_file = common.MakeTempFile(prefix='apex-container-',
@@ -449,7 +461,7 @@
def SignApex(avbtool, apex_data, payload_key, container_key, container_pw,
apk_keys, codename_to_api_level_map,
- no_hashtree, signing_args=None):
+ no_hashtree, signing_args=None, sign_tool=None):
"""Signs the current APEX with the given payload/container keys.
Args:
@@ -485,7 +497,8 @@
codename_to_api_level_map=codename_to_api_level_map,
no_hashtree=no_hashtree,
apk_keys=apk_keys,
- signing_args=signing_args)
+ signing_args=signing_args,
+ sign_tool=sign_tool)
elif apex_type == 'COMPRESSED':
return SignCompressedApex(
avbtool,
@@ -496,7 +509,8 @@
codename_to_api_level_map=codename_to_api_level_map,
no_hashtree=no_hashtree,
apk_keys=apk_keys,
- signing_args=signing_args)
+ signing_args=signing_args,
+ sign_tool=sign_tool)
else:
# TODO(b/172912232): support signing compressed apex
raise ApexInfoError('Unsupported apex type {}'.format(apex_type))
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index d749c9e..8a5d627 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
@@ -330,10 +334,6 @@
build_command.extend(["-C", fs_config])
if "selinux_fc" in prop_dict:
build_command.extend(["-c", prop_dict["selinux_fc"]])
- if "timestamp" in prop_dict:
- build_command.extend(["-T", str(prop_dict["timestamp"])])
- if "uuid" in prop_dict:
- build_command.extend(["-U", prop_dict["uuid"]])
compressor = None
if "erofs_default_compressor" in prop_dict:
compressor = prop_dict["erofs_default_compressor"]
@@ -341,6 +341,16 @@
compressor = prop_dict["erofs_compressor"]
if compressor:
build_command.extend(["-z", compressor])
+ if "timestamp" in prop_dict:
+ build_command.extend(["-T", str(prop_dict["timestamp"])])
+ if "uuid" in prop_dict:
+ build_command.extend(["-U", prop_dict["uuid"]])
+ if "block_list" in prop_dict:
+ build_command.extend(["-B", prop_dict["block_list"]])
+ if "erofs_pcluster_size" in prop_dict:
+ build_command.extend(["-P", prop_dict["erofs_pcluster_size"]])
+ if "erofs_share_dup_blocks" in prop_dict:
+ build_command.extend(["-k", "4096"])
elif fs_type.startswith("squash"):
build_command = ["mksquashfsimage.sh"]
build_command.extend([in_dir, out_file])
@@ -441,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.
@@ -469,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)
@@ -583,7 +662,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.
@@ -615,6 +693,8 @@
common_props = (
"extfs_sparse_flag",
"erofs_default_compressor",
+ "erofs_pcluster_size",
+ "erofs_share_dup_blocks",
"erofs_sparse_flag",
"squashfs_sparse_flag",
"system_f2fs_compress",
@@ -634,252 +714,101 @@
for p in common_props:
copy_prop(p, p)
- suffixed_props = (
- "erofs_compressor",
- )
- for p in suffixed_props:
- copy_prop("{}_{}".format(mount_point, p), p)
+ ro_mount_points = set([
+ "odm",
+ "odm_dlkm",
+ "oem",
+ "product",
+ "system",
+ "system_ext",
+ "system_other",
+ "vendor",
+ "vendor_dlkm",
+ ])
+ # Tuple layout: (readonly, specific prop, general prop)
+ fmt_props = (
+ # Generic first, then specific file type.
+ (False, "fs_type", "fs_type"),
+ (False, "{}_fs_type", "fs_type"),
+
+ # Ordering for these doesn't matter.
+ (False, "{}_selinux_fc", "selinux_fc"),
+ (False, "{}_size", "partition_size"),
+ (True, "avb_{}_add_hashtree_footer_args", "avb_add_hashtree_footer_args"),
+ (True, "avb_{}_algorithm", "avb_algorithm"),
+ (True, "avb_{}_hashtree_enable", "avb_hashtree_enable"),
+ (True, "avb_{}_key_path", "avb_key_path"),
+ (True, "avb_{}_salt", "avb_salt"),
+ (True, "ext4_share_dup_blocks", "ext4_share_dup_blocks"),
+ (True, "{}_base_fs_file", "base_fs_file"),
+ (True, "{}_disable_sparse", "disable_sparse"),
+ (True, "{}_erofs_compressor", "erofs_compressor"),
+ (True, "{}_erofs_pcluster_size", "erofs_pcluster_size"),
+ (True, "{}_erofs_share_dup_blocks", "erofs_share_dup_blocks"),
+ (True, "{}_extfs_inode_count", "extfs_inode_count"),
+ (True, "{}_f2fs_compress", "f2fs_compress"),
+ (True, "{}_f2fs_sldc_flags", "f2fs_sldc_flags"),
+ (True, "{}_reserved_size", "partition_reserved_size"),
+ (True, "{}_squashfs_block_size", "squashfs_block_size"),
+ (True, "{}_squashfs_compressor", "squashfs_compressor"),
+ (True, "{}_squashfs_compressor_opt", "squashfs_compressor_opt"),
+ (True, "{}_squashfs_disable_4k_align", "squashfs_disable_4k_align"),
+ (True, "{}_verity_block_device", "verity_block_device"),
+ )
+
+ # Translate prefixed properties into generic ones.
+ if mount_point == "data":
+ prefix = "userdata"
+ else:
+ prefix = mount_point
+
+ for readonly, src_prop, dest_prop in fmt_props:
+ if readonly and mount_point not in ro_mount_points:
+ continue
+
+ if src_prop == "fs_type":
+ # This property is legacy and only used on a few partitions. b/202600377
+ allowed_partitions = set(["system", "system_other", "data", "oem"])
+ if mount_point not in allowed_partitions:
+ continue
+
+ if mount_point == "system_other":
+ # Propagate system properties to system_other. They'll get overridden
+ # after as needed.
+ copy_prop(src_prop.format("system"), dest_prop)
+
+ copy_prop(src_prop.format(prefix), dest_prop)
+
+ # Set prefixed properties that need a default value.
+ if mount_point in ro_mount_points:
+ prop = "{}_journal_size".format(prefix)
+ if not copy_prop(prop, "journal_size"):
+ d["journal_size"] = "0"
+
+ prop = "{}_extfs_rsv_pct".format(prefix)
+ if not copy_prop(prop, "extfs_rsv_pct"):
+ d["extfs_rsv_pct"] = "0"
+
+ # Copy partition-specific properties.
d["mount_point"] = mount_point
if mount_point == "system":
- copy_prop("avb_system_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_system_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_system_key_path", "avb_key_path")
- copy_prop("avb_system_algorithm", "avb_algorithm")
- copy_prop("avb_system_salt", "avb_salt")
- copy_prop("fs_type", "fs_type")
- # Copy the generic system fs type first, override with specific one if
- # available.
- copy_prop("system_fs_type", "fs_type")
copy_prop("system_headroom", "partition_headroom")
- copy_prop("system_size", "partition_size")
- if not copy_prop("system_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("system_verity_block_device", "verity_block_device")
copy_prop("system_root_image", "system_root_image")
copy_prop("root_dir", "root_dir")
copy_prop("root_fs_config", "root_fs_config")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("system_f2fs_compress", "f2fs_compress")
- copy_prop("system_f2fs_sldc_flags", "f2fs_sldc_flags")
- copy_prop("system_squashfs_compressor", "squashfs_compressor")
- copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
- copy_prop("system_squashfs_block_size", "squashfs_block_size")
- copy_prop("system_squashfs_disable_4k_align", "squashfs_disable_4k_align")
- copy_prop("system_base_fs_file", "base_fs_file")
- copy_prop("system_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("system_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("system_reserved_size", "partition_reserved_size")
- copy_prop("system_selinux_fc", "selinux_fc")
- copy_prop("system_disable_sparse", "disable_sparse")
- elif mount_point == "system_other":
- # We inherit the selinux policies of /system since we contain some of its
- # files.
- copy_prop("avb_system_other_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_system_other_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_system_other_key_path", "avb_key_path")
- copy_prop("avb_system_other_algorithm", "avb_algorithm")
- copy_prop("avb_system_other_salt", "avb_salt")
- copy_prop("fs_type", "fs_type")
- copy_prop("system_fs_type", "fs_type")
- copy_prop("system_other_size", "partition_size")
- if not copy_prop("system_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("system_verity_block_device", "verity_block_device")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("system_f2fs_compress", "f2fs_compress")
- copy_prop("system_f2fs_sldc_flags", "f2fs_sldc_flags")
- copy_prop("system_squashfs_compressor", "squashfs_compressor")
- copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
- copy_prop("system_squashfs_block_size", "squashfs_block_size")
- copy_prop("system_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("system_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("system_reserved_size", "partition_reserved_size")
- copy_prop("system_selinux_fc", "selinux_fc")
- copy_prop("system_disable_sparse", "disable_sparse")
+ 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("fs_type", "fs_type")
- copy_prop("userdata_fs_type", "fs_type")
- copy_prop("userdata_size", "partition_size")
copy_prop("flash_logical_block_size", "flash_logical_block_size")
copy_prop("flash_erase_block_size", "flash_erase_block_size")
- copy_prop("userdata_selinux_fc", "selinux_fc")
copy_prop("needs_casefold", "needs_casefold")
copy_prop("needs_projid", "needs_projid")
copy_prop("needs_compress", "needs_compress")
- elif mount_point == "cache":
- copy_prop("cache_fs_type", "fs_type")
- copy_prop("cache_size", "partition_size")
- copy_prop("cache_selinux_fc", "selinux_fc")
- elif mount_point == "vendor":
- copy_prop("avb_vendor_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_vendor_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_vendor_key_path", "avb_key_path")
- copy_prop("avb_vendor_algorithm", "avb_algorithm")
- copy_prop("avb_vendor_salt", "avb_salt")
- copy_prop("vendor_fs_type", "fs_type")
- copy_prop("vendor_size", "partition_size")
- if not copy_prop("vendor_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("vendor_verity_block_device", "verity_block_device")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("vendor_f2fs_compress", "f2fs_compress")
- copy_prop("vendor_f2fs_sldc_flags", "f2fs_sldc_flags")
- copy_prop("vendor_squashfs_compressor", "squashfs_compressor")
- copy_prop("vendor_squashfs_compressor_opt", "squashfs_compressor_opt")
- copy_prop("vendor_squashfs_block_size", "squashfs_block_size")
- copy_prop("vendor_squashfs_disable_4k_align", "squashfs_disable_4k_align")
- copy_prop("vendor_base_fs_file", "base_fs_file")
- copy_prop("vendor_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("vendor_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("vendor_reserved_size", "partition_reserved_size")
- copy_prop("vendor_selinux_fc", "selinux_fc")
- copy_prop("vendor_disable_sparse", "disable_sparse")
- elif mount_point == "product":
- copy_prop("avb_product_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_product_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_product_key_path", "avb_key_path")
- copy_prop("avb_product_algorithm", "avb_algorithm")
- copy_prop("avb_product_salt", "avb_salt")
- copy_prop("product_fs_type", "fs_type")
- copy_prop("product_size", "partition_size")
- if not copy_prop("product_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("product_verity_block_device", "verity_block_device")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("product_f2fs_compress", "f2fs_compress")
- copy_prop("product_f2fs_sldc_flags", "f2fs_sldc_flags")
- copy_prop("product_squashfs_compressor", "squashfs_compressor")
- copy_prop("product_squashfs_compressor_opt", "squashfs_compressor_opt")
- copy_prop("product_squashfs_block_size", "squashfs_block_size")
- copy_prop("product_squashfs_disable_4k_align", "squashfs_disable_4k_align")
- copy_prop("product_base_fs_file", "base_fs_file")
- copy_prop("product_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("product_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("product_reserved_size", "partition_reserved_size")
- copy_prop("product_selinux_fc", "selinux_fc")
- copy_prop("product_disable_sparse", "disable_sparse")
- elif mount_point == "system_ext":
- copy_prop("avb_system_ext_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_system_ext_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_system_ext_key_path", "avb_key_path")
- copy_prop("avb_system_ext_algorithm", "avb_algorithm")
- copy_prop("avb_system_ext_salt", "avb_salt")
- copy_prop("system_ext_fs_type", "fs_type")
- copy_prop("system_ext_size", "partition_size")
- if not copy_prop("system_ext_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("system_ext_verity_block_device", "verity_block_device")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("system_ext_f2fs_compress", "f2fs_compress")
- copy_prop("system_ext_f2fs_sldc_flags", "f2fs_sldc_flags")
- copy_prop("system_ext_squashfs_compressor", "squashfs_compressor")
- copy_prop("system_ext_squashfs_compressor_opt",
- "squashfs_compressor_opt")
- copy_prop("system_ext_squashfs_block_size", "squashfs_block_size")
- copy_prop("system_ext_squashfs_disable_4k_align",
- "squashfs_disable_4k_align")
- copy_prop("system_ext_base_fs_file", "base_fs_file")
- copy_prop("system_ext_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("system_ext_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("system_ext_reserved_size", "partition_reserved_size")
- copy_prop("system_ext_selinux_fc", "selinux_fc")
- copy_prop("system_ext_disable_sparse", "disable_sparse")
- elif mount_point == "odm":
- copy_prop("avb_odm_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_odm_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_odm_key_path", "avb_key_path")
- copy_prop("avb_odm_algorithm", "avb_algorithm")
- copy_prop("avb_odm_salt", "avb_salt")
- copy_prop("odm_fs_type", "fs_type")
- copy_prop("odm_size", "partition_size")
- if not copy_prop("odm_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("odm_verity_block_device", "verity_block_device")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("odm_squashfs_compressor", "squashfs_compressor")
- copy_prop("odm_squashfs_compressor_opt", "squashfs_compressor_opt")
- copy_prop("odm_squashfs_block_size", "squashfs_block_size")
- copy_prop("odm_squashfs_disable_4k_align", "squashfs_disable_4k_align")
- copy_prop("odm_base_fs_file", "base_fs_file")
- copy_prop("odm_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("odm_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("odm_reserved_size", "partition_reserved_size")
- copy_prop("odm_selinux_fc", "selinux_fc")
- copy_prop("odm_disable_sparse", "disable_sparse")
- elif mount_point == "vendor_dlkm":
- copy_prop("avb_vendor_dlkm_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_vendor_dlkm_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_vendor_dlkm_key_path", "avb_key_path")
- copy_prop("avb_vendor_dlkm_algorithm", "avb_algorithm")
- copy_prop("avb_vendor_dlkm_salt", "avb_salt")
- copy_prop("vendor_dlkm_fs_type", "fs_type")
- copy_prop("vendor_dlkm_size", "partition_size")
- copy_prop("vendor_dlkm_f2fs_compress", "f2fs_compress")
- copy_prop("vendor_dlkm_f2fs_sldc_flags", "f2fs_sldc_flags")
- if not copy_prop("vendor_dlkm_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("vendor_dlkm_verity_block_device", "verity_block_device")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("vendor_dlkm_squashfs_compressor", "squashfs_compressor")
- copy_prop("vendor_dlkm_squashfs_compressor_opt", "squashfs_compressor_opt")
- copy_prop("vendor_dlkm_squashfs_block_size", "squashfs_block_size")
- copy_prop("vendor_dlkm_squashfs_disable_4k_align", "squashfs_disable_4k_align")
- copy_prop("vendor_dlkm_base_fs_file", "base_fs_file")
- copy_prop("vendor_dlkm_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("vendor_dlkm_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("vendor_dlkm_reserved_size", "partition_reserved_size")
- copy_prop("vendor_dlkm_selinux_fc", "selinux_fc")
- copy_prop("vendor_dlkm_disable_sparse", "disable_sparse")
- elif mount_point == "odm_dlkm":
- copy_prop("avb_odm_dlkm_hashtree_enable", "avb_hashtree_enable")
- copy_prop("avb_odm_dlkm_add_hashtree_footer_args",
- "avb_add_hashtree_footer_args")
- copy_prop("avb_odm_dlkm_key_path", "avb_key_path")
- copy_prop("avb_odm_dlkm_algorithm", "avb_algorithm")
- copy_prop("avb_odm_dlkm_salt", "avb_salt")
- copy_prop("odm_dlkm_fs_type", "fs_type")
- copy_prop("odm_dlkm_size", "partition_size")
- if not copy_prop("odm_dlkm_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("odm_dlkm_verity_block_device", "verity_block_device")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- copy_prop("odm_dlkm_squashfs_compressor", "squashfs_compressor")
- copy_prop("odm_dlkm_squashfs_compressor_opt", "squashfs_compressor_opt")
- copy_prop("odm_dlkm_squashfs_block_size", "squashfs_block_size")
- copy_prop("odm_dlkm_squashfs_disable_4k_align", "squashfs_disable_4k_align")
- copy_prop("odm_dlkm_base_fs_file", "base_fs_file")
- copy_prop("odm_dlkm_extfs_inode_count", "extfs_inode_count")
- if not copy_prop("odm_dlkm_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("odm_dlkm_reserved_size", "partition_reserved_size")
- copy_prop("odm_dlkm_selinux_fc", "selinux_fc")
- copy_prop("odm_dlkm_disable_sparse", "disable_sparse")
- elif mount_point == "oem":
- copy_prop("fs_type", "fs_type")
- copy_prop("oem_size", "partition_size")
- if not copy_prop("oem_journal_size", "journal_size"):
- d["journal_size"] = "0"
- copy_prop("oem_extfs_inode_count", "extfs_inode_count")
- copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
- if not copy_prop("oem_extfs_rsv_pct", "extfs_rsv_pct"):
- d["extfs_rsv_pct"] = "0"
- copy_prop("oem_selinux_fc", "selinux_fc")
d["partition_name"] = mount_point
return d
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 5affa32..1533030 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -2105,9 +2105,11 @@
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:
+ if k in SPECIAL_CERT_STRINGS or k is None:
no_passwords.append(k)
continue
@@ -3953,3 +3955,10 @@
OPTIONS.replace_updated_files_list.append(care_map_path)
else:
ZipWrite(output_file, temp_care_map, arcname=care_map_path)
+
+
+def IsSparseImage(filepath):
+ with open(filepath, 'rb') as fp:
+ # Magic for android sparse image format
+ # https://source.android.com/devices/bootloader/images
+ return fp.read(4) == b'\x3A\xFF\x26\xED'
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 4eb2f0c..e99152a 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -227,6 +227,9 @@
--force_minor_version
Override the update_engine minor version for delta generation.
+
+ --compressor_types
+ A colon ':' separated list of compressors. Allowed values are bz2 and brotli.
"""
from __future__ import print_function
@@ -248,6 +251,7 @@
import ota_utils
from ota_utils import (UNZIP_PATTERN, FinalizeMetadata, GetPackageMetadata,
PropertyFiles, SECURITY_PATCH_LEVEL_PROP_NAME, GetZipEntryOffset)
+from common import IsSparseImage
import target_files_diff
from check_target_files_vintf import CheckVintfIfTrebleEnabled
from non_ab_ota import GenerateNonAbOtaPackage
@@ -294,6 +298,7 @@
OPTIONS.vabc_downgrade = False
OPTIONS.enable_vabc_xor = True
OPTIONS.force_minor_version = None
+OPTIONS.compressor_types = None
POSTINSTALL_CONFIG = 'META/postinstall_config.txt'
DYNAMIC_PARTITION_INFO = 'META/dynamic_partitions_info.txt'
@@ -1017,13 +1022,6 @@
]
-def IsSparseImage(filepath):
- with open(filepath, 'rb') as fp:
- # Magic for android sparse image format
- # https://source.android.com/devices/bootloader/images
- return fp.read(4) == b'\x3A\xFF\x26\xED'
-
-
def SupportsMainlineGkiUpdates(target_file):
"""Return True if the build supports MainlineGKIUpdates.
@@ -1149,6 +1147,8 @@
additional_args += ["--enable_vabc_xor", "true"]
if OPTIONS.force_minor_version:
additional_args += ["--force_minor_version", OPTIONS.force_minor_version]
+ if OPTIONS.compressor_types:
+ additional_args += ["--compressor_types", OPTIONS.compressor_types]
additional_args += ["--max_timestamp", max_timestamp]
if SupportsMainlineGkiUpdates(source_file):
@@ -1191,6 +1191,8 @@
care_map_list = [x for x in ["care_map.pb", "care_map.txt"] if
"META/" + x in target_zip.namelist()]
+ # TODO(b/205541521) remove the workaround after root cause is fixed.
+ care_map_list = []
# Adds care_map if either the protobuf format or the plain text one exists.
if care_map_list:
care_map_name = care_map_list[0]
@@ -1324,6 +1326,8 @@
OPTIONS.enable_vabc_xor = a.lower() != "false"
elif o == "--force_minor_version":
OPTIONS.force_minor_version = a
+ elif o == "--compressor_types":
+ OPTIONS.compressor_types = a
else:
return False
return True
@@ -1370,6 +1374,7 @@
"vabc_downgrade",
"enable_vabc_xor=",
"force_minor_version=",
+ "compressor_types=",
], extra_option_handler=option_handler)
if len(args) != 2:
@@ -1401,8 +1406,8 @@
# We should only allow downgrading incrementals (as opposed to full).
# Otherwise the device may go back from arbitrary build with this full
# OTA package.
- if OPTIONS.incremental_source is None:
- raise ValueError("Cannot generate downgradable full OTAs")
+ if OPTIONS.incremental_source is None and OPTIONS.downgrade:
+ raise ValueError("Cannot generate downgradable full OTAs")
# TODO(xunchang) for retrofit and partial updates, maybe we should rebuild the
# target-file and reload the info_dict. So the info will be consistent with
@@ -1470,13 +1475,18 @@
"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.signapk_path:
+ 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)
+ )
if OPTIONS.source_info_dict:
source_build_prop = OPTIONS.source_info_dict["build.prop"]
@@ -1528,8 +1538,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/sign_apex.py b/tools/releasetools/sign_apex.py
index fb947f4..679f57a 100755
--- a/tools/releasetools/sign_apex.py
+++ b/tools/releasetools/sign_apex.py
@@ -39,6 +39,9 @@
--codename_to_api_level_map Q:29,R:30,...
A Mapping of codename to api level. This is useful to provide sdk targeting
information to APK Signer.
+
+ --sign_tool <sign_tool>
+ Optional flag that specifies a custom signing tool for the contents of the apex.
"""
import logging
@@ -52,7 +55,7 @@
def SignApexFile(avbtool, apex_file, payload_key, container_key, no_hashtree,
- apk_keys=None, signing_args=None, codename_to_api_level_map=None):
+ apk_keys=None, signing_args=None, codename_to_api_level_map=None, sign_tool=None):
"""Signs the given apex file."""
with open(apex_file, 'rb') as input_fp:
apex_data = input_fp.read()
@@ -66,7 +69,8 @@
codename_to_api_level_map=codename_to_api_level_map,
no_hashtree=no_hashtree,
apk_keys=apk_keys,
- signing_args=signing_args)
+ signing_args=signing_args,
+ sign_tool=sign_tool)
def main(argv):
@@ -100,6 +104,8 @@
if 'extra_apks' not in options:
options['extra_apks'] = {}
options['extra_apks'].update({n: key})
+ elif o == '--sign_tool':
+ options['sign_tool'] = a
else:
return False
return True
@@ -114,6 +120,7 @@
'payload_extra_args=',
'payload_key=',
'extra_apks=',
+ 'sign_tool=',
],
extra_option_handler=option_handler)
@@ -133,7 +140,8 @@
apk_keys=options.get('extra_apks', {}),
signing_args=options.get('payload_extra_args'),
codename_to_api_level_map=options.get(
- 'codename_to_api_level_map', {}))
+ 'codename_to_api_level_map', {}),
+ sign_tool=options['sign_tool'])
shutil.copyfile(signed_apex, args[1])
logger.info("done.")
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index d219ed6..5626980 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -136,6 +136,11 @@
--android_jar_path <path>
Path to the android.jar to repack the apex file.
+
+ --allow_gsi_debug_sepolicy
+ Allow the existence of the file 'userdebug_plat_sepolicy.cil' under
+ (/system/system_ext|/system_ext)/etc/selinux.
+ If not set, error out when the file exists.
"""
from __future__ import print_function
@@ -191,6 +196,7 @@
OPTIONS.android_jar_path = None
OPTIONS.vendor_partitions = set()
OPTIONS.vendor_otatools = None
+OPTIONS.allow_gsi_debug_sepolicy = False
AVB_FOOTER_ARGS_BY_PARTITION = {
@@ -256,7 +262,7 @@
Args:
keys_info: A dict that maps from APEX filenames to a tuple of (payload_key,
- container_key).
+ container_key, sign_tool).
key_map: A dict that overrides the keys, specified via command-line input.
Returns:
@@ -274,11 +280,11 @@
if apex not in keys_info:
logger.warning('Failed to find %s in target_files; Ignored', apex)
continue
- keys_info[apex] = (key, keys_info[apex][1])
+ keys_info[apex] = (key, keys_info[apex][1], keys_info[apex][2])
# Apply the key remapping to container keys.
- for apex, (payload_key, container_key) in keys_info.items():
- keys_info[apex] = (payload_key, key_map.get(container_key, container_key))
+ for apex, (payload_key, container_key, sign_tool) in keys_info.items():
+ keys_info[apex] = (payload_key, key_map.get(container_key, container_key), sign_tool)
# Apply all the --extra_apks options to override the container keys.
for apex, key in OPTIONS.extra_apks.items():
@@ -287,13 +293,13 @@
continue
if not key:
key = 'PRESIGNED'
- keys_info[apex] = (keys_info[apex][0], key_map.get(key, key))
+ keys_info[apex] = (keys_info[apex][0], key_map.get(key, key), keys_info[apex][2])
# A PRESIGNED container entails a PRESIGNED payload. Apply this to all the
# APEX key pairs. However, a PRESIGNED container with non-PRESIGNED payload
# (overridden via commandline) indicates a config error, which should not be
# allowed.
- for apex, (payload_key, container_key) in keys_info.items():
+ for apex, (payload_key, container_key, sign_tool) in keys_info.items():
if container_key != 'PRESIGNED':
continue
if apex in OPTIONS.extra_apex_payload_keys:
@@ -305,7 +311,7 @@
print(
"Setting {} payload as PRESIGNED due to PRESIGNED container".format(
apex))
- keys_info[apex] = ('PRESIGNED', 'PRESIGNED')
+ keys_info[apex] = ('PRESIGNED', 'PRESIGNED', None)
return keys_info
@@ -366,7 +372,7 @@
compressed_extension: The extension string of compressed APKs, such as
'.gz', or None if there's no compressed APKs.
apex_keys: A dict that contains the key mapping from APEX name to
- (payload_key, container_key).
+ (payload_key, container_key, sign_tool).
Raises:
AssertionError: On finding unknown APKs and APEXes.
@@ -411,7 +417,7 @@
name = GetApexFilename(info.filename)
- (payload_key, container_key) = apex_keys[name]
+ (payload_key, container_key, _) = apex_keys[name]
if ((payload_key in common.SPECIAL_CERT_STRINGS and
container_key not in common.SPECIAL_CERT_STRINGS) or
(payload_key not in common.SPECIAL_CERT_STRINGS and
@@ -563,7 +569,7 @@
elif IsApexFile(filename):
name = GetApexFilename(filename)
- payload_key, container_key = apex_keys[name]
+ payload_key, container_key, sign_tool = apex_keys[name]
# We've asserted not having a case with only one of them PRESIGNED.
if (payload_key not in common.SPECIAL_CERT_STRINGS and
@@ -582,7 +588,8 @@
apk_keys,
codename_to_api_level_map,
no_hashtree=None, # Let apex_util determine if hash tree is needed
- signing_args=OPTIONS.avb_extra_args.get('apex'))
+ signing_args=OPTIONS.avb_extra_args.get('apex'),
+ sign_tool=sign_tool)
common.ZipWrite(output_tf_zip, signed_apex, filename)
else:
@@ -664,7 +671,7 @@
# Updates system_other.avbpubkey in /product/etc/.
elif filename in (
"PRODUCT/etc/security/avb/system_other.avbpubkey",
- "SYSTEM/product/etc/security/avb/system_other.avbpubkey"):
+ "SYSTEM/product/etc/security/avb/system_other.avbpubkey"):
# Only update system_other's public key, if the corresponding signing
# key is specified via --avb_system_other_key.
signing_key = OPTIONS.avb_keys.get("system_other")
@@ -677,9 +684,19 @@
# Should NOT sign boot-debug.img.
elif filename in (
"BOOT/RAMDISK/force_debuggable",
- "BOOT/RAMDISK/first_stage_ramdisk/force_debuggable"):
+ "BOOT/RAMDISK/first_stage_ramdisk/force_debuggable"):
raise common.ExternalError("debuggable boot.img cannot be signed")
+ # Should NOT sign userdebug sepolicy file.
+ elif filename in (
+ "SYSTEM_EXT/etc/selinux/userdebug_plat_sepolicy.cil",
+ "SYSTEM/system_ext/etc/selinux/userdebug_plat_sepolicy.cil"):
+ if not OPTIONS.allow_gsi_debug_sepolicy:
+ raise common.ExternalError("debug sepolicy shouldn't be included")
+ else:
+ # Copy it verbatim if we allow the file to exist.
+ common.ZipWriteStr(output_tf_zip, out_info, data)
+
# A non-APK file; copy it verbatim.
else:
common.ZipWriteStr(output_tf_zip, out_info, data)
@@ -1131,15 +1148,16 @@
Given a target-files ZipFile, parses the META/apexkeys.txt entry and returns a
dict that contains the mapping from APEX names (e.g. com.android.tzdata) to a
- tuple of (payload_key, container_key).
+ tuple of (payload_key, container_key, sign_tool).
Args:
tf_zip: The input target_files ZipFile (already open).
Returns:
- (payload_key, container_key): payload_key contains the path to the payload
- signing key; container_key contains the path to the container signing
- key.
+ (payload_key, container_key, sign_tool):
+ - payload_key contains the path to the payload signing key
+ - container_key contains the path to the container signing key
+ - sign_tool is an apex-specific signing tool for its payload contents
"""
keys = {}
for line in tf_zip.read('META/apexkeys.txt').decode().split('\n'):
@@ -1152,7 +1170,8 @@
r'private_key="(?P<PAYLOAD_PRIVATE_KEY>.*)"\s+'
r'container_certificate="(?P<CONTAINER_CERT>.*)"\s+'
r'container_private_key="(?P<CONTAINER_PRIVATE_KEY>.*?)"'
- r'(\s+partition="(?P<PARTITION>.*?)")?$',
+ r'(\s+partition="(?P<PARTITION>.*?)")?'
+ r'(\s+sign_tool="(?P<SIGN_TOOL>.*?)")?$',
line)
if not matches:
continue
@@ -1181,7 +1200,8 @@
else:
raise ValueError("Failed to parse container keys: \n{}".format(line))
- keys[name] = (payload_private_key, container_key)
+ sign_tool = matches.group("SIGN_TOOL")
+ keys[name] = (payload_private_key, container_key, sign_tool)
return keys
@@ -1356,6 +1376,8 @@
OPTIONS.vendor_otatools = a
elif o == "--vendor_partitions":
OPTIONS.vendor_partitions = set(a.split(","))
+ elif o == "--allow_gsi_debug_sepolicy":
+ OPTIONS.allow_gsi_debug_sepolicy = True
else:
return False
return True
@@ -1408,6 +1430,7 @@
"gki_signing_extra_args=",
"vendor_partitions=",
"vendor_otatools=",
+ "allow_gsi_debug_sepolicy",
],
extra_option_handler=option_handler)
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/releasetools/test_apex_utils.py b/tools/releasetools/test_apex_utils.py
index 71f6433..ed920f2 100644
--- a/tools/releasetools/test_apex_utils.py
+++ b/tools/releasetools/test_apex_utils.py
@@ -187,3 +187,19 @@
self.payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
signer.ProcessApexFile(apk_keys, self.payload_key)
+
+ @test_utils.SkipIfExternalToolsUnavailable()
+ def test_ApexApkSigner_invokesCustomSignTool(self):
+ apex_path = common.MakeTempFile(suffix='.apex')
+ shutil.copy(self.apex_with_apk, apex_path)
+ apk_keys = {'wifi-service-resources.apk': os.path.join(
+ self.testdata_dir, 'testkey')}
+ self.payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
+
+ # pass `false` as a sign_tool to see the invocation error
+ with self.assertRaises(common.ExternalError) as cm:
+ signer = apex_utils.ApexApkSigner(apex_path, None, None, sign_tool='false')
+ signer.ProcessApexFile(apk_keys, self.payload_key)
+
+ the_exception = cm.exception
+ self.assertIn('Failed to run command \'[\'false\'', the_exception.message)
diff --git a/tools/releasetools/test_build_image.py b/tools/releasetools/test_build_image.py
index b24805f..cfae7a5 100644
--- a/tools/releasetools/test_build_image.py
+++ b/tools/releasetools/test_build_image.py
@@ -196,7 +196,7 @@
p.communicate()
self.assertEqual(0, p.returncode)
- fs_dict = GetFilesystemCharacteristics(output_file)
+ fs_dict = GetFilesystemCharacteristics('ext4', output_file)
self.assertEqual(int(fs_dict['Block size']), 4096)
self.assertGreaterEqual(int(fs_dict['Free blocks']), 0) # expect ~88
self.assertGreater(int(fs_dict['Inode count']), 0) # expect ~64
diff --git a/tools/releasetools/test_sign_apex.py b/tools/releasetools/test_sign_apex.py
index 646b04d..8470f20 100644
--- a/tools/releasetools/test_sign_apex.py
+++ b/tools/releasetools/test_sign_apex.py
@@ -69,5 +69,5 @@
payload_key,
container_key,
False,
- codename_to_api_level_map={'S': 31})
+ codename_to_api_level_map={'S': 31, 'Tiramisu' : 32})
self.assertTrue(os.path.exists(signed_apex))
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index ad9e657..92dca9a 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -328,23 +328,23 @@
'Apex3.apex' : 'key3',
}
apex_keys = {
- 'Apex1.apex' : ('payload-key1', 'container-key1'),
- 'Apex2.apex' : ('payload-key2', 'container-key2'),
+ 'Apex1.apex' : ('payload-key1', 'container-key1', None),
+ 'Apex2.apex' : ('payload-key2', 'container-key2', None),
}
with zipfile.ZipFile(input_file) as input_zip:
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
# Fine to have both keys as PRESIGNED.
- apex_keys['Apex2.apex'] = ('PRESIGNED', 'PRESIGNED')
+ apex_keys['Apex2.apex'] = ('PRESIGNED', 'PRESIGNED', None)
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
# Having only one of them as PRESIGNED is not allowed.
- apex_keys['Apex2.apex'] = ('payload-key2', 'PRESIGNED')
+ apex_keys['Apex2.apex'] = ('payload-key2', 'PRESIGNED', None)
self.assertRaises(
AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
None, apex_keys)
- apex_keys['Apex2.apex'] = ('PRESIGNED', 'container-key1')
+ apex_keys['Apex2.apex'] = ('PRESIGNED', 'container-key1', None)
self.assertRaises(
AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
None, apex_keys)
@@ -475,10 +475,10 @@
self.assertEqual({
'apex.apexd_test.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
'apex.apexd_test_different_app.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
}, keys_info)
def test_ReadApexKeysInfo_mismatchingContainerKeys(self):
@@ -514,10 +514,10 @@
self.assertEqual({
'apex.apexd_test.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
'apex.apexd_test_different_app.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
}, keys_info)
def test_ReadApexKeysInfo_missingPayloadPublicKey(self):
@@ -537,10 +537,10 @@
self.assertEqual({
'apex.apexd_test.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
'apex.apexd_test_different_app.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
}, keys_info)
def test_ReadApexKeysInfo_presignedKeys(self):
@@ -560,10 +560,10 @@
self.assertEqual({
'apex.apexd_test.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
'apex.apexd_test_different_app.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
}, keys_info)
def test_ReadApexKeysInfo_presignedKeys(self):
@@ -583,10 +583,10 @@
self.assertEqual({
'apex.apexd_test.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
'apex.apexd_test_different_app.apex': (
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
- 'build/make/target/product/security/testkey'),
+ 'build/make/target/product/security/testkey', None),
}, keys_info)
def test_ReplaceGkiSigningKey(self):
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index 622e57f..282dc99 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -36,7 +36,9 @@
import os.path
import re
import zipfile
+
from hashlib import sha1
+from common import IsSparseImage
import common
import rangelib
@@ -71,10 +73,16 @@
def CheckAllFiles(which):
logging.info('Checking %s image.', which)
- # Allow having shared blocks when loading the sparse image, because allowing
- # that doesn't affect the checks below (we will have all the blocks on file,
- # unless it's skipped due to the holes).
- image = common.GetSparseImage(which, input_tmp, input_zip, True)
+ path = os.path.join(input_tmp, "IMAGES", which + ".img")
+ if not IsSparseImage(path):
+ logging.info("%s is non-sparse image", which)
+ image = common.GetNonSparseImage(which, input_tmp)
+ else:
+ logging.info("%s is sparse image", which)
+ # Allow having shared blocks when loading the sparse image, because allowing
+ # that doesn't affect the checks below (we will have all the blocks on file,
+ # unless it's skipped due to the holes).
+ image = common.GetSparseImage(which, input_tmp, input_zip, True)
prefix = '/' + which
for entry in image.file_map:
# Skip entries like '__NONZERO-0'.
diff --git a/tools/warn/cpp_warn_patterns.py b/tools/warn/cpp_warn_patterns.py
index b738086..1e1aa43 100644
--- a/tools/warn/cpp_warn_patterns.py
+++ b/tools/warn/cpp_warn_patterns.py
@@ -297,6 +297,7 @@
[r".*: warning: declaration 'class .+' does not declare anything"]),
medium('Initialization order will be different',
[r".*: warning: '.+' will be initialized after",
+ r".*: warning: initializer order does not match the declaration order",
r".*: warning: field .+ will be initialized after .+Wreorder"]),
skip('skip, ....',
[r".*: warning: '.+'"]),
@@ -448,6 +449,7 @@
[r".*: warning: 'operator new' must not return NULL unless it is declared 'throw\(\)' .+"]),
medium('NULL used in arithmetic',
[r".*: warning: NULL used in arithmetic",
+ r".*: warning: .* subtraction with a null pointer",
r".*: warning: comparison between NULL and non-pointer"]),
medium('Misspelled header guard',
[r".*: warning: '.+' is used as a header guard .+ followed by .+ different macro"]),
diff --git a/tools/warn/tidy_warn_patterns.py b/tools/warn/tidy_warn_patterns.py
index 1297966..a5842ea 100644
--- a/tools/warn/tidy_warn_patterns.py
+++ b/tools/warn/tidy_warn_patterns.py
@@ -81,6 +81,7 @@
warn_patterns = [
# pylint does not recognize g-inconsistent-quotes
# pylint:disable=line-too-long,bad-option-value,g-inconsistent-quotes
+ group_tidy_warn_pattern('altera'),
group_tidy_warn_pattern('android'),
simple_tidy_warn_pattern('abseil-string-find-startswith'),
simple_tidy_warn_pattern('bugprone-argument-comment'),
@@ -127,8 +128,9 @@
simple_tidy_warn_pattern('cert-oop54-cpp'),
group_tidy_warn_pattern('cert'),
group_tidy_warn_pattern('clang-diagnostic'),
+ group_tidy_warn_pattern('concurrency'),
group_tidy_warn_pattern('cppcoreguidelines'),
- group_tidy_warn_pattern('llvm'),
+ group_tidy_warn_pattern('fuchsia'),
simple_tidy_warn_pattern('google-default-arguments'),
simple_tidy_warn_pattern('google-runtime-int'),
simple_tidy_warn_pattern('google-runtime-operator'),
@@ -152,8 +154,10 @@
simple_tidy_warn_pattern('hicpp-noexcept-move'),
simple_tidy_warn_pattern('hicpp-use-override'),
group_tidy_warn_pattern('hicpp'),
- group_tidy_warn_pattern('modernize'),
+ group_tidy_warn_pattern('llvm'),
+ group_tidy_warn_pattern('llvmlibc'),
group_tidy_warn_pattern('misc'),
+ group_tidy_warn_pattern('modernize'),
simple_tidy_warn_pattern('performance-faster-string-find'),
simple_tidy_warn_pattern('performance-for-range-copy'),
simple_tidy_warn_pattern('performance-implicit-cast-in-loop'),
@@ -173,6 +177,7 @@
group_tidy_warn_pattern('portability'),
tidy_warn('TIMEOUT', [r".*: warning: clang-tidy aborted "]),
+ tidy_warn('Long Runs', [r".*: warning: clang-tidy used "]),
# warnings from clang-tidy's clang-analyzer checks
analyzer_high('clang-analyzer-core, null pointer',