Fix the broken script in AssertFingerprintOrThumbprint. am: 9c6ab6c49b
am: aeb3125ac3
Change-Id: I47c97314269744576844861badacc2736a3efa36
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..a1455d4
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,8 @@
+LOCAL_PATH := $(call my-dir)
+
+# We're relocating the build project to a subdirectory, then using symlinks
+# to expose the subdirectories where they used to be. If the manifest hasn't
+# been updated, we need to include all the subdirectories.
+ifeq ($(LOCAL_PATH),build)
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/CleanSpec.mk b/CleanSpec.mk
index a97c71a..b955e25 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -378,6 +378,48 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/*)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/previous_overlays.txt)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/current_packages.txt)
+
+$(call add-clean-step, rm -rf $(HOST_OUT_INTERMEDIATES)/include)
+
+$(call add-clean-step, rm -rf $(HOST_OUT_COMMON_INTERMEDIATES)/APPS/*_intermediates/src)
+$(call add-clean-step, rm -rf $(HOST_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/previous_gen_java_config.mk)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/current_gen_java_config.mk)
+
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/*/package-res.apk)
+$(call add-clean-step, rm -rf $(TARGET_OUT_INTERMEDIATES)/APPS/*/package-res.apk)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/*_intermediates/src)
+$(call add-clean-step, rm -rf $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/*_intermediates/src)
+
+$(call add-clean-step, rm -rf $(HOST_OUT_TESTCASES))
+$(call add-clean-step, rm -rf $(TARGET_OUT_TESTCASES))
+
+$(call add-clean-step, rm -rf $(TARGET_OUT_ETC)/init)
+
+# Libraries are moved from {system|vendor}/lib to ./lib/framework, ./lib/vndk, etc.
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/vendor/lib*)
+
+# Revert that move
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/vendor/lib*)
+
+# Sanitized libraries now live in a different location.
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/lib*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/vendor/lib*)
+
+# Soong module variant change, remove obsolete intermediates
+$(call add-clean-step, rm -rf $(OUT_DIR)/soong/.intermediates)
+
+# Version checking moving to Soong
+$(call add-clean-step, rm -rf $(OUT_DIR)/versions_checked.mk)
+
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/buildspec.mk.default b/buildspec.mk.default
index d14208e..b31578a 100644
--- a/buildspec.mk.default
+++ b/buildspec.mk.default
@@ -36,6 +36,12 @@
#TARGET_BUILD_VARIANT:=eng
endif
+# Choose a targeted release. If you don't pick one, the default is the
+# soonest future release.
+ifndef TARGET_PLATFORM_RELEASE
+#TARGET_PLATFORM_RELEASE:=OPR1
+endif
+
# Choose additional targets to always install, even when building
# minimal targets like "make droid". This takes simple target names
# like "Browser" or "MyApp", the names used by LOCAL_MODULE or
@@ -61,9 +67,6 @@
# will be added to LOCAL_CFLAGS when building the module.
#DEBUG_MODULE_ModuleName:=true
-# Specify an alternative tool chain prefix if needed.
-#TARGET_TOOLS_PREFIX:=
-
# Specify the extra CFLAGS to use when building a module whose
# DEBUG_MODULE_ variable is set. Host and device flags are handled
# separately.
@@ -108,4 +111,4 @@
# variable will be changed. After you have modified this file with the new
# changes (see buildspec.mk.default), update this to the new value from
# buildspec.mk.default.
-BUILD_ENV_SEQUENCE_NUMBER := 10
+BUILD_ENV_SEQUENCE_NUMBER := 13
diff --git a/core/Makefile b/core/Makefile
index cf39a8b..a23cdd4 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -5,7 +5,7 @@
LOCAL_PATH := $(BUILD_SYSTEM)
# Pick a reasonable string to use to identify files.
-ifneq "" "$(filter eng.%,$(BUILD_NUMBER))"
+ifneq (,$(filter eng.%,$(BUILD_NUMBER)))
# BUILD_NUMBER has a timestamp in it, which means that
# it will change every time. Pick a stable value.
FILE_NAME_TAG := eng.$(USER)
@@ -74,12 +74,12 @@
# default.prop
INSTALLED_DEFAULT_PROP_TARGET := $(TARGET_ROOT_OUT)/default.prop
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_DEFAULT_PROP_TARGET)
-ADDITIONAL_DEFAULT_PROPERTIES := \
+FINAL_DEFAULT_PROPERTIES := \
$(call collapse-pairs, $(ADDITIONAL_DEFAULT_PROPERTIES))
-ADDITIONAL_DEFAULT_PROPERTIES += \
+FINAL_DEFAULT_PROPERTIES += \
$(call collapse-pairs, $(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
-ADDITIONAL_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
- $(ADDITIONAL_DEFAULT_PROPERTIES),=)
+FINAL_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
+ $(FINAL_DEFAULT_PROPERTIES),=)
intermediate_system_build_prop := $(call intermediates-dir-for,ETC,system_build_prop)/build.prop
@@ -89,7 +89,7 @@
$(hide) echo "#" > $@; \
echo "# ADDITIONAL_DEFAULT_PROPERTIES" >> $@; \
echo "#" >> $@;
- $(hide) $(foreach line,$(ADDITIONAL_DEFAULT_PROPERTIES), \
+ $(hide) $(foreach line,$(FINAL_DEFAULT_PROPERTIES), \
echo "$(line)" >> $@;)
$(hide) echo "#" >> $@; \
echo "# BOOTIMAGE_BUILD_PROPERTIES" >> $@; \
@@ -103,10 +103,10 @@
# build.prop
INSTALLED_BUILD_PROP_TARGET := $(TARGET_OUT)/build.prop
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_BUILD_PROP_TARGET)
-ADDITIONAL_BUILD_PROPERTIES := \
+FINAL_BUILD_PROPERTIES := \
$(call collapse-pairs, $(ADDITIONAL_BUILD_PROPERTIES))
-ADDITIONAL_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
- $(ADDITIONAL_BUILD_PROPERTIES),=)
+FINAL_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
+ $(FINAL_BUILD_PROPERTIES),=)
# A list of arbitrary tags describing the build configuration.
# Force ":=" so we can use +=
@@ -171,7 +171,7 @@
# release build number or branch.buld_number non-release builds
# Dev. branches should have DISPLAY_BUILD_NUMBER set
- ifeq "true" "$(DISPLAY_BUILD_NUMBER)"
+ ifeq (true,$(DISPLAY_BUILD_NUMBER))
BUILD_DISPLAY_ID := $(BUILD_ID).$(BUILD_NUMBER_FROM_FILE) $(BUILD_KEYS)
else
BUILD_DISPLAY_ID := $(BUILD_ID) $(BUILD_KEYS)
@@ -191,11 +191,16 @@
BUILDINFO_SH := build/tools/buildinfo.sh
-# TARGET_BUILD_FLAVOR and ro.build.flavor are used only by the test harness to distinguish builds.
+# TARGET_BUILD_FLAVOR and ro.build.flavor are used only by the test
+# harness to distinguish builds. Only add _asan for a sanitized build
+# if it isn't already a part of the flavor (via a dedicated lunch
+# config for example).
TARGET_BUILD_FLAVOR := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)
ifdef SANITIZE_TARGET
+ifeq (,$(findstring _asan,$(TARGET_BUILD_FLAVOR)))
TARGET_BUILD_FLAVOR := $(TARGET_BUILD_FLAVOR)_asan
endif
+endif
ifdef TARGET_SYSTEM_PROP
system_prop_file := $(TARGET_SYSTEM_PROP)
@@ -256,12 +261,12 @@
echo "#" >> $@; \
cat $(file) >> $@; \
fi;)
- $(if $(ADDITIONAL_BUILD_PROPERTIES), \
+ $(if $(FINAL_BUILD_PROPERTIES), \
$(hide) echo >> $@; \
echo "#" >> $@; \
echo "# ADDITIONAL_BUILD_PROPERTIES" >> $@; \
echo "#" >> $@; )
- $(hide) $(foreach line,$(ADDITIONAL_BUILD_PROPERTIES), \
+ $(hide) $(foreach line,$(FINAL_BUILD_PROPERTIES), \
echo "$(line)" >> $@;)
$(hide) cat $(INSTALLED_ANDROID_INFO_TXT_TARGET) | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' >> $@
$(hide) build/tools/post_process_props.py $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_PROPERTY_BLACKLIST)
@@ -284,7 +289,7 @@
# -----------------------------------------------------------------
# vendor build.prop
#
-# For verifying that the vendor build is what we thing it is
+# For verifying that the vendor build is what we think it is
ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
INSTALLED_VENDOR_BUILD_PROP_TARGET := $(TARGET_OUT_VENDOR)/build.prop
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_VENDOR_BUILD_PROP_TARGET)
@@ -386,7 +391,31 @@
endif
# -----------------------------------------------------------------
+# build system stats
+BUILD_SYSTEM_STATS := $(PRODUCT_OUT)/build_system_stats.txt
+$(BUILD_SYSTEM_STATS):
+ @rm -f $@
+ @$(foreach s,$(STATS.MODULE_TYPE),echo "modules_type_make,$(s),$(words $(STATS.MODULE_TYPE.$(s)))" >>$@;)
+ @$(foreach s,$(STATS.SOONG_MODULE_TYPE),echo "modules_type_soong,$(s),$(STATS.SOONG_MODULE_TYPE.$(s))" >>$@;)
+$(call dist-for-goals,droidcore,$(BUILD_SYSTEM_STATS))
+# -----------------------------------------------------------------
+# Modules ready to be converted to Soong, ordered by how many
+# modules depend on them.
+SOONG_CONV := $(sort $(SOONG_CONV))
+SOONG_CONV_DATA := $(call intermediates-dir-for,PACKAGING,soong_conversion)/soong_conv_data
+$(SOONG_CONV_DATA):
+ @rm -f $@
+ @$(foreach s,$(SOONG_CONV),echo "$(s),$(sort $(SOONG_CONV.$(s).PROBLEMS)),$(sort $(filter-out $(SOONG_ALREADY_CONV),$(SOONG_CONV.$(s).DEPS)))" >>$@;)
+
+SOONG_TO_CONVERT_SCRIPT := build/tools/soong_to_convert.py
+SOONG_TO_CONVERT := $(PRODUCT_OUT)/soong_to_convert.txt
+$(SOONG_TO_CONVERT): $(SOONG_CONV_DATA) $(SOONG_TO_CONVERT_SCRIPT)
+ @rm -f $@
+ $(hide) $(SOONG_TO_CONVERT_SCRIPT) $< >$@
+$(call dist-for-goals,droidcore,$(SOONG_TO_CONVERT))
+
+# -----------------------------------------------------------------
# The dev key is used to sign this package, and as the key required
# for future OTA packages installed by this system. Actual product
# deliverables will be re-signed by hand. We expect this file to
@@ -420,9 +449,9 @@
pdk_fusion_log_tags_file := $(patsubst $(PRODUCT_OUT)/%,$(_pdk_fusion_intermediates)/%,$(filter $(event_log_tags_file),$(ALL_PDK_FUSION_FILES)))
$(all_event_log_tags_file): PRIVATE_SRC_FILES := $(all_event_log_tags_src) $(pdk_fusion_log_tags_file)
-$(all_event_log_tags_file): $(all_event_log_tags_src) $(pdk_fusion_log_tags_file)
+$(all_event_log_tags_file): $(all_event_log_tags_src) $(pdk_fusion_log_tags_file) $(MERGETAGS) build/tools/event_log_tags.py
$(hide) mkdir -p $(dir $@)
- $(hide) build/tools/merge-event-log-tags.py -o $@ $(PRIVATE_SRC_FILES)
+ $(hide) $(MERGETAGS) -o $@ $(PRIVATE_SRC_FILES)
# Include tags from all packages included in this product, plus all
# tags that are part of the system (ie, not in a vendor/ or device/
@@ -436,9 +465,9 @@
$(event_log_tags_file): PRIVATE_SRC_FILES := $(event_log_tags_src) $(pdk_fusion_log_tags_file)
$(event_log_tags_file): PRIVATE_MERGED_FILE := $(all_event_log_tags_file)
-$(event_log_tags_file): $(event_log_tags_src) $(all_event_log_tags_file) $(pdk_fusion_log_tags_file)
+$(event_log_tags_file): $(event_log_tags_src) $(all_event_log_tags_file) $(pdk_fusion_log_tags_file) $(MERGETAGS) build/tools/event_log_tags.py
$(hide) mkdir -p $(dir $@)
- $(hide) build/tools/merge-event-log-tags.py -o $@ -m $(PRIVATE_MERGED_FILE) $(PRIVATE_SRC_FILES)
+ $(hide) $(MERGETAGS) -o $@ -m $(PRIVATE_MERGED_FILE) $(PRIVATE_SRC_FILES)
event-log-tags: $(event_log_tags_file)
@@ -468,7 +497,6 @@
# -----------------------------------------------------------------
# the ramdisk
INTERNAL_RAMDISK_FILES := $(filter $(TARGET_ROOT_OUT)/%, \
- $(ALL_PREBUILT) \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES))
@@ -499,12 +527,10 @@
INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS))
-BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE))
ifdef BOARD_KERNEL_BASE
INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
endif
-BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
ifdef BOARD_KERNEL_PAGESIZE
INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
endif
@@ -516,9 +542,9 @@
endif
endif
-BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE) buildvariant=$(TARGET_BUILD_VARIANT) $(VERITY_KEYID))
-ifdef BOARD_KERNEL_CMDLINE
-INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
+INTERNAL_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE) buildvariant=$(TARGET_BUILD_VARIANT) $(VERITY_KEYID))
+ifdef INTERNAL_KERNEL_CMDLINE
+INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(INTERNAL_KERNEL_CMDLINE)"
endif
INTERNAL_MKBOOTIMG_VERSION_ARGS := \
@@ -538,7 +564,31 @@
ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
$(error TARGET_BOOTIMAGE_USE_EXT2 is not supported anymore)
-else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)) # TARGET_BOOTIMAGE_USE_EXT2 != true
+
+else ifeq (true,$(BOARD_AVB_ENABLE)) # TARGET_BOOTIMAGE_USE_EXT2 != true
+
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES)
+ $(call pretty,"Target boot image: $@")
+ $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
+ $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
+ $(hide) $(AVBTOOL) add_hash_footer \
+ --image $@ \
+ --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
+ --partition_name boot $(INTERNAL_AVB_SIGNING_ARGS) \
+ $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)
+
+.PHONY: bootimage-nodeps
+bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL)
+ @echo "make $@: ignoring dependencies"
+ $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
+ $(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
+ $(hide) $(AVBTOOL) add_hash_footer \
+ --image $@ \
+ --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
+ --partition_name boot $(INTERNAL_AVB_SIGNING_ARGS) \
+ $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)
+
+else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)) # BOARD_AVB_ENABLE != true
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER)
$(call pretty,"Target boot image: $@")
@@ -585,6 +635,7 @@
endif # BOARD_USES_RECOVERY_AS_BOOT
else # TARGET_NO_KERNEL
+INTERNAL_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
# HACK: The top-level targets depend on the bootimage. Not all targets
# can produce a bootimage, though, and emulator targets need the ramdisk
# instead. Fake it out by calling the ramdisk the bootimage.
@@ -607,13 +658,14 @@
.PHONY: notice_files
-# Create the rule to combine the files into text and html forms
-# $(1) - Plain text output file
-# $(2) - HTML output file
-# $(3) - File title
-# $(4) - Directory to use. Notice files are all $(4)/src. Other
+# Create the rule to combine the files into text and html/xml forms
+# $(1) - xml_excluded_vendor|xml_vendor|html
+# $(2) - Plain text output file
+# $(3) - HTML/XML output file
+# $(4) - File title
+# $(5) - Directory to use. Notice files are all $(4)/src. Other
# directories in there will be used for scratch
-# $(5) - Dependencies for the output files
+# $(6) - Dependencies for the output files
#
# The algorithm here is that we go collect a hash for each of the notice
# files and write the names of the files that match that hash. Then
@@ -627,12 +679,16 @@
# original notice files instead of making rules to copy them somwehere.
# Then we could traverse that without quite as much bash drama.
define combine-notice-files
-$(1) $(2): PRIVATE_MESSAGE := $(3)
-$(1) $(2): PRIVATE_DIR := $(4)
-$(1) : $(2)
-$(2) : $(5) $(BUILD_SYSTEM)/Makefile build/tools/generate-notice-files.py
- build/tools/generate-notice-files.py $(1) $(2) $$(PRIVATE_MESSAGE) $$(PRIVATE_DIR)/src
-notice_files: $(1) $(2)
+$(2) $(3): PRIVATE_MESSAGE := $(4)
+$(2) $(3): PRIVATE_DIR := $(5)
+$(2) : $(3)
+$(3) : $(6) $(BUILD_SYSTEM)/Makefile build/tools/generate-notice-files.py
+ build/tools/generate-notice-files.py --text-output $(2) \
+ $(if $(filter $(1),xml_excluded_vendor),-e vendor --xml-output, \
+ $(if $(filter $(1),xml_vendor),-i vendor --xml-output, \
+ --html-output)) $(3) \
+ -t $$(PRIVATE_MESSAGE) -s $$(PRIVATE_DIR)/src
+notice_files: $(2) $(3)
endef
# TODO These intermediate NOTICE.txt/NOTICE.html files should go into
@@ -640,43 +696,82 @@
# the src subdirectory.
target_notice_file_txt := $(TARGET_OUT_INTERMEDIATES)/NOTICE.txt
-target_notice_file_html := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html
-target_notice_file_html_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html.gz
+target_notice_file_html_or_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html
+target_notice_file_html_or_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE.html.gz
+installed_notice_html_or_xml_gz := $(TARGET_OUT)/etc/NOTICE.html.gz
tools_notice_file_txt := $(HOST_OUT_INTERMEDIATES)/NOTICE.txt
tools_notice_file_html := $(HOST_OUT_INTERMEDIATES)/NOTICE.html
+ifeq ($(PRODUCT_FULL_TREBLE),true)
+target_notice_file_html_or_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE.xml
+target_notice_file_html_or_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE.xml.gz
+installed_notice_html_or_xml_gz := $(TARGET_OUT)/etc/NOTICE.xml.gz
+
+target_vendor_notice_file_txt := $(TARGET_OUT_INTERMEDIATES)/NOTICE_VENDOR.txt
+target_vendor_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE_VENDOR.xml
+target_vendor_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE_VENDOR.xml.gz
+installed_vendor_notice_xml_gz := $(TARGET_OUT_VENDOR)/etc/NOTICE.xml.gz
+endif
+
ifndef TARGET_BUILD_APPS
kernel_notice_file := $(TARGET_OUT_NOTICE_FILES)/src/kernel.txt
+winpthreads_notice_file := $(TARGET_OUT_NOTICE_FILES)/src/winpthreads.txt
pdk_fusion_notice_files := $(filter $(TARGET_OUT_NOTICE_FILES)/%, $(ALL_PDK_FUSION_FILES))
-$(eval $(call combine-notice-files, \
+ifdef target_vendor_notice_file_xml_gz
+$(eval $(call combine-notice-files, xml_excluded_vendor, \
$(target_notice_file_txt), \
- $(target_notice_file_html), \
+ $(target_notice_file_html_or_xml), \
"Notices for files contained in the filesystem images in this directory:", \
$(TARGET_OUT_NOTICE_FILES), \
$(ALL_DEFAULT_INSTALLED_MODULES) $(kernel_notice_file) $(pdk_fusion_notice_files)))
+$(eval $(call combine-notice-files, xml_vendor, \
+ $(target_vendor_notice_file_txt), \
+ $(target_vendor_notice_file_xml), \
+ "Notices for files contained in the vendor filesystem image in this directory:", \
+ $(TARGET_OUT_NOTICE_FILES), \
+ $(target_notice_file_html_or_xml)))
+else
+$(eval $(call combine-notice-files, html, \
+ $(target_notice_file_txt), \
+ $(target_notice_file_html_or_xml), \
+ "Notices for files contained in the filesystem images in this directory:", \
+ $(TARGET_OUT_NOTICE_FILES), \
+ $(ALL_DEFAULT_INSTALLED_MODULES) $(kernel_notice_file) $(pdk_fusion_notice_files)))
+endif
-$(eval $(call combine-notice-files, \
+$(eval $(call combine-notice-files, html, \
$(tools_notice_file_txt), \
$(tools_notice_file_html), \
"Notices for files contained in the tools directory:", \
$(HOST_OUT_NOTICE_FILES), \
- $(ALL_DEFAULT_INSTALLED_MODULES)))
+ $(ALL_DEFAULT_INSTALLED_MODULES) \
+ $(winpthreads_notice_file)))
# Install the html file at /system/etc/NOTICE.html.gz.
# This is not ideal, but this is very late in the game, after a lot of
# the module processing has already been done -- in fact, we used the
# fact that all that has been done to get the list of modules that we
# need notice files for.
-$(target_notice_file_html_gz): $(target_notice_file_html) | $(MINIGZIP)
+$(target_notice_file_html_or_xml_gz): $(target_notice_file_html_or_xml) | $(MINIGZIP)
$(hide) $(MINIGZIP) -9 < $< > $@
-installed_notice_html_gz := $(TARGET_OUT)/etc/NOTICE.html.gz
-$(installed_notice_html_gz): $(target_notice_file_html_gz) | $(ACP)
+$(installed_notice_html_or_xml_gz): $(target_notice_file_html_or_xml_gz)
$(copy-file-to-target)
+ifdef target_vendor_notice_file_xml_gz
+# Install the vendor html file at /vendor/etc/NOTICE.xml.gz.
+$(target_vendor_notice_file_xml_gz): $(target_vendor_notice_file_xml) | $(MINIGZIP)
+ $(hide) $(MINIGZIP) -9 < $< > $@
+$(installed_vendor_notice_xml_gz): $(target_vendor_notice_file_xml_gz)
+ $(copy-file-to-target)
+endif
+
# if we've been run my mm, mmm, etc, don't reinstall this every time
ifeq ($(ONE_SHOT_MAKEFILE),)
-ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_gz)
+ ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_or_xml_gz)
+ ifdef target_vendor_notice_file_xml_gz
+ ALL_DEFAULT_INSTALLED_MODULES += $(installed_vendor_notice_xml_gz)
+ endif
endif
endif # TARGET_BUILD_APPS
@@ -690,6 +785,12 @@
$(hide) mkdir -p $(dir $@)
$(hide) $(ACP) $< $@
+$(winpthreads_notice_file): \
+ $(BUILD_SYSTEM)/WINPTHREADS_COPYING \
+ | $(ACP)
+ @echo Copying: $@
+ $(hide) mkdir -p $(dir $@)
+ $(hide) $(ACP) $< $@
# -----------------------------------------------------------------
# Build a keystore with the authorized keys in it, used to verify the
@@ -705,11 +806,11 @@
$(hide) zip -qjX $@ $<
$(remove-timestamps-from-package)
-# Carry the public key for update_engine if it's a non-Brillo target that
+# Carry the public key for update_engine if it's a non-IoT target that
# uses the AB updater. We use the same key as otacerts but in RSA public key
# format.
ifeq ($(AB_OTA_UPDATER),true)
-ifeq ($(BRILLO),)
+ifneq ($(PRODUCT_IOT),true)
ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem
$(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem: $(addsuffix .x509.pem,$(DEFAULT_KEY_CERT_PAIR))
$(hide) rm -f $@
@@ -781,14 +882,19 @@
endif
endif
-SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts.bin
+SELINUX_FC := $(call intermediates-dir-for,ETC,file_contexts.bin)/file_contexts.bin
INTERNAL_USERIMAGES_DEPS += $(SELINUX_FC)
INTERNAL_USERIMAGES_DEPS += $(BLK_ALLOC_TO_BASE_FS)
+ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
+INTERNAL_USERIMAGES_DEPS += $(MKE2FS_CONF)
+endif
+
# $(1): the path of the output dictionary file
# $(2): additional "key=value" pairs to append to the dictionary file.
define generate-userimage-prop-dictionary
+$(hide) echo "ext_mkuserimg=$(notdir $(MKEXTUSERIMG))" >> $(1)
$(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -803,6 +909,8 @@
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM),$(hide) echo "system_headroom=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM)" >> $(1))
$(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
$(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(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))
$(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
$(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1))
$(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -832,6 +940,12 @@
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_subkey=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY)" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "futility=$(notdir $(FUTILITY))" >> $(1))
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_signer_cmd=$(VBOOT_SIGNER)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_signing_args=$(INTERNAL_AVB_SIGNING_ARGS)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_avbtool=$(notdir $(AVBTOOL))" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "system_avb_hashtree_enable=$(BOARD_AVB_ENABLE)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "system_avb_add_hashtree_footer_args=$(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "vendor_avb_hashtree_enable=$(BOARD_AVB_ENABLE)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "vendor_avb_add_hashtree_footer_args=$(BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
$(hide) echo "recovery_as_boot=true" >> $(1))
$(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
@@ -850,7 +964,15 @@
$(ALL_DEFAULT_INSTALLED_MODULES))
recovery_initrc := $(call include-path-for, recovery)/etc/init.rc
-recovery_sepolicy := $(call intermediates-dir-for,ETC,sepolicy.recovery)/sepolicy.recovery
+recovery_sepolicy := \
+ $(TARGET_RECOVERY_ROOT_OUT)/sepolicy \
+ $(TARGET_RECOVERY_ROOT_OUT)/file_contexts.bin \
+ $(TARGET_RECOVERY_ROOT_OUT)/plat_property_contexts \
+ $(TARGET_RECOVERY_ROOT_OUT)/nonplat_property_contexts
+# Passed into rsync from non-recovery root to recovery root, to avoid overwriting recovery-specific
+# SELinux files
+IGNORE_RECOVERY_SEPOLICY := $(patsubst $(TARGET_RECOVERY_OUT)/%,--exclude=/%,$(recovery_sepolicy))
+
recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system
recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img
recovery_build_prop := $(intermediate_system_build_prop)
@@ -932,13 +1054,12 @@
--ramdisk $(recovery_ramdisk)
# Assumes this has already been stripped
-ifdef BOARD_KERNEL_CMDLINE
- INTERNAL_RECOVERYIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
+ifdef INTERNAL_KERNEL_CMDLINE
+ INTERNAL_RECOVERYIMAGE_ARGS += --cmdline "$(INTERNAL_KERNEL_CMDLINE)"
endif
ifdef BOARD_KERNEL_BASE
INTERNAL_RECOVERYIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
endif
-BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
ifdef BOARD_KERNEL_PAGESIZE
INTERNAL_RECOVERYIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
endif
@@ -962,18 +1083,37 @@
java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) $(extra_keys) > $@
RECOVERYIMAGE_ID_FILE := $(PRODUCT_OUT)/recovery.id
+
+# $(1): modules list
+# $(2): output dir
+# $(3): mount point
+# $(4): staging dir
+# Depmod requires a well-formed kernel version so 0.0 is used as a placeholder.
+define build-image-kernel-modules
+ $(hide) rm -rf $(2)/lib/modules
+ $(hide) mkdir -p $(2)/lib/modules
+ $(hide) cp $(1) $(2)/lib/modules/
+ $(hide) rm -rf $(4)
+ $(hide) mkdir -p $(4)/lib/modules/0.0/$(3)lib/modules
+ $(hide) cp $(1) $(4)/lib/modules/0.0/$(3)lib/modules
+ $(hide) $(DEPMOD) -b $(4) 0.0
+ $(hide) sed -e 's/\(.*modules.*\):/\/\1:/g' -e 's/ \([^ ]*modules[^ ]*\)/ \/\1/g' -i $(4)/lib/modules/0.0/modules.dep
+ $(hide) cp $(4)/lib/modules/0.0/modules.dep $(2)/lib/modules
+endef
+
# $(1): output file
define build-recoveryimage-target
@echo ----- Making recovery image ------
$(hide) mkdir -p $(TARGET_RECOVERY_OUT)
$(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/sdcard $(TARGET_RECOVERY_ROOT_OUT)/tmp
@echo Copying baseline ramdisk...
- $(hide) rsync -a --exclude=etc --exclude=sdcard $(IGNORE_CACHE_LINK) $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT) # "cp -Rf" fails to overwrite broken symlinks on Mac.
+ # Use rsync because "cp -Rf" fails to overwrite broken symlinks on Mac.
+ $(hide) rsync -a --exclude=etc --exclude=sdcard $(IGNORE_RECOVERY_SEPOLICY) $(IGNORE_CACHE_LINK) $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)
@echo Modifying ramdisk contents...
+ $(if $(BOARD_RECOVERY_KERNEL_MODULES), \
+ $(call build-image-kernel-modules,$(BOARD_RECOVERY_KERNEL_MODULES),$(TARGET_RECOVERY_ROOT_OUT),,$(call intermediates-dir-for,PACKAGING,depmod_recovery)))
$(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/init*.rc
$(hide) cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/
- $(hide) rm -f $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
- $(hide) cp -f $(recovery_sepolicy) $(TARGET_RECOVERY_ROOT_OUT)/sepolicy
$(hide) cp $(TARGET_ROOT_OUT)/init.recovery.*.rc $(TARGET_RECOVERY_ROOT_OUT)/ || true # Ignore error when the src file doesn't exist.
$(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/res
$(hide) rm -rf $(TARGET_RECOVERY_ROOT_OUT)/res/*
@@ -1005,6 +1145,12 @@
)
$(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)), \
$(VBOOT_SIGNER) $(FUTILITY) $(1).unsigned $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbprivk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY).vbprivk $(1).keyblock $(1))
+ $(if $(and $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),$(filter true,$(BOARD_AVB_ENABLE))), \
+ $(hide) $(AVBTOOL) add_hash_footer \
+ --image $(1) \
+ --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
+ --partition_name boot $(INTERNAL_AVB_SIGNING_ARGS) \
+ $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS))
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)), \
$(hide) $(call assert-max-image-size,$(1),$(BOARD_BOOTIMAGE_PARTITION_SIZE)), \
$(hide) $(call assert-max-image-size,$(1),$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)))
@@ -1018,6 +1164,9 @@
ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT))
$(INSTALLED_BOOTIMAGE_TARGET) : $(VBOOT_SIGNER)
endif
+ifeq (true,$(BOARD_AVB_ENABLE))
+$(INSTALLED_BOOTIMAGE_TARGET) : $(AVBTOOL)
+endif
$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
$(INSTALLED_RAMDISK_TARGET) \
$(INTERNAL_RECOVERYIMAGE_FILES) \
@@ -1025,7 +1174,9 @@
$(INSTALLED_2NDBOOTLOADER_TARGET) \
$(recovery_build_prop) $(recovery_resource_deps) \
$(recovery_fstab) \
- $(RECOVERY_INSTALL_OTA_KEYS)
+ $(RECOVERY_INSTALL_OTA_KEYS) \
+ $(BOARD_RECOVERY_KERNEL_MODULES) \
+ $(DEPMOD)
$(call pretty,"Target boot image from recovery: $@")
$(call build-recoveryimage-target, $@)
endif
@@ -1038,7 +1189,9 @@
$(INSTALLED_2NDBOOTLOADER_TARGET) \
$(recovery_build_prop) $(recovery_resource_deps) \
$(recovery_fstab) \
- $(RECOVERY_INSTALL_OTA_KEYS)
+ $(RECOVERY_INSTALL_OTA_KEYS) \
+ $(BOARD_RECOVERY_KERNEL_MODULES) \
+ $(DEPMOD)
$(call build-recoveryimage-target, $@)
ifdef RECOVERY_RESOURCE_ZIP
@@ -1077,7 +1230,6 @@
$(ALL_PDK_FUSION_FILES))
INTERNAL_SYSTEMIMAGE_FILES := $(filter $(TARGET_OUT)/%, \
- $(ALL_PREBUILT) \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(PDK_FUSION_SYSIMG_FILES) \
@@ -1085,6 +1237,15 @@
FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
+
+# ASAN libraries in the system image - add dependency.
+ASAN_IN_SYSTEM_INSTALLED := $(TARGET_OUT)/asan.tar.bz2
+ifneq (,$(SANITIZE_TARGET))
+ ifeq (true,$(SANITIZE_TARGET_SYSTEM))
+ FULL_SYSTEMIMAGE_DEPS += $(ASAN_IN_SYSTEM_INSTALLED)
+ endif
+endif
+
# -----------------------------------------------------------------
# installed file list
# Depending on anything that $(BUILT_SYSTEMIMAGE) depends on.
@@ -1092,11 +1253,11 @@
# so that we can get the size stat even if the build fails due to too large
# system image.
INSTALLED_FILES_FILE := $(PRODUCT_OUT)/installed-files.txt
-$(INSTALLED_FILES_FILE): $(FULL_SYSTEMIMAGE_DEPS)
+$(INSTALLED_FILES_FILE): $(FULL_SYSTEMIMAGE_DEPS) $(FILESLIST)
@echo Installed file list: $@
@mkdir -p $(dir $@)
@rm -f $@
- $(hide) build/tools/fileslist.py $(TARGET_OUT) > $(@:.txt=.json)
+ $(hide) $(FILESLIST) $(TARGET_OUT) > $(@:.txt=.json)
$(hide) build/tools/fileslist_util.py -c $(@:.txt=.json) > $@
.PHONY: installed-file-list
@@ -1148,7 +1309,7 @@
exit 1 )
endef
-$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
+$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS)
$(call build-systemimage-target,$@)
INSTALLED_SYSTEMIMAGE := $(PRODUCT_OUT)/system.img
@@ -1176,7 +1337,7 @@
endif
-$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH) | $(ACP)
+$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
@echo "Install system fs image: $@"
$(copy-file-to-target)
$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
@@ -1260,7 +1421,7 @@
$(hide) echo "PDK.DEXPREOPT.$(m).MULTILIB:=$(DEXPREOPT.$(m).MULTILIB)" >> $@$(newline)\
$(hide) echo "PDK.DEXPREOPT.$(m).DEX_PREOPT_FLAGS:=$(DEXPREOPT.$(m).DEX_PREOPT_FLAGS)" >> $@$(newline)\
$(hide) echo "PDK.DEXPREOPT.$(m).PRIVILEGED_MODULE:=$(DEXPREOPT.$(m).PRIVILEGED_MODULE)" >> $@$(newline)\
- $(hide) echo "PDK.DEXPREOPT.$(m).PROPRIETARY_MODULE:=$(DEXPREOPT.$(m).PROPRIETARY_MODULE)" >> $@$(newline)\
+ $(hide) echo "PDK.DEXPREOPT.$(m).VENDOR_MODULE:=$(DEXPREOPT.$(m).VENDOR_MODULE)" >> $@$(newline)\
$(hide) echo "PDK.DEXPREOPT.$(m).TARGET_ARCH:=$(DEXPREOPT.$(m).TARGET_ARCH)" >> $@$(newline)\
$(hide) echo "PDK.DEXPREOPT.$(m).STRIPPED_SRC:=$(patsubst $(PRODUCT_OUT)/%,%,$(DEXPREOPT.$(m).INSTALLED_STRIPPED))" >> $@$(newline)\
)
@@ -1308,7 +1469,7 @@
$(hide) echo "Target boot fs tarball: $(INSTALLED_BOOTTARBALL_TARGET)"
$(hide) mkdir -p $(PRODUCT_OUT)/boot
$(hide) cp -f $(INTERNAL_BOOTIMAGE_FILES) $(PRODUCT_OUT)/boot/.
- $(hide) echo $(BOARD_KERNEL_CMDLINE) > $(PRODUCT_OUT)/boot/cmdline
+ $(hide) echo $(INTERNAL_KERNEL_CMDLINE) > $(PRODUCT_OUT)/boot/cmdline
$(hide) $(MKTARBALL) $(FS_GET_STATS) \
$(PRODUCT_OUT) boot $(PRIVATE_BOOT_TAR) \
$(INSTALLED_BOOTTARBALL_TARGET) $(TARGET_OUT)
@@ -1361,8 +1522,11 @@
# We just build this directly to the install location.
INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)
-$(INSTALLED_USERDATAIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) \
- $(INTERNAL_USERDATAIMAGE_FILES)
+INSTALLED_USERDATAIMAGE_TARGET_DEPS := \
+ $(INTERNAL_USERIMAGES_DEPS) \
+ $(INTERNAL_USERDATAIMAGE_FILES) \
+ $(BUILD_IMAGE_SRCS)
+$(INSTALLED_USERDATAIMAGE_TARGET): $(INSTALLED_USERDATAIMAGE_TARGET_DEPS)
$(build-userdataimage-target)
.PHONY: userdataimage-nodeps
@@ -1372,6 +1536,19 @@
endif # not skip_userdata.img
skip_userdata.img :=
+# ASAN libraries in the system image - build rule.
+ASAN_OUT_DIRS_FOR_SYSTEM_INSTALL := $(sort $(patsubst $(PRODUCT_OUT)/%,%,\
+ $(TARGET_OUT_SHARED_LIBRARIES) \
+ $(2ND_TARGET_OUT_SHARED_LIBRARIES) \
+ $(TARGET_OUT_VENDOR_SHARED_LIBRARIES) \
+ $(2ND_TARGET_OUT_VENDOR_SHARED_LIBRARIES)))
+# Extra options: Enforce the system user for the files to avoid having to change ownership.
+ASAN_SYSTEM_INSTALL_OPTIONS := --owner=1000 --group=1000
+# Note: experimentally, it seems not worth it to try to get "best" compression. We don't save
+# enough space.
+$(ASAN_IN_SYSTEM_INSTALLED): $(INSTALLED_USERDATAIMAGE_TARGET_DEPS)
+ tar cfj $(ASAN_IN_SYSTEM_INSTALLED) $(ASAN_SYSTEM_INSTALL_OPTIONS) -C $(TARGET_OUT_DATA)/.. $(ASAN_OUT_DIRS_FOR_SYSTEM_INSTALL) >/dev/null
+
#######
## data partition tarball
define build-userdatatarball-target
@@ -1396,6 +1573,40 @@
# -----------------------------------------------------------------
+# partition table image
+ifdef BOARD_BPT_INPUT_FILES
+
+BUILT_BPTIMAGE_TARGET := $(PRODUCT_OUT)/partition-table.img
+BUILT_BPTJSON_TARGET := $(PRODUCT_OUT)/partition-table.bpt
+
+INTERNAL_BVBTOOL_MAKE_TABLE_ARGS := \
+ --output_gpt $(BUILT_BPTIMAGE_TARGET) \
+ --output_json $(BUILT_BPTJSON_TARGET) \
+ $(foreach file, $(BOARD_BPT_INPUT_FILES), --input $(file))
+
+ifdef BOARD_BPT_DISK_SIZE
+INTERNAL_BVBTOOL_MAKE_TABLE_ARGS += --disk_size $(BOARD_BPT_DISK_SIZE)
+endif
+
+define build-bptimage-target
+ $(call pretty,"Target partition table image: $(INSTALLED_BPTIMAGE_TARGET)")
+ $(hide) $(BPTTOOL) make_table $(INTERNAL_BVBTOOL_MAKE_TABLE_ARGS) $(BOARD_BPT_MAKE_TABLE_ARGS)
+endef
+
+INSTALLED_BPTIMAGE_TARGET := $(BUILT_BPTIMAGE_TARGET)
+$(BUILT_BPTJSON_TARGET): $(INSTALLED_BPTIMAGE_TARGET)
+ $(hide) touch -c $(BUILT_BPTJSON_TARGET)
+
+$(INSTALLED_BPTIMAGE_TARGET): $(BPTTOOL) $(BOARD_BPT_INPUT_FILES)
+ $(build-bptimage-target)
+
+.PHONY: bptimage-nodeps
+bptimage-nodeps:
+ $(build-bptimage-target)
+
+endif # BOARD_BPT_INPUT_FILES
+
+# -----------------------------------------------------------------
# cache partition image
ifdef BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
INTERNAL_CACHEIMAGE_FILES := \
@@ -1418,7 +1629,7 @@
# We just build this directly to the install location.
INSTALLED_CACHEIMAGE_TARGET := $(BUILT_CACHEIMAGE_TARGET)
-$(INSTALLED_CACHEIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_CACHEIMAGE_FILES)
+$(INSTALLED_CACHEIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_CACHEIMAGE_FILES) $(BUILD_IMAGE_SRCS)
$(build-cacheimage-target)
.PHONY: cacheimage-nodeps
@@ -1430,7 +1641,6 @@
IGNORE_CACHE_LINK := --exclude=cache
endif # BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
-
# -----------------------------------------------------------------
# system_other partition image
ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
@@ -1450,11 +1660,12 @@
$(ALL_PDK_FUSION_FILES))
INSTALLED_FILES_FILE_SYSTEMOTHER := $(PRODUCT_OUT)/installed-files-system-other.txt
-$(INSTALLED_FILES_FILE_SYSTEMOTHER) : $(INTERNAL_SYSTEMOTHERIMAGE_FILES)
+$(INSTALLED_FILES_FILE_SYSTEMOTHER) : $(INTERNAL_SYSTEMOTHERIMAGE_FILES) $(FILESLIST)
@echo Installed file list: $@
@mkdir -p $(dir $@)
@rm -f $@
- $(hide) build/tools/fileslist.py $(TARGET_OUT_SYSTEM_OTHER) > $@
+ $(hide) $(FILESLIST) $(TARGET_OUT_SYSTEM_OTHER) > $(@:.txt=.json)
+ $(hide) build/tools/fileslist_util.py -c $(@:.txt=.json) > $@
systemotherimage_intermediates := \
$(call intermediates-dir-for,PACKAGING,system_other)
@@ -1496,22 +1707,23 @@
$(INSTALLED_PLATFORM_ZIP) : $(INTERNAL_VENDORIMAGE_FILES)
INSTALLED_FILES_FILE_VENDOR := $(PRODUCT_OUT)/installed-files-vendor.txt
-$(INSTALLED_FILES_FILE_VENDOR) : $(INTERNAL_VENDORIMAGE_FILES)
+$(INSTALLED_FILES_FILE_VENDOR) : $(INTERNAL_VENDORIMAGE_FILES) $(FILESLIST)
@echo Installed file list: $@
@mkdir -p $(dir $@)
@rm -f $@
- $(hide) build/tools/fileslist.py $(TARGET_OUT_VENDOR) > $(@:.txt=.json)
+ $(hide) $(FILESLIST) $(TARGET_OUT_VENDOR) > $(@:.txt=.json)
$(hide) build/tools/fileslist_util.py -c $(@:.txt=.json) > $@
vendorimage_intermediates := \
$(call intermediates-dir-for,PACKAGING,vendor)
BUILT_VENDORIMAGE_TARGET := $(PRODUCT_OUT)/vendor.img
-
define build-vendorimage-target
$(call pretty,"Target vendor fs image: $(INSTALLED_VENDORIMAGE_TARGET)")
@mkdir -p $(TARGET_OUT_VENDOR)
@mkdir -p $(vendorimage_intermediates) && rm -rf $(vendorimage_intermediates)/vendor_image_info.txt
$(call generate-userimage-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt, skip_fsck=true)
+ $(if $(BOARD_VENDOR_KERNEL_MODULES), \
+ $(call build-image-kernel-modules,$(BOARD_VENDOR_KERNEL_MODULES),$(TARGET_OUT_VENDOR),vendor/,$(call intermediates-dir-for,PACKAGING,depmod_vendor)))
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
./build/tools/releasetools/build_image.py \
$(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
@@ -1520,11 +1732,11 @@
# We just build this directly to the install location.
INSTALLED_VENDORIMAGE_TARGET := $(BUILT_VENDORIMAGE_TARGET)
-$(INSTALLED_VENDORIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_VENDORIMAGE_FILES) $(INSTALLED_FILES_FILE_VENDOR)
+$(INSTALLED_VENDORIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_VENDORIMAGE_FILES) $(INSTALLED_FILES_FILE_VENDOR) $(BUILD_IMAGE_SRCS) $(DEPMOD) $(BOARD_VENDOR_KERNEL_MODULES)
$(build-vendorimage-target)
-.PHONY: vendorimage-nodeps
-vendorimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS)
+.PHONY: vendorimage-nodeps vnod
+vendorimage-nodeps vnod: | $(INTERNAL_USERIMAGES_DEPS) $(DEPMOD)
$(build-vendorimage-target)
else ifdef BOARD_PREBUILT_VENDORIMAGE
@@ -1533,6 +1745,94 @@
endif
# -----------------------------------------------------------------
+# dtbo image
+ifdef BOARD_PREBUILT_DTBOIMAGE
+INSTALLED_DTBOIMAGE_TARGET := $(PRODUCT_OUT)/dtbo.img
+
+ifeq ($(BOARD_AVB_ENABLE),true)
+$(INSTALLED_DTBOIMAGE_TARGET): $(BOARD_PREBUILT_DTBOIMAGE) $(AVBTOOL)
+ cp $(BOARD_PREBUILT_DTBOIMAGE) $@
+ $(AVBTOOL) add_hash_footer \
+ --image $@ \
+ --partition_size $(BOARD_DTBOIMG_PARTITION_SIZE) \
+ --partition_name dtbo $(INTERNAL_AVB_SIGNING_ARGS) \
+ $(BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS)
+else
+$(INSTALLED_DTBOIMAGE_TARGET): $(BOARD_PREBUILT_DTBOIMAGE)
+ cp $(BOARD_PREBUILT_DTBOIMAGE) $@
+endif
+
+endif
+
+# -----------------------------------------------------------------
+# vbmeta image
+ifeq ($(BOARD_AVB_ENABLE),true)
+
+BUILT_VBMETAIMAGE_TARGET := $(PRODUCT_OUT)/vbmeta.img
+
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS := \
+ --include_descriptors_from_image $(INSTALLED_BOOTIMAGE_TARGET) \
+ --include_descriptors_from_image $(INSTALLED_SYSTEMIMAGE) \
+
+ifdef INSTALLED_VENDORIMAGE_TARGET
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+ --include_descriptors_from_image $(INSTALLED_VENDORIMAGE_TARGET)
+endif
+
+ifdef INSTALLED_DTBOIMAGE_TARGET
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+ --include_descriptors_from_image $(INSTALLED_DTBOIMAGE_TARGET)
+endif
+
+ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += --setup_rootfs_from_kernel $(BUILT_SYSTEMIMAGE)
+endif
+
+ifdef BOARD_AVB_ROLLBACK_INDEX
+INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += --rollback_index $(BOARD_AVB_ROLLBACK_INDEX)
+endif
+
+ifndef BOARD_AVB_KEY_PATH
+# If key path isn't specified, use the 4096-bit test key.
+INTERNAL_AVB_SIGNING_ARGS := \
+ --algorithm SHA256_RSA4096 \
+ --key external/avb/test/data/testkey_rsa4096.pem
+else
+INTERNAL_AVB_SIGNING_ARGS := \
+ --algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH)
+endif
+
+ifndef BOARD_BOOTIMAGE_PARTITION_SIZE
+ $(error BOARD_BOOTIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE)
+endif
+
+ifndef BOARD_SYSTEMIMAGE_PARTITION_SIZE
+ $(error BOARD_SYSTEMIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE)
+endif
+
+define build-vbmetaimage-target
+ $(call pretty,"Target vbmeta image: $(INSTALLED_VBMETAIMAGE_TARGET)")
+ $(hide) $(AVBTOOL) make_vbmeta_image \
+ $(INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS) \
+ $(INTERNAL_AVB_SIGNING_ARGS) \
+ $(BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS) \
+ --output $@
+endef
+
+INSTALLED_VBMETAIMAGE_TARGET := $(BUILT_VBMETAIMAGE_TARGET)
+$(INSTALLED_VBMETAIMAGE_TARGET): $(AVBTOOL) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_VENDORIMAGE_TARGET) $(INSTALLED_DTBOIMAGE_TARGET)
+ $(build-vbmetaimage-target)
+
+.PHONY: vbmetaimage-nodeps
+vbmetaimage-nodeps:
+ $(build-vbmetaimage-target)
+
+# We need $(AVBTOOL) for system.img generation.
+FULL_SYSTEMIMAGE_DEPS += $(AVBTOOL)
+
+endif # BOARD_AVB_ENABLE
+
+# -----------------------------------------------------------------
# bring in the installer image generation defines if necessary
ifeq ($(TARGET_USE_DISKINSTALLER),true)
include bootable/diskinstaller/config.mk
@@ -1579,8 +1879,12 @@
$(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar \
$(HOST_OUT_JAVA_LIBRARIES)/signapk.jar \
$(HOST_OUT_JAVA_LIBRARIES)/BootSignature.jar \
- $(HOST_OUT_EXECUTABLES)/mkuserimg.sh \
+ $(HOST_OUT_JAVA_LIBRARIES)/VeritySigner.jar \
$(HOST_OUT_EXECUTABLES)/make_ext4fs \
+ $(HOST_OUT_EXECUTABLES)/mkuserimg.sh \
+ $(HOST_OUT_EXECUTABLES)/mke2fs \
+ $(HOST_OUT_EXECUTABLES)/mkuserimg_mke2fs.sh \
+ $(HOST_OUT_EXECUTABLES)/e2fsdroid \
$(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh \
$(HOST_OUT_EXECUTABLES)/mksquashfs \
$(HOST_OUT_EXECUTABLES)/mkf2fsuserimg.sh \
@@ -1597,6 +1901,7 @@
$(HOST_OUT_EXECUTABLES)/brillo_update_payload \
$(HOST_OUT_EXECUTABLES)/lib/shflags/shflags \
$(HOST_OUT_EXECUTABLES)/delta_generator \
+ $(AVBTOOL) \
$(BLK_ALLOC_TO_BASE_FS)
ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT))
@@ -1612,26 +1917,26 @@
$(HOST_LIBRARY_PATH)/libcutils$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libselinux$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libcrypto-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libdivsufsort$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libdivsufsort64$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libext2fs-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libext2_blkid-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libext2_com_err-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libext2_e2p-host$(HOST_SHLIB_SUFFIX) \
+ $(HOST_LIBRARY_PATH)/libext2_misc$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libext2_profile-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libext2_quota-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libext2_uuid-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libconscrypt_openjdk_jni$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libbrillo$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libbrillo-stream$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libbrillo-http$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libchrome$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libcurl-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libevent-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libprotobuf-cpp-lite$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libssl-host$(HOST_SHLIB_SUFFIX) \
$(HOST_LIBRARY_PATH)/libz-host$(HOST_SHLIB_SUFFIX) \
- $(HOST_LIBRARY_PATH)/libbase$(HOST_SHLIB_SUFFIX)
+ $(HOST_LIBRARY_PATH)/libsparse-host$(HOST_SHLIB_SUFFIX) \
+ $(HOST_LIBRARY_PATH)/libbase$(HOST_SHLIB_SUFFIX) \
+ $(HOST_LIBRARY_PATH)/libpcre2$(HOST_SHLIB_SUFFIX)
.PHONY: otatools
otatools: $(OTATOOLS)
@@ -1639,22 +1944,32 @@
BUILT_OTATOOLS_PACKAGE := $(PRODUCT_OUT)/otatools.zip
$(BUILT_OTATOOLS_PACKAGE): zip_root := $(call intermediates-dir-for,PACKAGING,otatools)/otatools
-$(BUILT_OTATOOLS_PACKAGE): $(OTATOOLS) | $(ACP)
+OTATOOLS_DEPS := \
+ system/extras/verity/build_verity_metadata.py \
+ system/extras/ext4_utils/mke2fs.conf \
+ external/avb/test/data/testkey_rsa4096.pem \
+ $(shell find build/target/product/security -type f -name \*.x509.pem -o -name \*.pk8 -o \
+ -name verity_key | sort) \
+ $(shell find device vendor -type f -name \*.pk8 -o -name verifiedboot\* -o \
+ -name \*.x509.pem -o -name oem\*.prop | sort)
+
+OTATOOLS_RELEASETOOLS := \
+ $(shell find build/tools/releasetools -name \*.pyc -prune -o -type f | sort)
+
+ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT))
+OTATOOLS_DEPS += \
+ $(shell find external/vboot_reference/tests/devkeys -type f | sort)
+endif
+
+$(BUILT_OTATOOLS_PACKAGE): $(OTATOOLS) $(OTATOOLS_DEPS) $(OTATOOLS_RELEASETOOLS) | $(ACP)
@echo "Package OTA tools: $@"
$(hide) rm -rf $@ $(zip_root)
- $(hide) mkdir -p $(dir $@) $(zip_root)/bin $(zip_root)/framework $(zip_root)/releasetools $(zip_root)/system/extras/verity
+ $(hide) mkdir -p $(dir $@) $(zip_root)/bin $(zip_root)/framework $(zip_root)/releasetools
$(call copy-files-with-structure,$(OTATOOLS),$(HOST_OUT)/,$(zip_root))
- $(hide) $(ACP) $(HOST_OUT_JAVA_LIBRARIES)/VeritySigner.jar $(zip_root)/framework/
- $(hide) $(ACP) -p system/extras/verity/build_verity_metadata.py $(zip_root)/system/extras/verity/
$(hide) $(ACP) -r -d -p build/tools/releasetools/* $(zip_root)/releasetools
-ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT))
- $(hide) mkdir -p $(zip_root)/external/vboot_reference/tests/devkeys
- $(hide) $(ACP) -r -d -p external/vboot_reference/tests/devkeys/* $(zip_root)/external/vboot_reference/tests/devkeys
-endif
$(hide) rm -rf $@ $(zip_root)/releasetools/*.pyc
$(hide) (cd $(zip_root) && zip -qryX $(abspath $@) *)
- $(hide) zip -qryX $(abspath $@) build/target/product/security/
- $(hide) find device vendor -name \*.pk8 -o -name verifiedboot\* -o -name \*.x509.pem -o -name oem\*.prop | xargs zip -qryX $(abspath $@)>/dev/null || true
+ $(hide) echo $(OTATOOLS_DEPS) | xargs zip -qryX $(abspath $@)>/dev/null || true
.PHONY: otatools-package
otatools-package: $(BUILT_OTATOOLS_PACKAGE)
@@ -1703,15 +2018,23 @@
ifeq ($(TARGET_RELEASETOOLS_EXTENSIONS),)
# default to common dir for device vendor
-$(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_DEVICE_DIR)/../common
+tool_extensions := $(TARGET_DEVICE_DIR)/../common
else
-$(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)
+tool_extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)
endif
+tool_extension := $(wildcard $(tool_extensions)/releasetools.py)
+$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_TOOL_EXTENSIONS := $(tool_extensions)
+$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_TOOL_EXTENSION := $(tool_extension)
+ifeq ($(AB_OTA_UPDATER),true)
+# Build zlib fingerprint if using the AB Updater.
+updater_dep := $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint
+updater_dep += system/update_engine/update_engine.conf
+else
# Build OTA tools if not using the AB Updater.
-ifneq ($(AB_OTA_UPDATER),true)
-$(BUILT_TARGET_FILES_PACKAGE): $(built_ota_tools)
+updater_dep := $(built_ota_tools)
endif
+$(BUILT_TARGET_FILES_PACKAGE): $(updater_dep)
# If we are using recovery as boot, output recovery files to BOOT/.
ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
@@ -1720,24 +2043,53 @@
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_RECOVERY_OUT := RECOVERY
endif
+ifeq ($(AB_OTA_UPDATER),true)
+ ifdef BRILLO_VENDOR_PARTITIONS
+ $(BUILT_TARGET_FILES_PACKAGE): $(foreach p,$(BRILLO_VENDOR_PARTITIONS),\
+ $(call word-colon,1,$(p))/$(call word-colon,2,$(p)))
+ endif
+ ifdef OSRELEASED_DIRECTORY
+ $(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_id
+ $(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_version
+ $(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/system_version
+ endif
+endif
+
+# Run fs_config while creating the target files package
+# $1: root directory
+# $2: add prefix
+define fs_config
+(cd $(1); find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,$(2),' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC)
+endef
+
# Depending on the various images guarantees that the underlying
# directories are up-to-date.
$(BUILT_TARGET_FILES_PACKAGE): \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_RADIOIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
- $(INSTALLED_SYSTEMIMAGE) \
+ $(FULL_SYSTEMIMAGE_DEPS) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
- $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
+ $(INSTALLED_DTBOIMAGE_TARGET) \
+ $(INTERNAL_SYSTEMOTHERIMAGE_FILES) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
+ $(INSTALLED_KERNEL_TARGET) \
+ $(INSTALLED_2NDBOOTLOADER_TARGET) \
+ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH) \
+ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
$(SELINUX_FC) \
$(APKCERTS_FILE) \
+ $(SOONG_ZIP) \
$(HOST_OUT_EXECUTABLES)/fs_config \
+ $(HOST_OUT_EXECUTABLES)/imgdiff \
+ $(HOST_OUT_EXECUTABLES)/bsdiff \
+ $(BUILD_IMAGE_SRCS) \
| $(ACP)
@echo "Package target files: $@"
- $(hide) rm -rf $@ $(zip_root)
+ $(call create-system-vendor-symlink)
+ $(hide) rm -rf $@ $@.list $(zip_root)
$(hide) mkdir -p $(dir $@) $(zip_root)
ifneq (,$(INSTALLED_RECOVERYIMAGE_TARGET)$(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
@# Components of the recovery image
@@ -1745,14 +2097,13 @@
$(hide) $(call package_files-copy-root, \
$(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/$(PRIVATE_RECOVERY_OUT)/RAMDISK)
ifdef INSTALLED_KERNEL_TARGET
- $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/kernel
+ $(hide) cp $(INSTALLED_KERNEL_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/kernel
endif
ifdef INSTALLED_2NDBOOTLOADER_TARGET
- $(hide) $(ACP) \
- $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/second
+ $(hide) cp $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/$(PRIVATE_RECOVERY_OUT)/second
endif
-ifdef BOARD_KERNEL_CMDLINE
- $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/$(PRIVATE_RECOVERY_OUT)/cmdline
+ifdef INTERNAL_KERNEL_CMDLINE
+ $(hide) echo "$(INTERNAL_KERNEL_CMDLINE)" > $(zip_root)/$(PRIVATE_RECOVERY_OUT)/cmdline
endif
ifdef BOARD_KERNEL_BASE
$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/$(PRIVATE_RECOVERY_OUT)/base
@@ -1774,14 +2125,13 @@
@# If we are using recovery as boot, this is already done when processing recovery.
ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
ifdef INSTALLED_KERNEL_TARGET
- $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel
+ $(hide) cp $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel
endif
ifdef INSTALLED_2NDBOOTLOADER_TARGET
- $(hide) $(ACP) \
- $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/second
+ $(hide) cp $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/second
endif
-ifdef BOARD_KERNEL_CMDLINE
- $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline
+ifdef INTERNAL_KERNEL_CMDLINE
+ $(hide) echo "$(INTERNAL_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline
endif
ifdef BOARD_KERNEL_BASE
$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base
@@ -1792,7 +2142,7 @@
endif # BOARD_USES_RECOVERY_AS_BOOT
$(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),\
mkdir -p $(zip_root)/RADIO; \
- $(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)
+ cp $(t) $(zip_root)/RADIO/$(notdir $(t));)
@# Contents of the system image
$(hide) $(call package_files-copy-root, \
$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
@@ -1811,20 +2161,22 @@
endif
@# Extra contents of the OTA package
$(hide) mkdir -p $(zip_root)/OTA
- $(hide) $(ACP) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/
+ $(hide) cp $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/
ifneq ($(AB_OTA_UPDATER),true)
ifneq ($(built_ota_tools),)
$(hide) mkdir -p $(zip_root)/OTA/bin
- $(hide) $(ACP) $(PRIVATE_OTA_TOOLS) $(zip_root)/OTA/bin/
+ $(hide) cp $(PRIVATE_OTA_TOOLS) $(zip_root)/OTA/bin/
endif
endif
@# Files that do not end up in any images, but are necessary to
@# build them.
$(hide) mkdir -p $(zip_root)/META
- $(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
- $(hide) if test -e $(tool_extensions)/releasetools.py; then $(ACP) $(tool_extensions)/releasetools.py $(zip_root)/META/; fi
+ $(hide) cp $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
+ifneq ($(tool_extension),)
+ $(hide) cp $(PRIVATE_TOOL_EXTENSION) $(zip_root)/META/
+endif
$(hide) echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
- $(hide) $(ACP) $(SELINUX_FC) $(zip_root)/META/file_contexts.bin
+ $(hide) cp $(SELINUX_FC) $(zip_root)/META/file_contexts.bin
$(hide) echo "recovery_api_version=$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/misc_info.txt
$(hide) echo "fstab_version=$(PRIVATE_RECOVERY_FSTAB_VERSION)" >> $(zip_root)/META/misc_info.txt
ifdef BOARD_FLASH_BLOCK_SIZE
@@ -1851,27 +2203,25 @@
else
$(hide) echo "recovery_mount_options=$(DEFAULT_TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
endif
- $(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "tool_extensions=$(PRIVATE_TOOL_EXTENSIONS)" >> $(zip_root)/META/misc_info.txt
$(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $(zip_root)/META/misc_info.txt
ifdef PRODUCT_EXTRA_RECOVERY_KEYS
$(hide) echo "extra_recovery_keys=$(PRODUCT_EXTRA_RECOVERY_KEYS)" >> $(zip_root)/META/misc_info.txt
endif
$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $(zip_root)/META/misc_info.txt
$(hide) echo 'mkbootimg_version_args=$(INTERNAL_MKBOOTIMG_VERSION_ARGS)' >> $(zip_root)/META/misc_info.txt
- $(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
- $(hide) echo "update_rename_support=1" >> $(zip_root)/META/misc_info.txt
- $(hide) echo "blockimgdiff_versions=1,2,3,4" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "blockimgdiff_versions=3,4" >> $(zip_root)/META/misc_info.txt
ifneq ($(OEM_THUMBPRINT_PROPERTIES),)
# OTA scripts are only interested in fingerprint related properties
$(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt
endif
ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH),)
- $(hide) $(ACP) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH) \
+ $(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH) \
$(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH))
endif
ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH),)
- $(hide) $(ACP) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
+ $(hide) cp $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH) \
$(zip_root)/META/$(notdir $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH))
endif
ifneq ($(strip $(SANITIZE_TARGET)),)
@@ -1881,6 +2231,20 @@
ifeq ($(BOARD_USES_FULL_RECOVERY_IMAGE),true)
$(hide) echo "full_recovery_image=true" >> $(zip_root)/META/misc_info.txt
endif
+ifeq ($(BOARD_AVB_ENABLE),true)
+ $(hide) echo "board_avb_enable=true" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "board_avb_rollback_index=$(BOARD_AVB_ROLLBACK_INDEX)" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "board_avb_boot_add_hash_footer_args=$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "board_avb_make_vbmeta_image_args=$(BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS)" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_BPT_INPUT_FILES
+ $(hide) echo "board_bpt_enable=true" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "board_bpt_make_table_args=$(BOARD_BPT_MAKE_TABLE_ARGS)" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "board_bpt_input_files=$(BOARD_BPT_INPUT_FILES)" >> $(zip_root)/META/misc_info.txt
+endif
+ifdef BOARD_BPT_DISK_SIZE
+ $(hide) echo "board_bpt_disk_size=$(BOARD_BPT_DISK_SIZE)" >> $(zip_root)/META/misc_info.txt
+endif
$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
@@ -1888,7 +2252,8 @@
endif
ifeq ($(AB_OTA_UPDATER),true)
@# When using the A/B updater, include the updater config files in the zip.
- $(hide) $(ACP) $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt
+ $(hide) cp $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt
+ $(hide) cp $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint $(zip_root)/META/zlib_fingerprint.txt
$(hide) for part in $(AB_OTA_PARTITIONS); do \
echo "$${part}" >> $(zip_root)/META/ab_partitions.txt; \
done
@@ -1898,9 +2263,21 @@
@# Include the build type in META/misc_info.txt so the server can easily differentiate production builds.
$(hide) echo "build_type=$(TARGET_BUILD_VARIANT)" >> $(zip_root)/META/misc_info.txt
$(hide) echo "ab_update=true" >> $(zip_root)/META/misc_info.txt
+ifdef BRILLO_VENDOR_PARTITIONS
+ $(hide) mkdir -p $(zip_root)/VENDOR_IMAGES
+ $(hide) for f in $(BRILLO_VENDOR_PARTITIONS); do \
+ pair1="$$(echo $$f | awk -F':' '{print $$1}')"; \
+ pair2="$$(echo $$f | awk -F':' '{print $$2}')"; \
+ src=$${pair1}/$${pair2}; \
+ dest=$(zip_root)/VENDOR_IMAGES/$${pair2}; \
+ mkdir -p $$(dirname "$${dest}"); \
+ cp $${src} $${dest}; \
+ done;
+endif
ifdef OSRELEASED_DIRECTORY
- $(hide) $(ACP) $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/product_id $(zip_root)/META/product_id.txt
- $(hide) $(ACP) $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/product_version $(zip_root)/META/product_version.txt
+ $(hide) cp $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_id $(zip_root)/META/product_id.txt
+ $(hide) cp $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_version $(zip_root)/META/product_version.txt
+ $(hide) cp $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/system_version $(zip_root)/META/system_version.txt
endif
endif
ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true)
@@ -1911,28 +2288,39 @@
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_VENDORIMAGE_TARGET) $(zip_root)/IMAGES/
endif
- @# Zip everything up, preserving symlinks and placing META/ files first to
- @# help early validation of the .zip file while uploading it.
- $(hide) (cd $(zip_root) && \
- zip -qryX ../$(notdir $@) ./META && \
- zip -qryXu ../$(notdir $@) .)
+ifdef BOARD_PREBUILT_DTBOIMAGE
+ $(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
+ $(hide) cp $(INSTALLED_DTBOIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
+ $(hide) echo "has_dtbo=true" >> $(zip_root)/META/misc_info.txt
+ifeq ($(BOARD_AVB_ENABLE),true)
+ $(hide) echo "dtbo_size=$(BOARD_DTBOIMG_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
+ $(hide) echo "board_avb_dtbo_add_hash_footer_args=$(BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS)" \
+ >> $(zip_root)/META/misc_info.txt
+endif
+endif
@# Run fs_config on all the system, vendor, boot ramdisk,
@# and recovery ramdisk files in the zip, and save the output
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/filesystem_config.txt
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="VENDOR/" } /^VENDOR\// {print "vendor/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/vendor_filesystem_config.txt
-ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="ROOT/" } /^ROOT\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/root_filesystem_config.txt
+ $(hide) $(call fs_config,$(zip_root)/SYSTEM,system/) > $(zip_root)/META/filesystem_config.txt
+ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
+ $(hide) $(call fs_config,$(zip_root)/VENDOR,vendor/) > $(zip_root)/META/vendor_filesystem_config.txt
endif
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="BOOT/RAMDISK/" } /^BOOT\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/boot_filesystem_config.txt
+ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+ $(hide) $(call fs_config,$(zip_root)/ROOT,) > $(zip_root)/META/root_filesystem_config.txt
+endif
+ $(hide) $(call fs_config,$(zip_root)/BOOT/RAMDISK,) > $(zip_root)/META/boot_filesystem_config.txt
ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/recovery_filesystem_config.txt
+ $(hide) $(call fs_config,$(zip_root)/RECOVERY/RAMDISK,) > $(zip_root)/META/recovery_filesystem_config.txt
endif
ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
- $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM_OTHER/" } /^SYSTEM_OTHER\// { print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/system_other_filesystem_config.txt
+ $(hide) $(call fs_config,$(zip_root)/SYSTEM_OTHER,system/) > $(zip_root)/META/system_other_filesystem_config.txt
endif
- $(hide) (cd $(zip_root) && zip -qX ../$(notdir $@) META/*filesystem_config.txt)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
- ./build/tools/releasetools/add_img_to_target_files -a -v -p $(HOST_OUT) $@
+ ./build/tools/releasetools/add_img_to_target_files -a -v -p $(HOST_OUT) $(zip_root)
+ @# Zip everything up, preserving symlinks and placing META/ files first to
+ @# help early validation of the .zip file while uploading it.
+ $(hide) find $(zip_root)/META | sort >$@.list
+ $(hide) find $(zip_root) -path $(zip_root)/META -prune -o -print | sort >>$@.list
+ $(hide) $(SOONG_ZIP) -d -o $@ -C $(zip_root) -l $@.list
.PHONY: target-files-package
target-files-package: $(BUILT_TARGET_FILES_PACKAGE)
@@ -1941,6 +2329,15 @@
$(call dist-for-goals, target-files-package, $(BUILT_TARGET_FILES_PACKAGE))
endif
+# -----------------------------------------------------------------
+# NDK Sysroot Package
+NDK_SYSROOT_TARGET := $(PRODUCT_OUT)/ndk_sysroot.tar.bz2
+$(NDK_SYSROOT_TARGET): ndk
+ @echo Package NDK sysroot...
+ $(hide) tar cjf $@ -C $(SOONG_OUT_DIR) ndk
+
+$(call dist-for-goals,sdk,$(NDK_SYSROOT_TARGET))
+
ifeq ($(build_ota_package),true)
# -----------------------------------------------------------------
# OTA update package
@@ -1955,11 +2352,17 @@
$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
-$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE)
+ifeq ($(AB_OTA_UPDATER),true)
+$(INTERNAL_OTA_PACKAGE_TARGET): $(BRILLO_UPDATE_PAYLOAD)
+endif
+
+$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) \
+ build/tools/releasetools/ota_from_target_files
@echo "Package OTA: $@"
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
./build/tools/releasetools/ota_from_target_files -v \
--block \
+ --extracted_input_target_files $(patsubst %.zip,%,$(BUILT_TARGET_FILES_PACKAGE)) \
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
$(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
@@ -1981,12 +2384,10 @@
INTERNAL_UPDATE_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
-$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE)
+$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(ZIP2ZIP)
@echo "Package: $@"
- $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
- ./build/tools/releasetools/img_from_target_files -v \
- -p $(HOST_OUT) \
- $(BUILT_TARGET_FILES_PACKAGE) $@
+ $(hide) $(ZIP2ZIP) -i $(BUILT_TARGET_FILES_PACKAGE) -o $@ \
+ OTA/android-info.txt:android-info.txt "IMAGES/*.img:."
.PHONY: updatepackage
updatepackage: $(INTERNAL_UPDATE_PACKAGE_TARGET)
@@ -2004,13 +2405,41 @@
SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
# For apps_only build we'll establish the dependency later in build/core/main.mk.
ifndef TARGET_BUILD_APPS
-$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_BOOTIMAGE_TARGET)
+$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ $(INSTALLED_VENDORIMAGE_TARGET) \
+ $(updater_dep)
endif
-$(SYMBOLS_ZIP):
+$(SYMBOLS_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,symbols)/filelist
+$(SYMBOLS_ZIP): $(SOONG_ZIP)
@echo "Package symbols: $@"
- $(hide) rm -rf $@
- $(hide) mkdir -p $(dir $@) $(TARGET_OUT_UNSTRIPPED)
- $(hide) zip -qrX $@ $(TARGET_OUT_UNSTRIPPED)
+ $(hide) rm -rf $@ $(PRIVATE_LIST_FILE)
+ $(hide) mkdir -p $(dir $@) $(TARGET_OUT_UNSTRIPPED) $(dir $(PRIVATE_LIST_FILE))
+ $(hide) find $(TARGET_OUT_UNSTRIPPED) | sort >$(PRIVATE_LIST_FILE)
+ $(hide) $(SOONG_ZIP) -d -o $@ -C $(OUT_DIR)/.. -l $(PRIVATE_LIST_FILE)
+# -----------------------------------------------------------------
+# A zip of the coverage directory.
+#
+name := $(TARGET_PRODUCT)
+ifeq ($(TARGET_BUILD_TYPE),debug)
+name := $(name)_debug
+endif
+name := $(name)-coverage-$(FILE_NAME_TAG)
+COVERAGE_ZIP := $(PRODUCT_OUT)/$(name).zip
+ifndef TARGET_BUILD_APPS
+$(COVERAGE_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+ $(INSTALLED_BOOTIMAGE_TARGET) \
+ $(INSTALLED_USERDATAIMAGE_TARGET) \
+ $(INSTALLED_VENDORIMAGE_TARGET)
+endif
+$(COVERAGE_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,coverage)/filelist
+$(COVERAGE_ZIP): $(SOONG_ZIP)
+ @echo "Package coverage: $@"
+ $(hide) rm -rf $@ $(PRIVATE_LIST_FILE)
+ $(hide) mkdir -p $(dir $@) $(TARGET_OUT_COVERAGE) $(dir $(PRIVATE_LIST_FILE))
+ $(hide) find $(TARGET_OUT_COVERAGE) | sort >$(PRIVATE_LIST_FILE)
+ $(hide) $(SOONG_ZIP) -d -o $@ -C $(TARGET_OUT_COVERAGE) -l $(PRIVATE_LIST_FILE)
# -----------------------------------------------------------------
# A zip of the Android Apps. Not keeping full path so that we don't
@@ -2135,7 +2564,6 @@
# if we don't have a real list, then use "everything"
ifeq ($(strip $(ATREE_FILES)),)
ATREE_FILES := \
- $(ALL_PREBUILT) \
$(ALL_DEFAULT_INSTALLED_MODULES) \
$(INSTALLED_RAMDISK_TARGET) \
$(ALL_DOCS) \
@@ -2170,6 +2598,7 @@
$(tools_notice_file_txt) \
$(OUT_DOCS)/offline-sdk-timestamp \
$(SYMBOLS_ZIP) \
+ $(COVERAGE_ZIP) \
$(INSTALLED_SYSTEMIMAGE) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_RAMDISK_TARGET) \
@@ -2267,6 +2696,9 @@
-include $(sort $(wildcard vendor/*/*/build/tasks/*.mk))
-include $(sort $(wildcard device/*/*/build/tasks/*.mk))
-include $(sort $(wildcard product/*/*/build/tasks/*.mk))
+# Also add test specifc tasks
+include $(sort $(wildcard platform_testing/build/tasks/*.mk))
+include $(sort $(wildcard test/vts/tools/build/tasks/*.mk))
endif
include $(BUILD_SYSTEM)/product-graph.mk
diff --git a/core/WINPTHREADS_COPYING b/core/WINPTHREADS_COPYING
new file mode 100644
index 0000000..3507701
--- /dev/null
+++ b/core/WINPTHREADS_COPYING
@@ -0,0 +1,57 @@
+Copyright (c) 2011 mingw-w64 project
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+
+/*
+ * Parts of this library are derived by:
+ *
+ * Posix Threads library for Microsoft Windows
+ *
+ * Use at own risk, there is no implied warranty to this code.
+ * It uses undocumented features of Microsoft Windows that can change
+ * at any time in the future.
+ *
+ * (C) 2010 Lockless Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Lockless Inc. nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/core/aux_config.mk b/core/aux_config.mk
new file mode 100644
index 0000000..c40b8cc
--- /dev/null
+++ b/core/aux_config.mk
@@ -0,0 +1,187 @@
+variant_list := $(filter AUX-%,$(MAKECMDGOALS))
+
+ifdef variant_list
+AUX_OS_VARIANT_LIST := $(patsubst AUX-%,%,$(variant_list))
+else
+AUX_OS_VARIANT_LIST := $(TARGET_AUX_OS_VARIANT_LIST)
+endif
+
+# exclude AUX targets from build
+ifeq ($(AUX_OS_VARIANT_LIST),none)
+AUX_OS_VARIANT_LIST :=
+endif
+
+# temporary workaround to support external toolchain
+ifeq ($(NANOHUB_TOOLCHAIN),)
+AUX_OS_VARIANT_LIST :=
+endif
+
+# setup toolchain paths for various CPU architectures
+# this one will come from android prebuilts eventually
+AUX_TOOLCHAIN_cortexm4 := $(NANOHUB_TOOLCHAIN)
+ifeq ($(wildcard $(AUX_TOOLCHAIN_cortexm4)gcc),)
+AUX_TOOLCHAIN_cortexm4:=
+endif
+
+# there is no MAKE var that defines path to HOST toolchain
+# all the interesting paths are hardcoded in soong, and are not available from here
+# There is no other way but to hardcode them again, as we may need host x86 toolcain for AUX
+ifeq ($(HOST_OS),linux)
+AUX_TOOLCHAIN_x86 := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/bin/x86_64-linux-
+endif
+
+# setup AUX globals
+AUX_SHLIB_SUFFIX := .so
+AUX_GLOBAL_ARFLAGS := crsPD
+AUX_STATIC_LIB_SUFFIX := .a
+
+# Load ever-lasting "indexed" version of AUX variant environment; it is treated as READ-ONLY from this
+# moment on.
+#
+# $(1) - variant
+# no return value
+define aux-variant-setup-paths
+$(eval AUX_OUT_ROOT_$(1) := $(PRODUCT_OUT)/aux/$(1)) \
+$(eval AUX_COMMON_OUT_ROOT_$(1) := $(AUX_OUT_ROOT_$(1))/common) \
+$(eval AUX_OUT_$(1) := $(AUX_OUT_ROOT_$(1))/$(AUX_OS_$(1))-$(AUX_ARCH_$(1))-$(AUX_CPU_$(1))) \
+$(eval AUX_OUT_INTERMEDIATES_$(1) := $(AUX_OUT_$(1))/obj) \
+$(eval AUX_OUT_COMMON_INTERMEDIATES_$(1) := $(AUX_COMMON_OUT_ROOT_$(1))/obj) \
+$(eval AUX_OUT_HEADERS_$(1) := $(AUX_OUT_INTERMEDIATES_$(1))/include) \
+$(eval AUX_OUT_INTERMEDIATE_LIBRARIES_$(1) := $(AUX_OUT_INTERMEDIATES_$(1))/lib) \
+$(eval AUX_OUT_NOTICE_FILES_$(1) := $(AUX_OUT_INTERMEDIATES_$(1))/NOTICE_FILES) \
+$(eval AUX_OUT_FAKE_$(1) := $(AUX_OUT_$(1))/fake_packages) \
+$(eval AUX_OUT_GEN_$(1) := $(AUX_OUT_$(1))/gen) \
+$(eval AUX_OUT_COMMON_GEN_$(1) := $(AUX_COMMON_OUT_ROOT_$(1))/gen) \
+$(eval AUX_OUT_EXECUTABLES_$(1) := $(AUX_OUT_$(1))/bin) \
+$(eval AUX_OUT_UNSTRIPPED_$(1) := $(AUX_OUT_$(1))/symbols)
+endef
+
+# Copy "indexed" AUX environment for given VARIANT into
+# volatile not-indexed set of variables for simplicity of access.
+# Injection of index support throughout the build system is suboptimal
+# hence volatile environment is constructed
+# Unlike HOST*, TARGET* variables, AUX* variables are NOT read-only, but their
+# indexed versions are.
+#
+# $(1) - variant
+# no return value
+define aux-variant-load-env
+$(eval AUX_OS_VARIANT:=$(1)) \
+$(eval AUX_OS:=$(AUX_OS_$(1))) \
+$(eval AUX_ARCH:=$(AUX_ARCH_$(1))) \
+$(eval AUX_SUBARCH:=$(AUX_SUBARCH_$(1))) \
+$(eval AUX_CPU:=$(AUX_CPU_$(1))) \
+$(eval AUX_OS_PATH:=$(AUX_OS_PATH_$(1))) \
+$(eval AUX_OUT_ROOT := $(AUX_OUT_ROOT_$(1))) \
+$(eval AUX_COMMON_OUT_ROOT := $(AUX_COMMON_OUT_ROOT_$(1))) \
+$(eval AUX_OUT := $(AUX_OUT_$(1))) \
+$(eval AUX_OUT_INTERMEDIATES := $(AUX_OUT_INTERMEDIATES_$(1))) \
+$(eval AUX_OUT_COMMON_INTERMEDIATES := $(AUX_OUT_COMMON_INTERMEDIATES_$(1))) \
+$(eval AUX_OUT_HEADERS := $(AUX_OUT_HEADERS_$(1))) \
+$(eval AUX_OUT_INTERMEDIATE_LIBRARIES := $(AUX_OUT_INTERMEDIATE_LIBRARIES_$(1))) \
+$(eval AUX_OUT_NOTICE_FILES := $(AUX_OUT_NOTICE_FILES_$(1))) \
+$(eval AUX_OUT_FAKE := $(AUX_OUT_FAKE_$(1))) \
+$(eval AUX_OUT_GEN := $(AUX_OUT_GEN_$(1))) \
+$(eval AUX_OUT_COMMON_GEN := $(AUX_OUT_COMMON_GEN_$(1))) \
+$(eval AUX_OUT_EXECUTABLES := $(AUX_OUT_EXECUTABLES_$(1))) \
+$(eval AUX_OUT_UNSTRIPPED := $(AUX_OUT_UNSTRIPPED_$(1)))
+endef
+
+# given a variant:path pair, load the variant conviguration with aux-variant-setup-paths from file
+# this is a build system extension mechainsm, since configuration typically resides in non-build
+# project space
+#
+# $(1) - variant:path pair
+# $(2) - file suffix
+# no return value
+define aux-variant-import-from-pair
+$(eval _pair := $(subst :, ,$(1))) \
+$(eval _name:=$(word 1,$(_pair))) \
+$(eval _path:=$(word 2,$(_pair))) \
+$(eval include $(_path)/$(_name)$(2)) \
+$(eval AUX_OS_VARIANT_LIST_$(AUX_OS_$(1)):=) \
+$(call aux-variant-setup-paths,$(_name)) \
+$(eval AUX_ALL_VARIANTS += $(_name)) \
+$(eval AUX_ALL_OSES := $(filterout $(AUX_OS_$(_name)),$(AUX_ALL_OSES)) $(AUX_OS_$(_name))) \
+$(eval AUX_ALL_CPUS := $(filterout $(AUX_CPU_$(_name)),$(AUX_ALL_CPUS)) $(AUX_CPU_$(_name))) \
+$(eval AUX_ALL_ARCHS := $(filterout $(AUX_ARCH_$(_name)),$(AUX_ALL_ARCHS)) $(AUX_ARCH_$(_name))) \
+$(eval AUX_ALL_SUBARCHS := $(filterout $(AUX_SUBARCH_$(_name)),$(AUX_ALL_SUBARCHS)) $(AUX_SUBARCH_$(_name)))
+endef
+
+# Load system configuration referenced by AUX variant config;
+# this is a build extension mechanism; typically system config
+# resides in a non-build projects;
+# system config may define new rules and globally visible BUILD*
+# includes to support project-specific build steps and toolchains
+# MAintains list of valiants that reference this os config in OS "indexed" var
+# this facilitates multivariant build of the OS (or whataver it is the name of common component these variants share)
+#
+# $(1) - variant
+# no return value
+define aux-import-os-config
+$(eval _aioc_os := $(AUX_OS_$(1))) \
+$(eval AUX_OS_PATH_$(1) := $(patsubst $(_aioc_os):%,%,$(filter $(_aioc_os):%,$(AUX_ALL_OS_PATHS)))) \
+$(eval _aioc_os_cfg := $(AUX_OS_PATH_$(1))/$(_aioc_os)$(os_sfx)) \
+$(if $(wildcard $(_aioc_os_cfg)),,$(error AUX '$(_aioc_os)' OS config file [$(notdir $(_aioc_os_cfg))] required by AUX variant '$(1)' does not exist)) \
+$(if $(filter $(_aioc_os),$(_os_list)),,$(eval include $(_aioc_os_cfg))) \
+$(eval AUX_OS_VARIANT_LIST_$(_aioc_os) += $(1)) \
+$(eval _os_list += $(_aioc_os))
+endef
+
+# make sure that AUX config variables are minimally sane;
+# as a bare minimum they must contain the vars described by aux_env
+# Generate error if requirement is not met.
+#
+#$(1) - variant
+# no return value
+define aux-variant-validate
+$(eval _all:=) \
+$(eval _req:=$(addsuffix _$(1),$(aux_env))) \
+$(foreach var,$(_req),$(eval _all += $(var))) \
+$(eval _missing := $(filterout $(_all),$(_req))) \
+$(if $(_missing),$(error AUX variant $(1) must define vars: $(_missing)))
+endef
+
+AUX_ALL_VARIANTS :=
+AUX_ALL_OSES :=
+AUX_ALL_CPUS :=
+AUX_ALL_ARCHS :=
+AUX_ALL_SUBARCHS :=
+
+variant_sfx :=_aux_variant_config.mk
+os_sfx :=_aux_os_config.mk
+
+config_roots := $(wildcard device vendor)
+all_configs :=
+ifdef config_roots
+all_configs := $(shell find $(config_roots) -maxdepth 4 -name '*$(variant_sfx)' -o -name '*$(os_sfx)' | sort)
+endif
+all_os_configs := $(filter %$(os_sfx),$(all_configs))
+all_variant_configs := $(filter %$(variant_sfx),$(all_configs))
+
+AUX_ALL_OS_PATHS := $(foreach f,$(all_os_configs),$(patsubst %$(os_sfx),%,$(notdir $(f))):$(patsubst %/,%,$(dir $(f))))
+AUX_ALL_OS_VARIANT_PATHS := $(foreach f,$(all_variant_configs),$(patsubst %$(variant_sfx),%,$(notdir $(f))):$(patsubst %/,%,$(dir $(f))))
+
+my_variant_pairs := $(foreach v,$(AUX_OS_VARIANT_LIST),$(filter $(v):%,$(AUX_ALL_OS_VARIANT_PATHS)))
+my_missing_variants := $(foreach v,$(AUX_OS_VARIANT_LIST),$(if $(filter $(v):%,$(AUX_ALL_OS_VARIANT_PATHS)),,$(v)))
+
+ifneq ($(strip $(my_missing_variants)),)
+$(error Don't know how to build variant(s): $(my_missing_variants))
+endif
+
+# mandatory variables
+aux_env := AUX_OS AUX_ARCH AUX_SUBARCH AUX_CPU
+
+$(foreach v,$(my_variant_pairs),$(if $(filter $(v),$(AUX_ALL_VARIANTS)),,$(call aux-variant-import-from-pair,$(v),$(variant_sfx))))
+
+ifdef AUX_ALL_VARIANTS
+_os_list :=
+$(foreach v,$(AUX_ALL_VARIANTS),\
+ $(call aux-import-os-config,$(v)) \
+ $(call aux-variant-validate,$(v)) \
+)
+endif
+
+INSTALLED_AUX_TARGETS :=
+
+droidcore: auxiliary
diff --git a/core/aux_executable.mk b/core/aux_executable.mk
new file mode 100644
index 0000000..daf30e7
--- /dev/null
+++ b/core/aux_executable.mk
@@ -0,0 +1,96 @@
+# caller might have included aux_toolchain, e.g. if custom build steps are defined
+ifeq ($(LOCAL_IS_AUX_MODULE),)
+include $(BUILD_SYSTEM)/aux_toolchain.mk
+endif
+
+ifeq ($(AUX_BUILD_NOT_COMPATIBLE),)
+
+###########################################################
+## Standard rules for building an executable file.
+##
+## Additional inputs from base_rules.make:
+## None.
+###########################################################
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := EXECUTABLES
+endif
+
+$(call $(aux-executable-hook))
+
+###########################################################
+## Standard rules for building any target-side binaries
+## with dynamic linkage (dynamic libraries or executables
+## that link with dynamic libraries)
+##
+## Files including this file must define a rule to build
+## the target $(linked_module).
+###########################################################
+
+# The name of the target file, without any path prepended.
+# This duplicates logic from base_rules.mk because we need to
+# know its results before base_rules.mk is included.
+include $(BUILD_SYSTEM)/configure_module_stem.mk
+
+intermediates := $(call local-intermediates-dir)
+
+# Define the target that is the unmodified output of the linker.
+# The basename of this target must be the same as the final output
+# binary name, because it's used to set the "soname" in the binary.
+# The includer of this file will define a rule to build this target.
+linked_module := $(intermediates)/LINKED/$(my_built_module_stem)
+
+ALL_ORIGINAL_DYNAMIC_BINARIES += $(linked_module)
+
+# Because AUX_SYMBOL_FILTER_FILE depends on ALL_ORIGINAL_DYNAMIC_BINARIES,
+# the linked_module rules won't necessarily inherit the PRIVATE_
+# variables from LOCAL_BUILT_MODULE. This tells binary.make to explicitly
+# define the PRIVATE_ variables for linked_module as well as for
+# LOCAL_BUILT_MODULE.
+LOCAL_INTERMEDIATE_TARGETS += $(linked_module)
+
+###################################
+include $(BUILD_SYSTEM)/binary.mk
+###################################
+
+aux_output := $(linked_module)
+
+ifneq ($(LOCAL_CUSTOM_BUILD_STEP_INPUT),)
+ifneq ($(LOCAL_CUSTOM_BUILD_STEP_OUTPUT),)
+
+# injecting custom build steps
+$(LOCAL_CUSTOM_BUILD_STEP_INPUT): $(aux_output)
+ @echo "$(AUX_DISPLAY) custom copy: $(PRIVATE_MODULE) ($@)"
+ @mkdir -p $(dir $@)
+ $(hide) $(copy-file-to-target)
+
+aux_output := $(LOCAL_CUSTOM_BUILD_STEP_OUTPUT)
+
+endif
+endif
+
+$(LOCAL_BUILT_MODULE): $(aux_output)
+ @echo "$(AUX_DISPLAY) final copy: $(PRIVATE_MODULE) ($@)"
+ @mkdir -p $(dir $@)
+ $(hide) $(copy-file-to-target)
+
+INSTALLED_AUX_TARGETS += $(LOCAL_INSTALLED_MODULE)
+
+$(cleantarget): PRIVATE_CLEAN_FILES += \
+ $(linked_module) \
+
+# Define PRIVATE_ variables from global vars
+$(linked_module): PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES := $(AUX_OUT_INTERMEDIATE_LIBRARIES)
+$(linked_module): PRIVATE_POST_LINK_CMD := $(LOCAL_POST_LINK_CMD)
+
+ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+$(linked_module): $(all_objects) $(all_libraries) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(transform-o-to-aux-static-executable)
+ $(PRIVATE_POST_LINK_CMD)
+else
+$(linked_module): $(all_objects) $(all_libraries) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(transform-o-to-aux-executable)
+ $(PRIVATE_POST_LINK_CMD)
+endif
+
+endif # AUX_BUILD_NOT_COMPATIBLE
diff --git a/core/aux_static_library.mk b/core/aux_static_library.mk
new file mode 100644
index 0000000..d88478d
--- /dev/null
+++ b/core/aux_static_library.mk
@@ -0,0 +1,27 @@
+ifeq ($(LOCAL_IS_AUX_MODULE),)
+include $(BUILD_SYSTEM)/aux_toolchain.mk
+endif
+
+ifeq ($(AUX_BUILD_NOT_COMPATIBLE),)
+
+ifeq ($(strip $(LOCAL_MODULE_CLASS)),)
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+endif
+ifeq ($(strip $(LOCAL_MODULE_SUFFIX)),)
+LOCAL_MODULE_SUFFIX := .a
+endif
+
+LOCAL_UNINSTALLABLE_MODULE := true
+
+ifneq ($(strip $(LOCAL_MODULE_STEM)$(LOCAL_BUILT_MODULE_STEM)),)
+$(error $(LOCAL_PATH): Cannot set module stem for a library)
+endif
+
+include $(BUILD_SYSTEM)/binary.mk
+
+$(LOCAL_BUILT_MODULE) : PRIVATE_AR := $(AUX_AR)
+$(LOCAL_BUILT_MODULE) : $(built_whole_libraries)
+$(LOCAL_BUILT_MODULE) : $(all_objects)
+ $(transform-o-to-aux-static-lib)
+
+endif # AUX_BUILD_NOT_COMPATIBLE
diff --git a/core/aux_toolchain.mk b/core/aux_toolchain.mk
new file mode 100644
index 0000000..de0b139
--- /dev/null
+++ b/core/aux_toolchain.mk
@@ -0,0 +1,53 @@
+###########################################################
+# takes form LOCAL_AUX_TOOLCHAIN_$(LOCAL_AUX_CPU)
+###########################################################
+
+###############################
+# setup AUX environment
+###############################
+
+# shortcuts for targets with a single instance of OS, ARCH, VARIANT, CPU
+AUX_TOOLCHAIN := $(if $(LOCAL_AUX_TOOLCHAIN),$(LOCAL_AUX_TOOLCHAIN),$(AUX_TOOLCHAIN_$(AUX_CPU)))
+AUX_BUILD_NOT_COMPATIBLE:=
+ifeq ($(strip $(AUX_TOOLCHAIN)),)
+ ifeq ($(strip $(AUX_CPU)),)
+ $(warning $(LOCAL_PATH): $(LOCAL_MODULE): Undefined CPU for AUX toolchain)
+ AUX_BUILD_NOT_COMPATIBLE += TOOLCHAIN
+ else
+ $(warning $(LOCAL_PATH): $(LOCAL_MODULE): Undefined AUX toolchain for CPU=$(AUX_CPU))
+ AUX_BUILD_NOT_COMPATIBLE += TOOLCHAIN
+ endif
+endif
+
+AUX_BUILD_NOT_COMPATIBLE += $(foreach var,OS ARCH SUBARCH CPU OS_VARIANT,$(if $(LOCAL_AUX_$(var)),$(if \
+ $(filter $(LOCAL_AUX_$(var)),$(AUX_$(var))),,$(var))))
+
+AUX_BUILD_NOT_COMPATIBLE := $(strip $(AUX_BUILD_NOT_COMPATIBLE))
+
+ifneq ($(AUX_BUILD_NOT_COMPATIBLE),)
+$(info $(LOCAL_PATH): $(LOCAL_MODULE): not compatible: "$(AUX_BUILD_NOT_COMPATIBLE)" with)
+$(info ====> OS=$(AUX_OS) CPU=$(AUX_CPU) ARCH=$(AUX_ARCH) SUBARCH=$(AUX_SUBARCH) OS_VARIANT=$(AUX_OS_VARIANT))
+$(info ====> TOOLCHAIN=$(AUX_TOOLCHAIN))
+endif
+
+AUX_AR := $(AUX_TOOLCHAIN)ar
+AUX_AS := $(AUX_TOOLCHAIN)gcc
+AUX_CC := $(AUX_TOOLCHAIN)gcc
+AUX_CXX := $(AUX_TOOLCHAIN)g++
+AUX_LINKER := $(AUX_TOOLCHAIN)ld
+AUX_OBJCOPY := $(AUX_TOOLCHAIN)objcopy
+AUX_OBJDUMP := $(AUX_TOOLCHAIN)objdump
+
+###############################
+# setup Android environment
+###############################
+
+LOCAL_IS_AUX_MODULE := true
+LOCAL_2ND_ARCH_VAR_PREFIX :=
+LOCAL_CC := $(AUX_CC)
+LOCAL_CXX := $(AUX_CXX)
+LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
+LOCAL_SYSTEM_SHARED_LIBRARIES :=
+LOCAL_CXX_STL := none
+LOCAL_NO_PIC := true
+LOCAL_NO_LIBCOMPILER_RT := true
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 6fc2935..c327d2c 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -14,6 +14,9 @@
# limitations under the License.
#
+# Catch users that directly include base_rules.mk
+$(call record-module-type,base_rules)
+
# Users can define base-rules-hook in their buildspec.mk to perform
# arbitrary operations as each module is included.
ifdef base-rules-hook
@@ -30,6 +33,7 @@
endif
LOCAL_IS_HOST_MODULE := $(strip $(LOCAL_IS_HOST_MODULE))
+LOCAL_IS_AUX_MODULE := $(strip $(LOCAL_IS_AUX_MODULE))
ifdef LOCAL_IS_HOST_MODULE
ifneq ($(LOCAL_IS_HOST_MODULE),true)
$(error $(LOCAL_PATH): LOCAL_IS_HOST_MODULE must be "true" or empty, not "$(LOCAL_IS_HOST_MODULE)")
@@ -40,8 +44,18 @@
my_prefix := $(LOCAL_HOST_PREFIX)
endif
my_host := host-
+ my_kind := HOST
else
- my_prefix := TARGET_
+ ifdef LOCAL_IS_AUX_MODULE
+ ifneq ($(LOCAL_IS_AUX_MODULE),true)
+ $(error $(LOCAL_PATH): LOCAL_IS_AUX_MODULE must be "true" or empty, not "$(LOCAL_IS_AUX_MODULE)")
+ endif
+ my_prefix := AUX_
+ my_kind := AUX
+ else
+ my_prefix := TARGET_
+ my_kind :=
+ endif
my_host :=
endif
@@ -51,12 +65,29 @@
my_host_cross :=
endif
+ifndef LOCAL_PROPRIETARY_MODULE
+ LOCAL_PROPRIETARY_MODULE := $(LOCAL_VENDOR_MODULE)
+endif
+ifndef LOCAL_VENDOR_MODULE
+ LOCAL_VENDOR_MODULE := $(LOCAL_PROPRIETARY_MODULE)
+endif
+ifneq ($(filter-out $(LOCAL_PROPRIETARY_MODULE),$(LOCAL_VENDOR_MODULE))$(filter-out $(LOCAL_VENDOR_MODULE),$(LOCAL_PROPRIETARY_MODULE)),)
+$(call pretty-error,Only one of LOCAL_PROPRIETARY_MODULE[$(LOCAL_PROPRIETARY_MODULE)] and LOCAL_VENDOR_MODULE[$(LOCAL_VENDOR_MODULE)] may be set, or they must be equal)
+endif
+
+include $(BUILD_SYSTEM)/local_vndk.mk
+
my_module_tags := $(LOCAL_MODULE_TAGS)
ifeq ($(my_host_cross),true)
my_module_tags :=
endif
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+ifdef LOCAL_2ND_ARCH_VAR_PREFIX
+# Don't pull in modules by tags if this is for translation TARGET_2ND_ARCH.
+ my_module_tags :=
+endif
+endif
-ifdef BUILDING_WITH_NINJA
# Ninja has an implicit dependency on the command being run, and kati will
# regenerate the ninja manifest if any read makefile changes, so there is no
# need to have dependencies on makefiles.
@@ -64,7 +95,6 @@
# a .mk file, because a few users of LOCAL_ADDITIONAL_DEPENDENCIES don't include
# base_rules.mk, but it will fix the most common ones.
LOCAL_ADDITIONAL_DEPENDENCIES := $(filter-out %.mk,$(LOCAL_ADDITIONAL_DEPENDENCIES))
-endif
###########################################################
## Validate and define fallbacks for input LOCAL_* variables.
@@ -101,7 +131,7 @@
# makefiles. Anything else is either a typo or a source of unexpected
# behaviors.
ifneq ($(filter-out debug eng tests optional samples,$(my_module_tags)),)
-$(warning unusual tags $(my_module_tags) on $(LOCAL_MODULE) at $(LOCAL_PATH))
+$(call pretty-warning,unusual tags $(my_module_tags))
endif
# Add implicit tags.
@@ -125,29 +155,42 @@
my_32_64_bit_suffix := $(if $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)IS_64_BIT),64,32)
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+# When in TARGET_TRANSLATE_2ND_ARCH both TARGET_ARCH and TARGET_2ND_ARCH are 32-bit,
+# to avoid path conflict we force using LOCAL_MODULE_PATH_64 for the first arch.
+ifdef LOCAL_2ND_ARCH_VAR_PREFIX
+my_multilib_module_path := $(LOCAL_MODULE_PATH_32)
+else # ! LOCAL_2ND_ARCH_VAR_PREFIX
+my_multilib_module_path := $(LOCAL_MODULE_PATH_64)
+endif # ! LOCAL_2ND_ARCH_VAR_PREFIX
+else # ! TARGET_TRANSLATE_2ND_ARCH
my_multilib_module_path := $(strip $(LOCAL_MODULE_PATH_$(my_32_64_bit_suffix)))
+endif # ! TARGET_TRANSLATE_2ND_ARCH
ifdef my_multilib_module_path
my_module_path := $(my_multilib_module_path)
else
my_module_path := $(strip $(LOCAL_MODULE_PATH))
endif
+my_module_path := $(patsubst %/,%,$(my_module_path))
my_module_relative_path := $(strip $(LOCAL_MODULE_RELATIVE_PATH))
+ifdef LOCAL_IS_HOST_MODULE
+ partition_tag :=
+else
+ifeq (true,$(LOCAL_VENDOR_MODULE))
+ partition_tag := _VENDOR
+else ifeq (true,$(LOCAL_OEM_MODULE))
+ partition_tag := _OEM
+else ifeq (true,$(LOCAL_ODM_MODULE))
+ partition_tag := _ODM
+else ifeq (NATIVE_TESTS,$(LOCAL_MODULE_CLASS))
+ partition_tag := _DATA
+else
+ # The definition of should-install-to-system will be different depending
+ # on which goal (e.g., sdk or just droid) is being built.
+ partition_tag := $(if $(call should-install-to-system,$(my_module_tags)),,_DATA)
+endif
+endif
ifeq ($(my_module_path),)
- ifdef LOCAL_IS_HOST_MODULE
- partition_tag :=
- else
- ifeq (true,$(LOCAL_PROPRIETARY_MODULE))
- partition_tag := _VENDOR
- else ifeq (true,$(LOCAL_OEM_MODULE))
- partition_tag := _OEM
- else ifeq (true,$(LOCAL_ODM_MODULE))
- partition_tag := _ODM
- else
- # The definition of should-install-to-system will be different depending
- # on which goal (e.g., sdk or just droid) is being built.
- partition_tag := $(if $(call should-install-to-system,$(my_module_tags)),,_DATA)
- endif
- endif
install_path_var := $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT$(partition_tag)_$(LOCAL_MODULE_CLASS)
ifeq (true,$(LOCAL_PRIVILEGED_MODULE))
install_path_var := $(install_path_var)_PRIVILEGED
@@ -176,9 +219,21 @@
my_register_name := $(my_register_name)$($(my_prefix)2ND_ARCH_MODULE_SUFFIX)
endif
endif
+
+ifeq ($(my_host_cross),true)
+ my_all_targets := host_cross_$(my_register_name)_all_targets
+else ifneq ($(LOCAL_IS_HOST_MODULE),)
+ my_all_targets := host_$(my_register_name)_all_targets
+else
+ my_all_targets := device_$(my_register_name)_all_targets
+endif
+
+# variant is enough to make nano class unique; it serves as a key to lookup (OS,ARCH) tuple
+aux_class := $($(my_prefix)OS_VARIANT)
# Make sure that this IS_HOST/CLASS/MODULE combination is unique.
module_id := MODULE.$(if \
- $(LOCAL_IS_HOST_MODULE),$($(my_prefix)OS),TARGET).$(LOCAL_MODULE_CLASS).$(my_register_name)
+ $(LOCAL_IS_HOST_MODULE),$($(my_prefix)OS),$(if \
+ $(LOCAL_IS_AUX_MODULE),$(aux_class),TARGET)).$(LOCAL_MODULE_CLASS).$(my_register_name)
ifdef $(module_id)
$(error $(LOCAL_PATH): $(module_id) already defined by $($(module_id)))
endif
@@ -193,6 +248,8 @@
###########################################################
include $(BUILD_SYSTEM)/configure_module_stem.mk
+LOCAL_BUILT_MODULE := $(intermediates)/$(my_built_module_stem)
+
# OVERRIDE_BUILT_MODULE_PATH is only allowed to be used by the
# internal SHARED_LIBRARIES build files.
OVERRIDE_BUILT_MODULE_PATH := $(strip $(OVERRIDE_BUILT_MODULE_PATH))
@@ -200,11 +257,8 @@
ifneq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
$(error $(LOCAL_PATH): Illegal use of OVERRIDE_BUILT_MODULE_PATH)
endif
- built_module_path := $(OVERRIDE_BUILT_MODULE_PATH)
-else
- built_module_path := $(intermediates)
+ $(eval $(call copy-one-file,$(LOCAL_BUILT_MODULE),$(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem)))
endif
-LOCAL_BUILT_MODULE := $(built_module_path)/$(my_built_module_stem)
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
# Apk and its attachments reside in its own subdir.
@@ -230,9 +284,6 @@
# dependent binaries of a .toc file will be rebuilt only when the content of
# the .toc file is changed.
###########################################################
-ifndef LOCAL_IS_HOST_MODULE
-# Disable .toc optimization for host modules: we may run the host binaries during the build process
-# and the libraries' implementation matters.
ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_BUILT_MODULE).toc
$(LOCAL_BUILT_MODULE).toc: $(LOCAL_BUILT_MODULE)
@@ -242,7 +293,11 @@
# Kati adds restat=1 to ninja. GNU make does nothing for this.
.KATI_RESTAT: $(LOCAL_BUILT_MODULE).toc
# Build .toc file when using mm, mma, or make $(my_register_name)
-$(my_register_name): $(LOCAL_BUILT_MODULE).toc
+$(my_all_targets): $(LOCAL_BUILT_MODULE).toc
+
+ifdef OVERRIDE_BUILT_MODULE_PATH
+$(eval $(call copy-one-file,$(LOCAL_BUILT_MODULE).toc,$(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem).toc))
+$(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem).toc: $(OVERRIDE_BUILT_MODULE_PATH)/$(my_built_module_stem)
endif
endif
@@ -250,7 +305,7 @@
## logtags: Add .logtags files to global list
###########################################################
-logtags_sources := $(filter %.logtags,$(LOCAL_SRC_FILES))
+logtags_sources := $(filter %.logtags,$(LOCAL_SRC_FILES)) $(LOCAL_LOGTAGS_FILES)
ifneq ($(strip $(logtags_sources)),)
event_log_tags := $(addprefix $(LOCAL_PATH)/,$(logtags_sources))
@@ -276,6 +331,7 @@
###########################################################
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_PATH:=$(LOCAL_PATH)
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_IS_HOST_MODULE := $(LOCAL_IS_HOST_MODULE)
+$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_IS_AUX_MODULE := $(LOCAL_IS_AUX_MODULE)
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_HOST:= $(my_host)
$(LOCAL_INTERMEDIATE_TARGETS) : PRIVATE_PREFIX := $(my_prefix)
@@ -288,8 +344,17 @@
# Provide a short-hand for building this module.
# We name both BUILT and INSTALLED in case
# LOCAL_UNINSTALLABLE_MODULE is set.
+.PHONY: $(my_all_targets)
+$(my_all_targets): $(LOCAL_BUILT_MODULE) $(LOCAL_INSTALLED_MODULE)
+
.PHONY: $(my_register_name)
-$(my_register_name): $(LOCAL_BUILT_MODULE) $(LOCAL_INSTALLED_MODULE)
+$(my_register_name): $(my_all_targets)
+
+ifneq ($(my_register_name),$(LOCAL_MODULE))
+# $(LOCAL_MODULE) covers all the multilib targets.
+.PHONY: $(LOCAL_MODULE)
+$(LOCAL_MODULE) : $(my_all_targets)
+endif
# Set up phony targets that covers all modules under the given paths.
# This allows us to build everything in given paths by running mmma/mma.
@@ -298,51 +363,46 @@
$(foreach c, $(my_path_components),\
$(eval my_path_prefix := $(my_path_prefix)-$(c))\
$(eval .PHONY : $(my_path_prefix))\
- $(eval $(my_path_prefix) : $(my_register_name)))
+ $(eval $(my_path_prefix) : $(my_all_targets)))
###########################################################
## Module installation rule
###########################################################
-# Some hosts do not have ACP; override the LOCAL version if that's the case.
-ifneq ($(strip $(HOST_ACP_UNAVAILABLE)),)
- LOCAL_ACP_UNAVAILABLE := $(strip $(HOST_ACP_UNAVAILABLE))
-endif
-
+my_init_rc_installed :=
+my_init_rc_pairs :=
+my_installed_symlinks :=
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
- # Define a copy rule to install the module.
- # acp and libraries that it uses can't use acp for
- # installation; hence, LOCAL_ACP_UNAVAILABLE.
$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
-ifneq ($(LOCAL_ACP_UNAVAILABLE),true)
-$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE) | $(ACP)
+$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
@echo "Install: $@"
$(copy-file-to-new-target)
$(PRIVATE_POST_INSTALL_CMD)
-else
-$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
- @echo "Install: $@"
- $(copy-file-to-target-with-cp)
-endif
+ifndef LOCAL_IS_HOST_MODULE
# Rule to install the module's companion init.rc.
-my_init_rc := $(LOCAL_INIT_RC_$(my_32_64_bit_suffix))
-my_init_rc_src :=
-my_init_rc_installed :=
-ifndef my_init_rc
-my_init_rc := $(LOCAL_INIT_RC)
-# Make sure we don't define the rule twice in multilib module.
-LOCAL_INIT_RC :=
-endif
-ifdef my_init_rc
-my_init_rc_src := $(LOCAL_PATH)/$(my_init_rc)
-my_init_rc_installed := $(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(my_init_rc_src))
-$(my_init_rc_installed) : $(my_init_rc_src) | $(ACP)
- @echo "Install: $@"
- $(copy-file-to-new-target)
+my_init_rc := $(LOCAL_INIT_RC_$(my_32_64_bit_suffix)) $(LOCAL_INIT_RC)
+ifneq ($(strip $(my_init_rc)),)
+my_init_rc_pairs := $(foreach rc,$(my_init_rc),$(LOCAL_PATH)/$(rc):$(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(rc)))
+my_init_rc_installed := $(foreach rc,$(my_init_rc_pairs),$(call word-colon,2,$(rc)))
-$(my_register_name) : $(my_init_rc_installed)
+# 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-files,$(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)
+
endif # !LOCAL_UNINSTALLABLE_MODULE
###########################################################
@@ -371,50 +431,99 @@
endif
###########################################################
-## Compatibiliy suite files.
+## Compatibility suite files.
###########################################################
ifdef LOCAL_COMPATIBILITY_SUITE
-ifneq ($(words $(LOCAL_COMPATIBILITY_SUITE)),1)
-$(error $(LOCAL_PATH):$(LOCAL_MODULE) LOCAL_COMPATIBILITY_SUITE can be only one name)
+
+# If we are building a native test or benchmark and its stem variants are not defined,
+# separate the multiple architectures into subdirectories of the testcase folder.
+arch_dir :=
+is_native :=
+ifeq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
+ is_native := true
+endif
+ifeq ($(LOCAL_MODULE_CLASS),NATIVE_BENCHMARK)
+ is_native := true
+endif
+ifdef LOCAL_MULTILIB
+ is_native := true
+endif
+ifdef is_native
+ arch_dir := /$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+ is_native :=
endif
# The module itself.
-my_compat_dist := \
- $(LOCAL_BUILT_MODULE):$(COMPATIBILITY_TESTCASES_OUT_$(LOCAL_COMPATIBILITY_SUITE))/$(my_installed_module_stem)
+$(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))))
# Make sure we only add the files once for multilib modules.
ifndef $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
$(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files := true
# LOCAL_COMPATIBILITY_SUPPORT_FILES is a list of <src>[:<dest>].
-my_compat_dist += $(foreach f, $(LOCAL_COMPATIBILITY_SUPPORT_FILES),\
- $(eval p := $(subst :,$(space),$(f)))\
- $(eval s := $(word 1,$(p)))\
- $(eval d := $(COMPATIBILITY_TESTCASES_OUT_$(LOCAL_COMPATIBILITY_SUITE))/$(or $(word 2,$(p)),$(notdir $(word 1,$(p)))))\
- $(s):$(d))
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_$(suite) += $(foreach f, $(LOCAL_COMPATIBILITY_SUPPORT_FILES), \
+ $(eval p := $(subst :,$(space),$(f))) \
+ $(eval s := $(word 1,$(p))) \
+ $(eval n := $(or $(word 2,$(p)),$(notdir $(word 1, $(p))))) \
+ $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(s):$(dir)/$(n)))))
+
ifneq (,$(wildcard $(LOCAL_PATH)/AndroidTest.xml))
-my_compat_dist += \
- $(LOCAL_PATH)/AndroidTest.xml:$(COMPATIBILITY_TESTCASES_OUT_$(LOCAL_COMPATIBILITY_SUITE))/$(LOCAL_MODULE).config
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(LOCAL_PATH)/AndroidTest.xml:$(dir)/$(LOCAL_MODULE).config)))
endif
ifneq (,$(wildcard $(LOCAL_PATH)/DynamicConfig.xml))
-my_compat_dist += \
- $(LOCAL_PATH)/DynamicConfig.xml:$(COMPATIBILITY_TESTCASES_OUT_$(LOCAL_COMPATIBILITY_SUITE))/$(LOCAL_MODULE).dynamic
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(LOCAL_PATH)/DynamicConfig.xml:$(dir)/$(LOCAL_MODULE).dynamic)))
+endif
+
+ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config))
+$(foreach extra_config, $(wildcard $(LOCAL_PATH)/$(LOCAL_MODULE)_*.config), \
+ $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(extra_config):$(dir)/$(notdir $(extra_config))))))
endif
endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
-my_compat_files := $(call copy-many-files, $(my_compat_dist))
+$(call create-suite-dependencies)
-COMPATIBILITY.$(LOCAL_COMPATIBILITY_SUITE).FILES := \
- $(COMPATIBILITY.$(LOCAL_COMPATIBILITY_SUITE).FILES) \
- $(my_compat_files)
-
-# Copy over the compatibility files when user runs mm/mmm.
-$(my_register_name) : $(my_compat_files)
endif # LOCAL_COMPATIBILITY_SUITE
###########################################################
+## Test Data
+###########################################################
+my_test_data_pairs :=
+my_installed_test_data :=
+
+ifneq ($(filter NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+ifneq ($(strip $(LOCAL_TEST_DATA)),)
+ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
+
+my_test_data_pairs := $(strip $(foreach td,$(LOCAL_TEST_DATA), \
+ $(eval _file := $(call word-colon,2,$(td))) \
+ $(if $(_file), \
+ $(eval _base := $(call word-colon,1,$(td))), \
+ $(eval _base := $(LOCAL_PATH)) \
+ $(eval _file := $(call word-colon,1,$(td)))) \
+ $(if $(findstring ..,$(_file)),$(error $(LOCAL_MODULE_MAKEFILE): LOCAL_TEST_DATA may not include '..': $(_file))) \
+ $(if $(filter /%,$(_base) $(_file)),$(error $(LOCAL_MODULE_MAKEFILE): LOCAL_TEST_DATA may not include absolute paths: $(_base) $(_file))) \
+ $(call append-path,$(_base),$(_file)):$(call append-path,$(my_module_path),$(_file))))
+
+my_installed_test_data := $(call copy-many-files,$(my_test_data_pairs))
+$(LOCAL_INSTALLED_MODULE): $(my_installed_test_data)
+
+endif
+endif
+endif
+
+###########################################################
## Register with ALL_MODULES
###########################################################
@@ -435,11 +544,12 @@
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))
+ $(LOCAL_INSTALLED_MODULE) $(my_init_rc_installed) $(my_installed_symlinks) \
+ $(my_installed_test_data))
ALL_MODULES.$(my_register_name).BUILT_INSTALLED := \
$(strip $(ALL_MODULES.$(my_register_name).BUILT_INSTALLED) \
$(LOCAL_BUILT_MODULE):$(LOCAL_INSTALLED_MODULE) \
- $(addprefix $(my_init_rc_src):,$(my_init_rc_installed)))
+ $(my_init_rc_pairs) $(my_test_data_pairs))
endif
ifdef LOCAL_PICKUP_FILES
# Files or directories ready to pick up by the build system
@@ -454,6 +564,9 @@
endif
ALL_MODULES.$(my_register_name).REQUIRED := \
$(strip $(ALL_MODULES.$(my_register_name).REQUIRED) $(my_required_modules))
+ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED := \
+ $(strip $(ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED)\
+ $(my_required_modules))
ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS := \
$(ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS) $(event_log_tags)
ALL_MODULES.$(my_register_name).MAKEFILE := \
@@ -478,6 +591,7 @@
$(LOCAL_STATIC_LIBRARIES) \
$(LOCAL_WHOLE_STATIC_LIBRARIES) \
$(LOCAL_SHARED_LIBRARIES) \
+ $(LOCAL_HEADER_LIBRARIES) \
$(LOCAL_STATIC_JAVA_LIBRARIES) \
$(LOCAL_JAVA_LIBRARIES)\
$(LOCAL_JNI_SHARED_LIBRARIES))
@@ -499,7 +613,7 @@
## umbrella targets used to verify builds
###########################################################
j_or_n :=
-ifneq (,$(filter EXECUTABLES SHARED_LIBRARIES STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS)))
+ifneq (,$(filter EXECUTABLES SHARED_LIBRARIES STATIC_LIBRARIES HEADER_LIBRARIES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)))
j_or_n := native
else
ifneq (,$(filter JAVA_LIBRARIES APPS,$(LOCAL_MODULE_CLASS)))
@@ -508,15 +622,26 @@
endif
ifdef LOCAL_IS_HOST_MODULE
h_or_t := host
+ifeq ($(my_host_cross),true)
+h_or_hc_or_t := host-cross
else
+h_or_hc_or_t := host
+endif
+else
+h_or_hc_or_t := target
h_or_t := target
endif
+
ifdef j_or_n
$(j_or_n) $(h_or_t) $(j_or_n)-$(h_or_t) : $(my_checked_module)
ifneq (,$(filter $(my_module_tags),tests))
$(j_or_n)-$(h_or_t)-tests $(j_or_n)-tests $(h_or_t)-tests : $(my_checked_module)
endif
+$(LOCAL_MODULE)-$(h_or_hc_or_t) : $(my_all_targets)
+ifeq ($(j_or_n),native)
+$(LOCAL_MODULE)-$(h_or_hc_or_t)$(my_32_64_bit_suffix) : $(my_all_targets)
+endif
endif
###########################################################
diff --git a/core/binary.mk b/core/binary.mk
index 7b22903..b2b8186 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -30,6 +30,8 @@
endif
endif
+my_soong_problems :=
+
# The following LOCAL_ variables will be modified in this file.
# Because the same LOCAL_ variables may be used to define modules for both 1st arch and 2nd arch,
# we can't modify them in place.
@@ -38,6 +40,7 @@
my_static_libraries := $(LOCAL_STATIC_LIBRARIES)
my_whole_static_libraries := $(LOCAL_WHOLE_STATIC_LIBRARIES)
my_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
+my_header_libraries := $(LOCAL_HEADER_LIBRARIES)
my_cflags := $(LOCAL_CFLAGS)
my_conlyflags := $(LOCAL_CONLYFLAGS)
my_cppflags := $(LOCAL_CPPFLAGS)
@@ -52,29 +55,90 @@
my_cxx_wrapper := $(CXX_WRAPPER)
my_c_includes := $(LOCAL_C_INCLUDES)
my_generated_sources := $(LOCAL_GENERATED_SOURCES)
-my_native_coverage := $(LOCAL_NATIVE_COVERAGE)
-my_additional_dependencies := $(LOCAL_MODULE_MAKEFILE_DEP) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+my_additional_dependencies := $(LOCAL_ADDITIONAL_DEPENDENCIES)
my_export_c_include_dirs := $(LOCAL_EXPORT_C_INCLUDE_DIRS)
+my_export_c_include_deps := $(LOCAL_EXPORT_C_INCLUDE_DEPS)
+my_arflags :=
+ifneq (,$(strip $(foreach dir,$(subst $(comma),$(space),$(COVERAGE_PATHS)),$(filter $(dir)%,$(LOCAL_PATH)))))
+ifeq (,$(strip $(foreach dir,$(subst $(comma),$(space),$(COVERAGE_EXCLUDE_PATHS)),$(filter $(dir)%,$(LOCAL_PATH)))))
+ my_native_coverage := true
+else
+ my_native_coverage := false
+endif
+else
+ my_native_coverage := false
+endif
+
+my_allow_undefined_symbols := $(strip $(LOCAL_ALLOW_UNDEFINED_SYMBOLS))
+ifdef SANITIZE_HOST
ifdef LOCAL_IS_HOST_MODULE
my_allow_undefined_symbols := true
-else
-my_allow_undefined_symbols := $(strip $(LOCAL_ALLOW_UNDEFINED_SYMBOLS))
+endif
endif
my_ndk_sysroot :=
my_ndk_sysroot_include :=
my_ndk_sysroot_lib :=
-ifdef LOCAL_SDK_VERSION
- ifdef LOCAL_NDK_VERSION
- $(error $(LOCAL_PATH): LOCAL_NDK_VERSION is now retired.)
- endif
+ifneq ($(LOCAL_SDK_VERSION),)
ifdef LOCAL_IS_HOST_MODULE
$(error $(LOCAL_PATH): LOCAL_SDK_VERSION cannot be used in host module)
endif
- my_ndk_source_root := $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources
- my_ndk_sysroot := $(HISTORICAL_NDK_VERSIONS_ROOT)/current/platforms/android-$(LOCAL_SDK_VERSION)/arch-$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
- my_ndk_sysroot_include := $(my_ndk_sysroot)/usr/include
+
+ # Make sure we've built the NDK.
+ my_additional_dependencies += $(SOONG_OUT_DIR)/ndk.timestamp
+
+ # mips32r6 is not supported by the NDK. No released NDK contains these
+ # libraries, but the r10 in prebuilts/ndk had a local hack to add them :(
+ #
+ # We need to find a real solution to this problem, but until we do just drop
+ # mips32r6 things back to r10 to get the tree building again.
+ ifeq (mips32r6,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH_VARIANT))
+ ifeq ($(LOCAL_NDK_VERSION), current)
+ LOCAL_NDK_VERSION := r10
+ endif
+ endif
+
+ my_arch := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+ ifneq (,$(filter arm64 mips64 x86_64,$(my_arch)))
+ my_min_sdk_version := 21
+ else
+ my_min_sdk_version := 9
+ endif
+
+ # Historically we've just set up a bunch of symlinks in prebuilts/ndk to map
+ # missing API levels to existing ones where necessary, but we're not doing
+ # that for the generated libraries. Clip the API level to the minimum where
+ # appropriate.
+ my_ndk_api := $(LOCAL_SDK_VERSION)
+ ifneq ($(my_ndk_api),current)
+ my_ndk_api := $(call math_max,$(my_ndk_api),$(my_min_sdk_version))
+ endif
+
+ my_ndk_api_def := $(my_ndk_api)
+ my_ndk_hist_api := $(my_ndk_api)
+ ifeq ($(my_ndk_api),current)
+ my_ndk_api_def := __ANDROID_API_FUTURE__
+ # The last API level supported by the old prebuilt NDKs.
+ my_ndk_hist_api := 24
+ endif
+
+
+ # Traditionally this has come from android/api-level.h, but with the libc
+ # headers unified it must be set by the build system since we don't have
+ # per-API level copies of that header now.
+ my_cflags += -D__ANDROID_API__=$(my_ndk_api_def)
+
+ my_ndk_source_root := \
+ $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources
+ my_ndk_sysroot := \
+ $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/platforms/android-$(my_ndk_hist_api)/arch-$(my_arch)
+ my_built_ndk := $(SOONG_OUT_DIR)/ndk
+ my_ndk_triple := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_TRIPLE)
+ my_ndk_sysroot_include := \
+ $(my_built_ndk)/sysroot/usr/include \
+ $(my_built_ndk)/sysroot/usr/include/$(my_ndk_triple) \
+ $(my_ndk_sysroot)/usr/include \
# x86_64 and and mips64 are both multilib toolchains, so their libraries are
# installed in /usr/lib64. Aarch64, on the other hand, is not a multilib
@@ -83,14 +147,19 @@
# Mips32r6 is yet another variation, with libraries installed in libr6.
#
# For the rest, the libraries are installed simply to /usr/lib.
- ifneq (,$(filter x86_64 mips64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)))
- my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/lib64
+ ifneq (,$(filter x86_64 mips64,$(my_arch)))
+ my_ndk_libdir_name := lib64
else ifeq (mips32r6,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH_VARIANT))
- my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/libr6
+ my_ndk_libdir_name := libr6
else
- my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/lib
+ my_ndk_libdir_name := lib
endif
+ my_ndk_platform_dir := \
+ $(my_built_ndk)/platforms/android-$(my_ndk_api)/arch-$(my_arch)
+ my_built_ndk_libs := $(my_ndk_platform_dir)/usr/$(my_ndk_libdir_name)
+ my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/$(my_ndk_libdir_name)
+
# The bionic linker now has support for packed relocations and gnu style
# hashes (which are much faster!), but shipping to older devices requires
# the old style hash. Fortunately, we can build with both and it'll work
@@ -108,9 +177,8 @@
# See ndk/docs/CPLUSPLUS-SUPPORT.html
my_ndk_stl_include_path :=
my_ndk_stl_shared_lib_fullpath :=
- my_ndk_stl_shared_lib :=
my_ndk_stl_static_lib :=
- my_ndk_stl_cppflags :=
+ my_ndk_cpp_std_version :=
my_cpu_variant := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)
ifeq (mips32r6,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH_VARIANT))
my_cpu_variant := mips32r6
@@ -131,22 +199,62 @@
my_system_shared_libraries += libstdc++
ifeq (stlport_static,$(LOCAL_NDK_STL_VARIANT))
my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(my_cpu_variant)/libstlport_static.a
+ my_ldlibs += -ldl
else
my_ndk_stl_shared_lib_fullpath := $(my_ndk_source_root)/cxx-stl/stlport/libs/$(my_cpu_variant)/libstlport_shared.so
- my_ndk_stl_shared_lib := -lstlport_shared
endif
else # LOCAL_NDK_STL_VARIANT is not stlport_* either
ifneq (,$(filter c++_%, $(LOCAL_NDK_STL_VARIANT)))
- my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libcxx/include \
- $(my_ndk_source_root)/cxx-stl/llvm-libc++/gabi++/include \
- $(my_ndk_source_root)/android/support/include
- ifeq (c++_static,$(LOCAL_NDK_STL_VARIANT))
- my_ndk_stl_static_lib := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libc++_static.a
+ # Pre-r11 NDKs used libgabi++ for libc++'s C++ ABI, but r11 and later use
+ # libc++abi.
+ #
+ # r13 no longer has the inner directory as a side effect of just using
+ # external/libcxx.
+ ifeq (r10,$(LOCAL_NDK_VERSION))
+ my_ndk_stl_include_path := \
+ $(my_ndk_source_root)/cxx-stl/llvm-libc++/libcxx/include
+ my_ndk_stl_include_path += \
+ $(my_ndk_source_root)/cxx-stl/llvm-libc++/gabi++/include
+ else ifeq (r11,$(LOCAL_NDK_VERSION))
+ my_ndk_stl_include_path := \
+ $(my_ndk_source_root)/cxx-stl/llvm-libc++/libcxx/include
+ my_ndk_stl_include_path += \
+ $(my_ndk_source_root)/cxx-stl/llvm-libc++abi/libcxxabi/include
else
- my_ndk_stl_shared_lib_fullpath := $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libc++_shared.so
- my_ndk_stl_shared_lib := -lc++_shared
+ my_ndk_stl_include_path := \
+ $(my_ndk_source_root)/cxx-stl/llvm-libc++/include
+ my_ndk_stl_include_path += \
+ $(my_ndk_source_root)/cxx-stl/llvm-libc++abi/include
endif
- my_ndk_stl_cppflags := -std=c++11
+ my_ndk_stl_include_path += $(my_ndk_source_root)/android/support/include
+
+ my_libcxx_libdir := \
+ $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)
+
+ ifneq (,$(filter r10 r11,$(LOCAL_NDK_VERSION)))
+ ifeq (c++_static,$(LOCAL_NDK_STL_VARIANT))
+ my_ndk_stl_static_lib := $(my_libcxx_libdir)/libc++_static.a
+ else
+ my_ndk_stl_shared_lib_fullpath := $(my_libcxx_libdir)/libc++_shared.so
+ endif
+ else
+ ifeq (c++_static,$(LOCAL_NDK_STL_VARIANT))
+ my_ndk_stl_static_lib := \
+ $(my_libcxx_libdir)/libc++_static.a \
+ $(my_libcxx_libdir)/libc++abi.a
+ else
+ my_ndk_stl_shared_lib_fullpath := $(my_libcxx_libdir)/libc++_shared.so
+ endif
+
+ my_ndk_stl_static_lib += $(my_libcxx_libdir)/libandroid_support.a
+ ifneq (,$(filter armeabi armeabi-v7a,$(my_cpu_variant)))
+ my_ndk_stl_static_lib += $(my_libcxx_libdir)/libunwind.a
+ endif
+ endif
+
+ my_ldlibs += -ldl
+
+ my_ndk_cpp_std_version := c++11
else # LOCAL_NDK_STL_VARIANT is not c++_* either
ifneq (,$(filter gnustl_%, $(LOCAL_NDK_STL_VARIANT)))
my_ndk_stl_include_path := $(my_ndk_source_root)/cxx-stl/gnu-libstdc++/$($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NDK_GCC_VERSION)/libs/$(my_cpu_variant)/include \
@@ -160,21 +268,59 @@
endif
endif
+ifneq ($(LOCAL_USE_VNDK),)
+ my_cflags += -D__ANDROID_API__=__ANDROID_API_FUTURE__
+endif
+
+ifndef LOCAL_IS_HOST_MODULE
+# For device libraries, move LOCAL_LDLIBS references to my_shared_libraries. We
+# no longer need to use my_ldlibs to pick up NDK prebuilt libraries since we're
+# linking my_shared_libraries by full path now.
+my_allowed_ldlibs :=
+
+# Sort ldlibs and ldflags between -l and other linker flags
+# We'll do this again later, since there are still changes happening, but that's fine.
+my_ldlib_flags := $(my_ldflags) $(my_ldlibs)
+my_ldlibs := $(filter -l%,$(my_ldlib_flags))
+my_ldflags := $(filter-out -l%,$(my_ldlib_flags))
+my_ldlib_flags :=
+
+# Move other ldlibs back to shared libraries
+my_shared_libraries += $(patsubst -l%,lib%,$(filter-out $(my_allowed_ldlibs),$(my_ldlibs)))
+my_ldlibs := $(filter $(my_allowed_ldlibs),$(my_ldlibs))
+endif
+
+ifneq ($(LOCAL_SDK_VERSION),)
+ my_all_ndk_libraries := \
+ $(NDK_MIGRATED_LIBS) $(addprefix lib,$(NDK_PREBUILT_SHARED_LIBRARIES))
+ my_ndk_shared_libraries := \
+ $(filter $(my_all_ndk_libraries),\
+ $(my_shared_libraries) $(my_system_shared_libraries))
+
+ my_shared_libraries := \
+ $(filter-out $(my_all_ndk_libraries),$(my_shared_libraries))
+ my_system_shared_libraries := \
+ $(filter-out $(my_all_ndk_libraries),$(my_system_shared_libraries))
+endif
+
# MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
# all code is position independent, and then those warnings get promoted to
# errors.
+ifneq ($(LOCAL_NO_PIC),true)
ifneq ($($(my_prefix)OS),windows)
-ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
-my_cflags += -fpie
+ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+my_cflags += -fPIE
else
my_cflags += -fPIC
endif
endif
+endif
ifdef LOCAL_IS_HOST_MODULE
my_src_files += $(LOCAL_SRC_FILES_$($(my_prefix)OS)) $(LOCAL_SRC_FILES_$($(my_prefix)OS)_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
my_static_libraries += $(LOCAL_STATIC_LIBRARIES_$($(my_prefix)OS))
my_shared_libraries += $(LOCAL_SHARED_LIBRARIES_$($(my_prefix)OS))
+my_header_libraries += $(LOCAL_HEADER_LIBRARIES_$($(my_prefix)OS))
my_cflags += $(LOCAL_CFLAGS_$($(my_prefix)OS))
my_cppflags += $(LOCAL_CPPFLAGS_$($(my_prefix)OS))
my_ldflags += $(LOCAL_LDFLAGS_$($(my_prefix)OS))
@@ -201,6 +347,10 @@
endif
my_src_files := $(filter-out $(my_src_files_exclude),$(my_src_files))
+# Strip '/' from the beginning of each src file. This helps the ../ detection in case
+# the source file is in the form of /../file
+my_src_files := $(patsubst /%,%,$(my_src_files))
+
my_clang := $(strip $(LOCAL_CLANG))
ifdef LOCAL_CLANG_$(my_32_64_bit_suffix)
my_clang := $(strip $(LOCAL_CLANG_$(my_32_64_bit_suffix)))
@@ -209,13 +359,32 @@
my_clang := $(strip $(LOCAL_CLANG_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)))
endif
+# if custom toolchain is in use, default is not to use clang, if not explicitly required
+ifneq ($(my_cc)$(my_cxx),)
+ ifeq ($(my_clang),)
+ my_clang := false
+ endif
+endif
+# Issue warning if LOCAL_CLANG* is set to false and the local makefile is not found
+# in the exception project list.
+ifeq ($(my_clang),false)
+ ifeq ($(call find_in_local_clang_exception_projects,$(LOCAL_MODULE_MAKEFILE)),)
+ $(error $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): LOCAL_CLANG is set to false)
+ endif
+endif
+
# clang is enabled by default for host builds
# enable it unless we've specifically disabled clang above
ifdef LOCAL_IS_HOST_MODULE
- ifneq ($($(my_prefix)OS),windows)
- ifeq ($(my_clang),)
- my_clang := true
- endif
+ ifeq ($($(my_prefix)OS),windows)
+ ifeq ($(my_clang),true)
+ $(error $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Clang is not yet supported for windows binaries)
+ endif
+ my_clang := false
+ else
+ ifeq ($(my_clang),)
+ my_clang := true
+ endif
endif
# Add option to make gcc the default for device build
else ifeq ($(USE_CLANG_PLATFORM_BUILD),false)
@@ -226,34 +395,56 @@
my_clang := true
endif
-my_cpp_std_version := -std=gnu++14
+ifeq ($(LOCAL_C_STD),)
+ my_c_std_version := $(DEFAULT_C_STD_VERSION)
+else ifeq ($(LOCAL_C_STD),experimental)
+ my_c_std_version := $(EXPERIMENTAL_C_STD_VERSION)
+else
+ my_c_std_version := $(LOCAL_C_STD)
+endif
+
+ifeq ($(LOCAL_CPP_STD),)
+ my_cpp_std_version := $(DEFAULT_CPP_STD_VERSION)
+else ifeq ($(LOCAL_CPP_STD),experimental)
+ my_cpp_std_version := $(EXPERIMENTAL_CPP_STD_VERSION)
+else
+ my_cpp_std_version := $(LOCAL_CPP_STD)
+endif
ifneq ($(my_clang),true)
# GCC uses an invalid C++14 ABI (emits calls to
# __cxa_throw_bad_array_length, which is not a valid C++ RT ABI).
# http://b/25022512
- my_cpp_std_version := -std=gnu++11
+ my_cpp_std_version := $(DEFAULT_GCC_CPP_STD_VERSION)
endif
ifdef LOCAL_SDK_VERSION
# The NDK handles this itself.
- my_cpp_std_version :=
+ my_cpp_std_version := $(my_ndk_cpp_std_version)
endif
ifdef LOCAL_IS_HOST_MODULE
ifneq ($(my_clang),true)
# The host GCC doesn't support C++14 (and is deprecated, so likely
# never will). Build these modules with C++11.
- my_cpp_std_version := -std=gnu++11
+ my_cpp_std_version := $(DEFAULT_GCC_CPP_STD_VERSION)
endif
endif
-my_cppflags := $(my_cpp_std_version) $(my_cppflags)
+my_c_std_conlyflags :=
+my_cpp_std_cppflags :=
+ifneq (,$(my_c_std_version))
+ my_c_std_conlyflags := -std=$(my_c_std_version)
+endif
+ifneq (,$(my_cpp_std_version))
+ my_cpp_std_cppflags := -std=$(my_cpp_std_version)
+endif
# arch-specific static libraries go first so that generic ones can depend on them
my_static_libraries := $(LOCAL_STATIC_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_STATIC_LIBRARIES_$(my_32_64_bit_suffix)) $(my_static_libraries)
my_whole_static_libraries := $(LOCAL_WHOLE_STATIC_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_WHOLE_STATIC_LIBRARIES_$(my_32_64_bit_suffix)) $(my_whole_static_libraries)
+my_header_libraries := $(LOCAL_HEADER_LIBRARIES_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_HEADER_LIBRARIES_$(my_32_64_bit_suffix)) $(my_header_libraries)
include $(BUILD_SYSTEM)/cxx_stl_setup.mk
@@ -269,15 +460,32 @@
ifneq ($(strip $(CUSTOM_$(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)LINKER)),)
my_linker := $(CUSTOM_$(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)LINKER)
else
- my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LINKER)
+ my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LINKER)
endif
include $(BUILD_SYSTEM)/config_sanitizers.mk
+ifneq ($(LOCAL_NO_LIBCOMPILER_RT),true)
# Add in libcompiler_rt for all regular device builds
-ifeq (,$(LOCAL_SDK_VERSION)$(WITHOUT_LIBCOMPILER_RT))
+ifeq (,$(WITHOUT_LIBCOMPILER_RT))
my_static_libraries += $(COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES)
endif
+endif
+
+# Statically link libwinpthread when cross compiling win32.
+ifeq ($($(my_prefix)OS),windows)
+ my_static_libraries += libwinpthread
+endif
+
+ifneq ($(filter ../%,$(my_src_files)),)
+my_soong_problems += dotdot_srcs
+endif
+ifneq ($(foreach i,$(my_c_includes),$(filter %/..,$(i))$(findstring /../,$(i))),)
+my_soong_problems += dotdot_incs
+endif
+ifneq ($(filter %.arm,$(my_src_files)),)
+my_soong_problems += srcs_dotarm
+endif
####################################################
## Add FDO flags if FDO is turned on and supported
@@ -306,35 +514,48 @@
###########################################################
my_asflags += -D__ASSEMBLY__
-
###########################################################
## Define PRIVATE_ variables from global vars
###########################################################
ifndef LOCAL_IS_HOST_MODULE
-ifdef LOCAL_SDK_VERSION
-my_target_project_includes :=
-my_target_c_includes := $(my_ndk_stl_include_path) $(my_ndk_sysroot_include)
-my_target_global_cppflags := $(my_ndk_stl_cppflags)
+ifdef LOCAL_USE_VNDK
+my_target_global_c_includes := \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_INCLUDES)
+my_target_global_c_system_includes := \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_SYSTEM_INCLUDES)
+else ifdef LOCAL_SDK_VERSION
+my_target_global_c_includes :=
+my_target_global_c_system_includes := $(my_ndk_stl_include_path) $(my_ndk_sysroot_include)
+else ifdef BOARD_VNDK_VERSION
+my_target_global_c_includes := $(SRC_HEADERS) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_INCLUDES) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_INCLUDES)
+my_target_global_c_system_includes := $(SRC_SYSTEM_HEADERS) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_SYSTEM_INCLUDES) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_SYSTEM_INCLUDES)
else
-my_target_project_includes := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_PROJECT_INCLUDES)
-my_target_c_includes := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_C_INCLUDES)
-my_target_global_cppflags :=
-endif # LOCAL_SDK_VERSION
+my_target_global_c_includes := $(SRC_HEADERS) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_INCLUDES) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_INCLUDES)
+my_target_global_c_system_includes := $(SRC_SYSTEM_HEADERS) $(TARGET_OUT_HEADERS) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_SYSTEM_INCLUDES) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_SYSTEM_INCLUDES)
+endif
ifeq ($(my_clang),true)
-my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_CFLAGS)
-my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_CONLYFLAGS)
-my_target_global_cppflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_CPPFLAGS)
-my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_TARGET_GLOBAL_LDFLAGS)
+my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CFLAGS)
+my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
+my_target_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CPPFLAGS) $(my_cpp_std_cppflags)
+my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LDFLAGS)
else
-my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CFLAGS)
-my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CONLYFLAGS)
-my_target_global_cppflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CPPFLAGS)
-my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LDFLAGS)
+my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CFLAGS)
+my_target_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
+my_target_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CPPFLAGS) $(my_cpp_std_cppflags)
+my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_LDFLAGS)
endif # my_clang
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_PROJECT_INCLUDES := $(my_target_project_includes)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_C_INCLUDES := $(my_target_c_includes)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_GLOBAL_C_INCLUDES := $(my_target_global_c_includes)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_GLOBAL_C_SYSTEM_INCLUDES := $(my_target_global_c_system_includes)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CFLAGS := $(my_target_global_cflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CONLYFLAGS := $(my_target_global_conlyflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CPPFLAGS := $(my_target_global_cppflags)
@@ -342,21 +563,25 @@
else # LOCAL_IS_HOST_MODULE
+my_host_global_c_includes := $(SRC_HEADERS) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_INCLUDES)
+my_host_global_c_system_includes := $(SRC_SYSTEM_HEADERS) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_SYSTEM_INCLUDES)
+
ifeq ($(my_clang),true)
my_host_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CFLAGS)
-my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CONLYFLAGS)
-my_host_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CPPFLAGS)
+my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
+my_host_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CPPFLAGS) $(my_cpp_std_cppflags)
my_host_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_LDFLAGS)
-my_host_c_includes := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_INCLUDES)
else
my_host_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CFLAGS)
-my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CONLYFLAGS)
-my_host_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CPPFLAGS)
+my_host_global_conlyflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CONLYFLAGS) $(my_c_std_conlyflags)
+my_host_global_cppflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CPPFLAGS) $(my_cpp_std_cppflags)
my_host_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_LDFLAGS)
-my_host_c_includes := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_INCLUDES)
endif # my_clang
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_C_INCLUDES := $(my_host_c_includes)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_GLOBAL_C_INCLUDES := $(my_host_global_c_includes)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_GLOBAL_C_SYSTEM_INCLUDES := $(my_host_global_c_system_includes)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_GLOBAL_CFLAGS := $(my_host_global_cflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_GLOBAL_CONLYFLAGS := $(my_host_global_conlyflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HOST_GLOBAL_CPPFLAGS := $(my_host_global_cppflags)
@@ -378,28 +603,25 @@
my_cflags += --coverage -O0
my_ldflags += --coverage
endif
+
+ ifeq ($(my_clang),true)
+ my_coverage_lib := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LIBPROFILE_RT)
+ else
+ my_coverage_lib := $(call intermediates-dir-for,STATIC_LIBRARIES,libgcov,$(filter AUX,$(my_kind)),,$(LOCAL_2ND_ARCH_VAR_PREFIX))/libgcov.a
+ endif
+
+ $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_COVERAGE_LIB := $(my_coverage_lib)
+ $(LOCAL_INTERMEDIATE_TARGETS): $(my_coverage_lib)
else
my_native_coverage := false
endif
-ifeq ($(my_clang),true)
- my_coverage_lib := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBPROFILE_RT)
-else
- my_coverage_lib := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCOV)
-endif
-
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_COVERAGE_LIB := $(my_coverage_lib)
-
###########################################################
## Define PRIVATE_ variables used by multiple module types
###########################################################
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_NO_DEFAULT_COMPILER_FLAGS := \
$(strip $(LOCAL_NO_DEFAULT_COMPILER_FLAGS))
-ifeq ($(strip $(WITH_SYNTAX_CHECK)),)
- LOCAL_NO_SYNTAX_CHECK := true
-endif
-
ifeq ($(strip $(WITH_STATIC_ANALYZER)),)
LOCAL_NO_STATIC_ANALYZER := true
endif
@@ -413,7 +635,7 @@
ifneq ($(strip $(LOCAL_IS_HOST_MODULE)),)
my_syntax_arch := host
else
- my_syntax_arch := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+ my_syntax_arch := $($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
endif
ifeq ($(strip $(my_cc)),)
@@ -428,10 +650,6 @@
ifneq ($(LOCAL_NO_STATIC_ANALYZER),true)
my_cc := CCC_CC=$(CLANG) CLANG=$(CLANG) \
$(SYNTAX_TOOLS_PREFIX)/ccc-analyzer
-else
-ifneq ($(LOCAL_NO_SYNTAX_CHECK),true)
- my_cc := $(my_cc) -fsyntax-only
-endif
endif
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CC := $(my_cc)
@@ -448,10 +666,6 @@
ifneq ($(LOCAL_NO_STATIC_ANALYZER),true)
my_cxx := CCC_CXX=$(CLANG_CXX) CLANG_CXX=$(CLANG_CXX) \
$(SYNTAX_TOOLS_PREFIX)/c++-analyzer
-else
-ifneq ($(LOCAL_NO_SYNTAX_CHECK),true)
- my_cxx := $(my_cxx) -fsyntax-only
-endif
endif
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LINKER := $(my_linker)
@@ -467,9 +681,18 @@
# Certain modules like libdl have to have symbols resolved at runtime and blow
# up if --no-undefined is passed to the linker.
ifeq ($(strip $(LOCAL_NO_DEFAULT_COMPILER_FLAGS)),)
-ifeq ($(my_allow_undefined_symbols),)
- my_ldflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)NO_UNDEFINED_LDFLAGS)
-endif
+ ifeq ($(my_allow_undefined_symbols),)
+ ifneq ($(HOST_OS),darwin)
+ my_ldflags += -Wl,--no-undefined
+ endif
+ else
+ ifdef LOCAL_IS_HOST_MODULE
+ ifeq ($(HOST_OS),darwin)
+ # darwin defaults to treating undefined symbols as errors
+ my_ldflags += -Wl,-undefined,dynamic_lookup
+ endif
+ endif
+ endif
endif
ifeq (true,$(LOCAL_GROUP_STATIC_LIBRARIES))
@@ -492,8 +715,8 @@
arm_objects_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)$(arm_objects_mode)_CFLAGS)
normal_objects_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)$(normal_objects_mode)_CFLAGS)
ifeq ($(my_clang),true)
-arm_objects_cflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(arm_objects_cflags))
-normal_objects_cflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(normal_objects_cflags))
+arm_objects_cflags := $(call convert-to-clang-flags,$(arm_objects_cflags))
+normal_objects_cflags := $(call convert-to-clang-flags,$(normal_objects_cflags))
endif
else
@@ -530,7 +753,7 @@
my_gen_sources_copy := $(patsubst $(generated_sources_dir)/%,$(intermediates)/%,$(filter $(generated_sources_dir)/%,$(my_generated_sources)))
-$(my_gen_sources_copy): $(intermediates)/% : $(generated_sources_dir)/% | $(ACP)
+$(my_gen_sources_copy): $(intermediates)/% : $(generated_sources_dir)/%
@echo "Copy: $@"
$(copy-file-to-target)
@@ -551,6 +774,7 @@
renderscript_sources := $(filter %.rs %.fs,$(my_src_files))
ifneq (,$(renderscript_sources))
+my_soong_problems += rs
renderscript_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(renderscript_sources))
RenderScript_file_stamp := $(intermediates)/RenderScriptCPP.stamp
@@ -583,7 +807,7 @@
renderscript_includes := \
$(TOPDIR)external/clang/lib/Headers \
- $(TOPDIR)frameworks/rs/scriptc \
+ $(TOPDIR)frameworks/rs/script_api/include \
$(LOCAL_RENDERSCRIPT_INCLUDES)
ifneq ($(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE),)
@@ -603,8 +827,8 @@
$(RenderScript_file_stamp): $(renderscript_sources_fullpath) $(LOCAL_RENDERSCRIPT_CC)
$(transform-renderscripts-to-cpp-and-bc)
-# include the dependency files (.d/.P) generated by llvm-rs-cc.
-$(call include-depfile,$(RenderScript_file_stamp).P,$(RenderScript_file_stamp))
+# include the dependency files (.d) generated by llvm-rs-cc.
+$(call include-depfile,$(RenderScript_file_stamp).d,$(RenderScript_file_stamp))
LOCAL_INTERMEDIATE_TARGETS += $(RenderScript_file_stamp)
@@ -631,6 +855,7 @@
proto_sources := $(filter %.proto,$(my_src_files))
ifneq ($(proto_sources),)
proto_gen_dir := $(generated_sources_dir)/proto
+proto_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(proto_sources))
my_rename_cpp_ext :=
ifneq (,$(filter nanopb-c nanopb-c-enable_malloc, $(LOCAL_PROTOC_OPTIMIZE_TYPE)))
@@ -638,6 +863,7 @@
my_proto_c_includes := external/nanopb-c
my_protoc_flags := --nanopb_out=$(proto_gen_dir) \
--plugin=external/nanopb-c/generator/protoc-gen-nanopb
+my_protoc_deps := $(NANOPB_SRCS) $(proto_sources_fullpath:%.proto=%.options)
else
my_proto_source_suffix := $(LOCAL_CPP_EXTENSION)
ifneq ($(my_proto_source_suffix),.cc)
@@ -648,10 +874,10 @@
my_proto_c_includes := external/protobuf/src
my_cflags += -DGOOGLE_PROTOBUF_NO_RTTI
my_protoc_flags := --cpp_out=$(proto_gen_dir)
+my_protoc_deps :=
endif
my_proto_c_includes += $(proto_gen_dir)
-proto_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(proto_sources))
proto_generated_cpps := $(addprefix $(proto_gen_dir)/, \
$(patsubst %.proto,%.pb$(my_proto_source_suffix),$(proto_sources_fullpath)))
@@ -671,7 +897,7 @@
proto_intermediate_dir := $(intermediates)/proto
proto_intermediate_cpps := $(patsubst $(proto_gen_dir)/%,$(proto_intermediate_dir)/%,\
$(proto_generated_cpps))
-$(proto_intermediate_cpps) : $(proto_intermediate_dir)/% : $(proto_gen_dir)/% | $(ACP)
+$(proto_intermediate_cpps) : $(proto_intermediate_dir)/% : $(proto_gen_dir)/%
@echo "Copy: $@"
$(copy-file-to-target)
$(hide) cp $(basename $<).h $(basename $@).h
@@ -693,6 +919,8 @@
else
my_shared_libraries += libprotobuf-cpp-full
endif
+else ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),lite-static)
+ my_static_libraries += libprotobuf-cpp-lite
else
ifdef LOCAL_SDK_VERSION
my_static_libraries += libprotobuf-cpp-lite-ndk
@@ -703,61 +931,6 @@
endif # $(proto_sources) non-empty
###########################################################
-## Compile the .dbus-xml files to c++ headers
-###########################################################
-dbus_definitions := $(filter %.dbus-xml,$(my_src_files))
-dbus_generated_headers :=
-ifneq ($(dbus_definitions),)
-
-dbus_definition_paths := $(addprefix $(LOCAL_PATH)/,$(dbus_definitions))
-dbus_service_config := $(filter %dbus-service-config.json,$(my_src_files))
-dbus_service_config_path := $(addprefix $(LOCAL_PATH)/,$(dbus_service_config))
-
-# Mark these source files as not producing objects
-$(call track-src-file-obj,$(dbus_definitions) $(dbus_service_config),)
-
-dbus_gen_dir := $(generated_sources_dir)/dbus_bindings
-
-ifdef LOCAL_DBUS_PROXY_PREFIX
-dbus_header_dir := $(dbus_gen_dir)/include/$(LOCAL_DBUS_PROXY_PREFIX)
-dbus_headers := dbus-proxies.h
-else
-dbus_header_dir := $(dbus_gen_dir)
-dbus_headers := $(patsubst %.dbus-xml,%.h,$(dbus_definitions))
-endif
-dbus_generated_headers := $(addprefix $(dbus_header_dir)/,$(dbus_headers))
-
-# Ensure that we only define build rules once in multilib builds.
-ifndef $(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_dbus_bindings_defined
-$(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_dbus_bindings_defined := true
-
-$(dbus_generated_headers): PRIVATE_MODULE := $(LOCAL_MODULE)
-$(dbus_generated_headers): PRIVATE_DBUS_SERVICE_CONFIG := $(dbus_service_config_path)
-$(dbus_generated_headers) : $(dbus_service_config_path) $(DBUS_GENERATOR)
-ifdef LOCAL_DBUS_PROXY_PREFIX
-$(dbus_generated_headers) : $(dbus_definition_paths)
- $(generate-dbus-proxies)
-else
-$(dbus_generated_headers) : $(dbus_header_dir)/%.h : $(LOCAL_PATH)/%.dbus-xml
- $(generate-dbus-adaptors)
-endif # $(LOCAL_DBUS_PROXY_PREFIX)
-endif # $(my_prefix)_$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_dbus_bindings_defined
-
-ifdef LOCAL_DBUS_PROXY_PREFIX
-# Auto-export the generated dbus proxy directory.
-my_export_c_include_dirs += $(dbus_gen_dir)/include
-my_c_includes += $(dbus_gen_dir)/include
-else
-my_export_c_include_dirs += $(dbus_header_dir)
-my_c_includes += $(dbus_header_dir)
-endif # $(LOCAL_DBUS_PROXY_PREFIX)
-
-my_generated_sources += $(dbus_generated_headers)
-
-endif # $(dbus_definitions) non-empty
-
-
-###########################################################
## AIDL: Compile .aidl files to .cpp and .h files
###########################################################
aidl_src := $(strip $(filter %.aidl,$(my_src_files)))
@@ -773,7 +946,7 @@
$(foreach s,$(aidl_src),\
$(eval $(call define-aidl-cpp-rule,$(s),$(aidl_gen_cpp_root),aidl_gen_cpp)))
$(foreach cpp,$(aidl_gen_cpp), \
- $(call include-depfile,$(addsuffix .aidl.P,$(basename $(cpp))),$(cpp)))
+ $(call include-depfile,$(addsuffix .aidl.d,$(basename $(cpp))),$(cpp)))
$(call track-src-file-gen,$(aidl_src),$(aidl_gen_cpp))
$(aidl_gen_cpp) : PRIVATE_MODULE := $(LOCAL_MODULE)
@@ -795,6 +968,7 @@
vts_src := $(strip $(filter %.vts,$(my_src_files)))
vts_gen_cpp :=
ifneq ($(vts_src),)
+my_soong_problems += vts
# Use the intermediates directory to avoid writing our own .cpp -> .o rules.
vts_gen_cpp_root := $(intermediates)/vts-generated/src
@@ -829,7 +1003,7 @@
$(intermediates)/,$(y_yacc_sources:.y=.c))
ifneq ($(y_yacc_cs),)
$(y_yacc_cs): $(intermediates)/%.c: \
- $(TOPDIR)$(LOCAL_PATH)/%.y \
+ $(TOPDIR)$(LOCAL_PATH)/%.y $(BISON) $(BISON_DATA) \
$(my_additional_dependencies)
$(call transform-y-to-c-or-cpp)
$(call track-src-file-gen,$(y_yacc_sources),$(y_yacc_cs))
@@ -842,7 +1016,7 @@
$(intermediates)/,$(yy_yacc_sources:.yy=$(LOCAL_CPP_EXTENSION)))
ifneq ($(yy_yacc_cpps),)
$(yy_yacc_cpps): $(intermediates)/%$(LOCAL_CPP_EXTENSION): \
- $(TOPDIR)$(LOCAL_PATH)/%.yy \
+ $(TOPDIR)$(LOCAL_PATH)/%.yy $(BISON) $(BISON_DATA) \
$(my_additional_dependencies)
$(call transform-y-to-c-or-cpp)
$(call track-src-file-gen,$(yy_yacc_sources),$(yy_yacc_cpps))
@@ -970,7 +1144,7 @@
ifneq ($(strip $(gen_s_objects)),)
$(gen_s_objects): $(intermediates)/%.o: $(intermediates)/%.s \
$(my_additional_dependencies)
- $(transform-$(PRIVATE_HOST)s-to-o-no-deps)
+ $(transform-$(PRIVATE_HOST)s-to-o)
endif
gen_asm_objects := $(gen_S_objects) $(gen_s_objects)
@@ -1057,6 +1231,7 @@
$(call track-src-file-obj,$(objc_sources),$(objc_objects))
ifneq ($(strip $(objc_objects)),)
+my_soong_problems += objc
$(objc_objects): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.m \
$(my_additional_dependencies)
$(transform-$(PRIVATE_HOST)m-to-o)
@@ -1118,7 +1293,7 @@
ifneq ($(strip $(asm_objects_s)),)
$(asm_objects_s): $(intermediates)/%.o: $(TOPDIR)$(LOCAL_PATH)/%.s \
$(my_additional_dependencies)
- $(transform-$(PRIVATE_HOST)s-to-o-no-deps)
+ $(transform-$(PRIVATE_HOST)s-to-o)
endif
asm_objects := $(dotdot_objects_S) $(dotdot_objects_s) $(asm_objects_S) $(asm_objects_s)
@@ -1137,6 +1312,36 @@
asm_objects += $(asm_objects_asm)
endif
+###########################################################
+## When compiling against the VNDK, use LL-NDK libraries
+###########################################################
+ifneq ($(LOCAL_USE_VNDK),)
+ ####################################################
+ ## Soong modules may be built twice, once for /system
+ ## and once for /vendor. If we're using the VNDK,
+ ## switch all soong libraries over to the /vendor
+ ## variant.
+ ####################################################
+ ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ # Soong-built libraries should always use the .vendor variant
+ my_whole_static_libraries := $(addsuffix .vendor,$(my_whole_static_libraries))
+ my_static_libraries := $(addsuffix .vendor,$(my_static_libraries))
+ my_shared_libraries := $(addsuffix .vendor,$(my_shared_libraries))
+ my_system_shared_libraries := $(addsuffix .vendor,$(my_system_shared_libraries))
+ my_header_libraries := $(addsuffix .vendor,$(my_header_libraries))
+ else
+ my_whole_static_libraries := $(foreach l,$(my_whole_static_libraries),\
+ $(if $(SPLIT_VENDOR.STATIC_LIBRARIES.$(l)),$(l).vendor,$(l)))
+ my_static_libraries := $(foreach l,$(my_static_libraries),\
+ $(if $(SPLIT_VENDOR.STATIC_LIBRARIES.$(l)),$(l).vendor,$(l)))
+ my_shared_libraries := $(foreach l,$(my_shared_libraries),\
+ $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+ my_system_shared_libraries := $(foreach l,$(my_system_shared_libraries),\
+ $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+ my_header_libraries := $(foreach l,$(my_header_libraries),\
+ $(if $(SPLIT_VENDOR.HEADER_LIBRARIES.$(l)),$(l).vendor,$(l)))
+ endif
+endif
##########################################################
## Set up installed module dependency
@@ -1144,7 +1349,7 @@
## they may cusomize their install path with LOCAL_MODULE_PATH
##########################################################
# Get the list of INSTALLED libraries as module names.
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION),)
installed_shared_library_module_names := \
$(my_shared_libraries)
else
@@ -1168,11 +1373,13 @@
import_includes := $(intermediates)/import_includes
import_includes_deps := $(strip \
$(foreach l, $(installed_shared_library_module_names), \
- $(call intermediates-dir-for,SHARED_LIBRARIES,$(l),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes) \
+ $(call intermediates-dir-for,SHARED_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes) \
$(foreach l, $(my_static_libraries) $(my_whole_static_libraries), \
- $(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes))
+ $(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes) \
+ $(foreach l, $(my_header_libraries), \
+ $(call intermediates-dir-for,HEADER_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes))
$(import_includes): PRIVATE_IMPORT_EXPORT_INCLUDES := $(import_includes_deps)
-$(import_includes) : $(LOCAL_MODULE_MAKEFILE_DEP) $(import_includes_deps)
+$(import_includes) : $(import_includes_deps)
@echo Import includes file: $@
$(hide) mkdir -p $(dir $@) && rm -f $@
ifdef import_includes_deps
@@ -1183,13 +1390,41 @@
$(hide) touch $@
endif
+####################################################
+## Verify that NDK-built libraries only link against
+## other NDK-built libraries
+####################################################
+
+ifdef LOCAL_SDK_VERSION
+my_link_type := native:ndk
+my_warn_types :=
+my_allowed_types := native:ndk
+else ifdef LOCAL_USE_VNDK
+my_link_type := native:vendor
+my_warn_types :=
+my_allowed_types := native:vendor
+else
+my_link_type := native:platform
+my_warn_types :=
+my_allowed_types := native:ndk native:platform
+endif
+
+my_link_deps := $(addprefix STATIC_LIBRARIES:,$(my_whole_static_libraries) $(my_static_libraries))
+ifneq ($(filter-out STATIC_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+my_link_deps += $(addprefix SHARED_LIBRARIES:,$(my_shared_libraries))
+endif
+
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+my_common :=
+include $(BUILD_SYSTEM)/link_type.mk
+
###########################################################
## Common object handling.
###########################################################
my_unused_src_files := $(filter-out $(logtags_sources) $(my_tracked_src_files),$(my_src_files) $(my_gen_src_files))
ifneq ($(my_unused_src_files),)
- $(warning $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Unused source files: $(my_unused_src_files))
+ $(error $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Unused source files: $(my_unused_src_files))
endif
# some rules depend on asm_objects being first. If your code depends on
@@ -1233,16 +1468,17 @@
my_c_includes += $(JNI_H_INCLUDE)
endif
+my_outside_includes := $(filter-out $(OUT_DIR)/%,$(filter /%,$(my_c_includes)))
+ifneq ($(my_outside_includes),)
+$(error $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): C_INCLUDES must be under the source or output directories: $(my_outside_includes))
+endif
+
# all_objects includes gen_o_objects which were part of LOCAL_GENERATED_SOURCES;
# use normal_objects here to avoid creating circular dependencies. This assumes
# that custom build rules which generate .o files don't consume other generated
# sources as input (or if they do they take care of that dependency themselves).
$(normal_objects) : | $(my_generated_sources)
-ifeq ($(BUILDING_WITH_NINJA),true)
$(all_objects) : $(import_includes)
-else
-$(all_objects) : | $(import_includes)
-endif
ALL_C_CPP_ETC_OBJECTS += $(all_objects)
@@ -1279,7 +1515,7 @@
so_suffix := $($(my_prefix)SHLIB_SUFFIX)
a_suffix := $($(my_prefix)STATIC_LIB_SUFFIX)
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION),)
built_shared_libraries := \
$(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
$(addsuffix $(so_suffix), \
@@ -1292,26 +1528,32 @@
$(addprefix $(my_ndk_sysroot_lib)/, \
$(addsuffix $(so_suffix), $(my_system_shared_libraries)))
-built_shared_libraries += $(my_system_shared_libraries_fullpath)
+# We need to preserve the ordering of LOCAL_SHARED_LIBRARIES regardless of
+# whether the libs are generated or prebuilt, so we simply can't split into two
+# lists and use addprefix.
+my_ndk_shared_libraries_fullpath := \
+ $(foreach _lib,$(my_ndk_shared_libraries),\
+ $(if $(filter $(NDK_MIGRATED_LIBS),$(_lib)),\
+ $(my_built_ndk_libs)/$(_lib)$(so_suffix),\
+ $(my_ndk_sysroot_lib)/$(_lib)$(so_suffix)))
+
+built_shared_libraries += \
+ $(my_ndk_shared_libraries_fullpath) \
+ $(my_system_shared_libraries_fullpath) \
+
else
built_shared_libraries := \
$(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
$(addsuffix $(so_suffix), \
$(installed_shared_library_module_names)))
-ifdef LOCAL_IS_HOST_MODULE
-# Disable .toc optimization for host modules: we may run the host binaries during the build process
-# and the libraries' implementation matters.
-built_shared_library_deps := $(built_shared_libraries)
-else
built_shared_library_deps := $(addsuffix .toc, $(built_shared_libraries))
-endif
my_system_shared_libraries_fullpath :=
endif
built_static_libraries := \
$(foreach lib,$(my_static_libraries), \
$(call intermediates-dir-for, \
- STATIC_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/$(lib)$(a_suffix))
+ STATIC_LIBRARIES,$(lib),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/$(lib)$(a_suffix))
ifdef LOCAL_SDK_VERSION
built_static_libraries += $(my_ndk_stl_static_lib)
@@ -1320,7 +1562,7 @@
built_whole_libraries := \
$(foreach lib,$(my_whole_static_libraries), \
$(call intermediates-dir-for, \
- STATIC_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/$(lib)$(a_suffix))
+ STATIC_LIBRARIES,$(lib),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/$(lib)$(a_suffix))
# We don't care about installed static libraries, since the
# libraries have already been linked into the module at that point.
@@ -1353,10 +1595,14 @@
my_cppflags += $(LOCAL_CLANG_CPPFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_CPPFLAGS_$(my_32_64_bit_suffix))
my_ldflags += $(LOCAL_CLANG_LDFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_LDFLAGS_$(my_32_64_bit_suffix))
my_asflags += $(LOCAL_CLANG_ASFLAGS_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) $(LOCAL_CLANG_ASFLAGS_$(my_32_64_bit_suffix))
-my_cflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_cflags))
-my_cppflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_cppflags))
-my_asflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_asflags))
-my_ldflags := $(call $(LOCAL_2ND_ARCH_VAR_PREFIX)convert-to-$(my_host)clang-flags,$(my_ldflags))
+my_cflags := $(call convert-to-clang-flags,$(my_cflags))
+my_cppflags := $(call convert-to-clang-flags,$(my_cppflags))
+my_asflags := $(call convert-to-clang-flags,$(my_asflags))
+my_ldflags := $(call convert-to-clang-flags,$(my_ldflags))
+else
+# gcc does not handle hidden functions in a manner compatible with LLVM libcxx
+# see b/27908145
+my_cflags += -Wno-attributes
endif
ifeq ($(my_fdo_build), true)
@@ -1374,6 +1620,103 @@
my_cppflags := $(filter-out $(my_illegal_flags),$(my_cppflags))
my_conlyflags := $(filter-out $(my_illegal_flags),$(my_conlyflags))
+# We can enforce some rules more strictly in the code we own. my_strict
+# indicates if this is code that we can be stricter with. If we have rules that
+# we want to apply to *our* code (but maybe can't for vendor/device specific
+# things), we could extend this to be a ternary value.
+my_strict := true
+ifneq ($(filter external/%,$(LOCAL_PATH)),)
+ my_strict := false
+endif
+
+# Can be used to make some annotations stricter for code we can fix (such as
+# when we mark functions as deprecated).
+ifeq ($(my_strict),true)
+ my_cflags += -DANDROID_STRICT
+endif
+
+# Add -Werror if LOCAL_PATH is in the WARNING_DISALLOWED project list,
+# or not in the WARNING_ALLOWED project list.
+ifneq (,$(strip $(call find_warning_disallowed_projects,$(LOCAL_PATH))))
+ my_cflags_no_override += -Werror
+else
+ ifeq (,$(strip $(call find_warning_allowed_projects,$(LOCAL_PATH))))
+ my_cflags_no_override += -Werror
+ endif
+endif
+
+# Disable clang-tidy if it is not found.
+ifeq ($(PATH_TO_CLANG_TIDY),)
+ my_tidy_enabled := false
+else
+ # If LOCAL_TIDY is not defined, use global WITH_TIDY
+ my_tidy_enabled := $(LOCAL_TIDY)
+ ifeq ($(my_tidy_enabled),)
+ my_tidy_enabled := $(WITH_TIDY)
+ endif
+endif
+
+# my_tidy_checks is empty if clang-tidy is disabled.
+my_tidy_checks :=
+my_tidy_flags :=
+ifneq (,$(filter 1 true,$(my_tidy_enabled)))
+ ifneq ($(my_clang),true)
+ # Disable clang-tidy if clang is disabled.
+ my_tidy_enabled := false
+ else
+ tidy_only: $(cpp_objects) $(c_objects)
+ # Set up global default checks
+ my_tidy_checks := $(WITH_TIDY_CHECKS)
+ ifeq ($(my_tidy_checks),)
+ my_tidy_checks := $(call default_global_tidy_checks,$(LOCAL_PATH))
+ endif
+ # Append local clang-tidy checks.
+ ifneq ($(LOCAL_TIDY_CHECKS),)
+ my_tidy_checks := $(my_tidy_checks),$(LOCAL_TIDY_CHECKS)
+ endif
+ # Set up global default clang-tidy flags, which is none.
+ my_tidy_flags := $(WITH_TIDY_FLAGS)
+ # Use local clang-tidy flags if specified.
+ ifneq ($(LOCAL_TIDY_FLAGS),)
+ my_tidy_flags := $(LOCAL_TIDY_FLAGS)
+ endif
+ # If tidy flags are not specified, default to check all header files.
+ ifeq ($(my_tidy_flags),)
+ my_tidy_flags := $(call default_tidy_header_filter,$(LOCAL_PATH))
+ endif
+
+ # We might be using the static analyzer through clang-tidy.
+ # https://bugs.llvm.org/show_bug.cgi?id=32914
+ ifneq ($(my_tidy_checks),)
+ my_tidy_flags += "-extra-arg-before=-D__clang_analyzer__"
+ endif
+ endif
+endif
+
+my_tidy_checks := $(subst $(space),,$(my_tidy_checks))
+
+# Move -l* entries from ldflags to ldlibs, and everything else to ldflags
+my_ldlib_flags := $(my_ldflags) $(my_ldlibs)
+my_ldlibs := $(filter -l%,$(my_ldlib_flags))
+my_ldflags := $(filter-out -l%,$(my_ldlib_flags))
+
+# One last verification check for ldlibs
+ifndef LOCAL_IS_HOST_MODULE
+my_allowed_ldlibs :=
+ifneq ($(LOCAL_SDK_VERSION),)
+ my_allowed_ldlibs := $(addprefix -l,$(NDK_PREBUILT_SHARED_LIBRARIES))
+endif
+
+my_bad_ldlibs := $(filter-out $(my_allowed_ldlibs),$(my_ldlibs))
+ifneq ($(my_bad_ldlibs),)
+ $(error $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Bad LOCAL_LDLIBS entries: $(my_bad_ldlibs))
+endif
+endif
+
+# my_cxx_ldlibs may contain linker flags need to wrap certain libraries
+# (start-group/end-group), so append after the check above.
+my_ldlibs += $(my_cxx_ldlibs)
+
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASFLAGS := $(my_asflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CONLYFLAGS := $(my_conlyflags)
@@ -1387,13 +1730,16 @@
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_IMPORT_INCLUDES := $(import_includes)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LDFLAGS := $(my_ldflags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LDLIBS := $(my_ldlibs)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TIDY_CHECKS := $(my_tidy_checks)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TIDY_FLAGS := $(my_tidy_flags)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ARFLAGS := $(my_arflags)
# this is really the way to get the files onto the command line instead
# of using $^, because then LOCAL_ADDITIONAL_DEPENDENCIES doesn't work
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_SHARED_LIBRARIES := $(built_shared_libraries)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_STATIC_LIBRARIES := $(built_static_libraries)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_WHOLE_STATIC_LIBRARIES := $(built_whole_libraries)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_OBJECTS := $(all_objects)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_OBJECTS := $(strip $(all_objects))
###########################################################
# Define library dependencies.
@@ -1414,31 +1760,86 @@
# Export includes
###########################################################
export_includes := $(intermediates)/export_includes
-$(export_includes): PRIVATE_EXPORT_C_INCLUDE_DIRS := $(my_export_c_include_dirs)
+export_cflags := $(foreach d,$(my_export_c_include_dirs),-I $(d))
+# Soong exports cflags instead of include dirs, so that -isystem can be included.
+ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+export_cflags += $(LOCAL_EXPORT_CFLAGS)
+else ifdef LOCAL_EXPORT_CFLAGS
+$(call pretty-error,LOCAL_EXPORT_CFLAGS can only be used by Soong, use LOCAL_EXPORT_C_INCLUDE_DIRS instead)
+endif
+$(export_includes): PRIVATE_EXPORT_CFLAGS := $(export_cflags)
+# Headers exported by whole static libraries are also exported by this library.
+export_include_deps := $(strip \
+ $(foreach l,$(my_whole_static_libraries), \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes))
+# Re-export requested headers from shared libraries.
+export_include_deps += $(strip \
+ $(foreach l,$(LOCAL_EXPORT_SHARED_LIBRARY_HEADERS), \
+ $(call intermediates-dir-for,SHARED_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes))
+# Re-export requested headers from static libraries.
+export_include_deps += $(strip \
+ $(foreach l,$(LOCAL_EXPORT_STATIC_LIBRARY_HEADERS), \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes))
+# Re-export requested headers from header libraries.
+export_include_deps += $(strip \
+ $(foreach l,$(LOCAL_EXPORT_HEADER_LIBRARY_HEADERS), \
+ $(call intermediates-dir-for,HEADER_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/export_includes))
+$(export_includes): PRIVATE_REEXPORTED_INCLUDES := $(export_include_deps)
# By adding $(my_generated_sources) it makes sure the headers get generated
# before any dependent source files get compiled.
-$(export_includes) : $(my_generated_sources) $(export_include_deps)
+$(export_includes) : $(my_export_c_include_deps) $(my_generated_sources) $(export_include_deps) $(LOCAL_EXPORT_C_INCLUDE_DEPS)
@echo Export includes file: $< -- $@
- $(hide) mkdir -p $(dir $@) && rm -f $@.tmp
-ifdef my_export_c_include_dirs
- $(hide) for d in $(PRIVATE_EXPORT_C_INCLUDE_DIRS); do \
- echo "-I $$d" >> $@.tmp; \
- done
-else
- $(hide) touch $@.tmp
+ $(hide) mkdir -p $(dir $@) && rm -f $@.tmp && touch $@.tmp
+ifdef export_cflags
+ $(hide) echo "$(PRIVATE_EXPORT_CFLAGS)" >>$@.tmp
endif
-ifeq ($(BUILDING_WITH_NINJA),true)
+ifdef export_include_deps
+ $(hide) for f in $(PRIVATE_REEXPORTED_INCLUDES); do \
+ cat $$f >> $@.tmp; \
+ done
+endif
$(hide) if cmp -s $@.tmp $@ ; then \
rm $@.tmp ; \
else \
mv $@.tmp $@ ; \
fi
-else
- mv $@.tmp $@ ;
-endif
+export_cflags :=
# Kati adds restat=1 to ninja. GNU make does nothing for this.
.KATI_RESTAT: $(export_includes)
# Make sure export_includes gets generated when you are running mm/mmm
$(LOCAL_BUILT_MODULE) : | $(export_includes)
+
+ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ifneq (,$(filter-out $(LOCAL_PATH)/%,$(my_export_c_include_dirs)))
+my_soong_problems += non_local__export_c_include_dirs
+endif
+
+SOONG_CONV.$(LOCAL_MODULE).PROBLEMS := \
+ $(SOONG_CONV.$(LOCAL_MODULE).PROBLEMS) $(my_soong_problems)
+SOONG_CONV.$(LOCAL_MODULE).DEPS := \
+ $(SOONG_CONV.$(LOCAL_MODULE).DEPS) \
+ $(filter-out $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY),\
+ $(my_static_libraries) \
+ $(my_whole_static_libraries) \
+ $(my_shared_libraries) \
+ $(my_system_shared_libraries))
+SOONG_CONV := $(SOONG_CONV) $(LOCAL_MODULE)
+endif
+
+###########################################################
+# Coverage packaging.
+###########################################################
+ifeq ($(my_native_coverage),true)
+my_gcno_objects := \
+ $(cpp_objects) \
+ $(gen_cpp_objects) \
+ $(c_objects) \
+ $(gen_c_objects) \
+ $(objc_objects) \
+ $(objcpp_objects)
+
+LOCAL_GCNO_FILES := $(patsubst %.o,%.gcno,$(my_gcno_objects))
+$(foreach f,$(my_gcno_objects),$(eval $(call gcno-touch-rule,$(f),$(f:.o=.gcno))))
+endif
diff --git a/core/build-system.html b/core/build-system.html
index bddde6a..c7938cc 100644
--- a/core/build-system.html
+++ b/core/build-system.html
@@ -438,7 +438,7 @@
GEN := $(intermediates)/<font color=red>file.c</font>
$(GEN): PRIVATE_INPUT_FILE := $(LOCAL_PATH)/<font color=red>input.file</font>
$(GEN): PRIVATE_CUSTOM_TOOL = <font color=red>cat $(PRIVATE_INPUT_FILE) > $@</font>
-$(GEN): <font color=red>$(LOCAL_PATH)/file.c</font>
+$(GEN): <font color=red>$(LOCAL_PATH)/input.file</font>
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
</pre>
@@ -592,6 +592,17 @@
</ul>
</p>
+<h4>LOCAL_ANNOTATION_PROCESSORS</h4>
+<p>Set this to a list of modules built with <code>BUILD_HOST_JAVA_LIBRARY</code>
+to have their jars passed to javac with -processorpath for use as annotation
+processors.</p>
+
+<h4>LOCAL_ANNOTATION_PROCESSOR_CLASSES</h4>
+<p>Set this to a list of classes to be passed to javac as -processor arguments.
+This list is would be unnecessary, as javac will autodetect annotation processor
+classes, except that the Grok tool that is used on the Android source code
+does not autodetect them and requires listing them manually.</p>
+
<h4>LOCAL_ASSET_FILES</h4>
<p>In Android.mk files that <code>include $(BUILD_PACKAGE)</code> set this
to the set of files you want built into your app. Usually:</p>
@@ -707,6 +718,11 @@
them here. For example:</p>
<p><code>LOCAL_JAVACFLAGS += -Xlint:deprecation</code></p>
+<h4>LOCAL_ERROR_PRONE_FLAGS</h4>
+<p>If you have additional flags to pass into the error prone compiler, add
+them here. For example:</p>
+<p><code>LOCAL_ERROR_PRONE_FLAGS += -Xep:ClassCanBeStatic:ERROR</code></p>
+
<h4>LOCAL_JAVA_LIBRARIES</h4>
<p>When linking Java apps and libraries, <code>LOCAL_JAVA_LIBRARIES</code>
specifies which sets of java classes to include. Currently there are
diff --git a/core/ccache.mk b/core/ccache.mk
index 5c2ae23..d67bce6 100644
--- a/core/ccache.mk
+++ b/core/ccache.mk
@@ -17,7 +17,7 @@
ifneq ($(filter-out false,$(USE_CCACHE)),)
# The default check uses size and modification time, causing false misses
# since the mtime depends when the repo was checked out
- export CCACHE_COMPILERCHECK := content
+ export CCACHE_COMPILERCHECK ?= content
# See man page, optimizations to get more cache hits
# implies that __DATE__ and __TIME__ are not critical for functionality.
diff --git a/core/clang/HOST_CROSS_x86.mk b/core/clang/HOST_CROSS_x86.mk
index b78a074..bf48f95 100644
--- a/core/clang/HOST_CROSS_x86.mk
+++ b/core/clang/HOST_CROSS_x86.mk
@@ -1,56 +1 @@
-
-include $(BUILD_SYSTEM)/clang/x86.mk
-
-CLANG_CONFIG_x86_HOST_CROSS_TRIPLE := i686-pc-mingw32
-
-CLANG_CONFIG_x86_HOST_CROSS_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_HOST_CROSS_COMBO_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_x86_HOST_CROSS_TRIPLE)
-
-CLANG_CONFIG_x86_HOST_CROSS_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_HOST_CROSS_COMBO_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_HOST_CROSS_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_x86_HOST_CROSS_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_HOST_CROSS_COMBO_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_x86_HOST_CROSS_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_HOST_CROSS_COMBO_EXTRA_CPPFLAGS) \
- -target $(CLANG_CONFIG_x86_HOST_CROSS_TRIPLE)
-
-CLANG_CONFIG_x86_HOST_CROSS_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_HOST_CROSS_COMBO_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_x86_HOST_CROSS_TRIPLE)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_CFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_CROSS_EXTRA_CFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_CONLYFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_CROSS_EXTRA_CONLYFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_CPPFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_CROSS_EXTRA_CPPFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_LDFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_CROSS_EXTRA_LDFLAGS)
-
$(clang_2nd_arch_prefix)HOST_CROSS_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-i686.a
diff --git a/core/clang/HOST_CROSS_x86_64.mk b/core/clang/HOST_CROSS_x86_64.mk
index b6f2de9..f921a1c 100644
--- a/core/clang/HOST_CROSS_x86_64.mk
+++ b/core/clang/HOST_CROSS_x86_64.mk
@@ -1,56 +1 @@
-
-include $(BUILD_SYSTEM)/clang/x86_64.mk
-
-CLANG_CONFIG_x86_64_HOST_CROSS_TRIPLE := x86_64-pc-mingw32
-
-CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_COMBO_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_x86_64_HOST_CROSS_TRIPLE)
-
-CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_COMBO_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_COMBO_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_COMBO_EXTRA_CPPFLAGS) \
- -target $(CLANG_CONFIG_x86_64_HOST_CROSS_TRIPLE)
-
-CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_HOST_CROSS_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_COMBO_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_x86_64_HOST_CROSS_TRIPLE)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_CFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_CFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_CONLYFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_CONLYFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_CPPFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_CPPFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_CROSS_GLOBAL_LDFLAGS := \
- $(call convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_CROSS_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_CROSS_EXTRA_LDFLAGS)
-
$(clang_2nd_arch_prefix)HOST_CROSS_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-x86_64.a
diff --git a/core/clang/HOST_x86.mk b/core/clang/HOST_x86.mk
index 0ec64ad..0722b2a 100644
--- a/core/clang/HOST_x86.mk
+++ b/core/clang/HOST_x86.mk
@@ -1,77 +1 @@
-
-include $(BUILD_SYSTEM)/clang/x86.mk
-include $(BUILD_SYSTEM)/clang/HOST_x86_common.mk
-
-ifeq ($(HOST_OS),linux)
-CLANG_CONFIG_x86_HOST_TRIPLE := i686-linux-gnu
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_ASFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_ASFLAGS)
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CFLAGS)
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CPPFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CPPFLAGS)
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_LDFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_LDFLAGS)
-endif
-ifeq ($(HOST_OS),darwin)
-CLANG_CONFIG_x86_HOST_TRIPLE := i686-apple-darwin
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_ASFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_ASFLAGS)
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CFLAGS)
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CPPFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CPPFLAGS)
-CLANG_CONFIG_x86_HOST_COMBO_EXTRA_LDFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_LDFLAGS)
-endif
-
-CLANG_CONFIG_x86_HOST_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_HOST_COMBO_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_x86_HOST_TRIPLE)
-
-CLANG_CONFIG_x86_HOST_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_HOST_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_x86_HOST_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_x86_HOST_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_HOST_COMBO_EXTRA_CPPFLAGS) \
- -target $(CLANG_CONFIG_x86_HOST_TRIPLE)
-
-CLANG_CONFIG_x86_HOST_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_HOST_COMBO_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_x86_HOST_TRIPLE)
-
-define $(clang_2nd_arch_prefix)convert-to-host-clang-flags
- $(strip \
- $(call subst-clang-incompatible-x86-flags,\
- $(filter-out $(CLANG_CONFIG_x86_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-$(clang_2nd_arch_prefix)CLANG_HOST_GLOBAL_CFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_EXTRA_CFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_GLOBAL_CONLYFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_EXTRA_CONLYFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_GLOBAL_CPPFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_EXTRA_CPPFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_HOST_GLOBAL_LDFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-host-clang-flags,$($(clang_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_x86_HOST_EXTRA_LDFLAGS)
-
$(clang_2nd_arch_prefix)HOST_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-i686.a
diff --git a/core/clang/HOST_x86_64.mk b/core/clang/HOST_x86_64.mk
index d46cb67..4fdffd8 100644
--- a/core/clang/HOST_x86_64.mk
+++ b/core/clang/HOST_x86_64.mk
@@ -1,77 +1 @@
-
-include $(BUILD_SYSTEM)/clang/x86_64.mk
-include $(BUILD_SYSTEM)/clang/HOST_x86_common.mk
-
-ifeq ($(HOST_OS),linux)
-CLANG_CONFIG_x86_64_HOST_TRIPLE := x86_64-linux-gnu
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_ASFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_ASFLAGS)
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CFLAGS)
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CPPFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CPPFLAGS)
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_LDFLAGS := $(CLANG_CONFIG_x86_LINUX_HOST_EXTRA_LDFLAGS)
-endif
-ifeq ($(HOST_OS),darwin)
-CLANG_CONFIG_x86_64_HOST_TRIPLE := x86_64-apple-darwin
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_ASFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_ASFLAGS)
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CFLAGS)
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CPPFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CPPFLAGS)
-CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_LDFLAGS := $(CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_LDFLAGS)
-endif
-
-CLANG_CONFIG_x86_64_HOST_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_x86_64_HOST_TRIPLE)
-
-CLANG_CONFIG_x86_64_HOST_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_x86_64_HOST_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_x86_64_HOST_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_CPPFLAGS) \
- -target $(CLANG_CONFIG_x86_64_HOST_TRIPLE)
-
-CLANG_CONFIG_x86_64_HOST_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_HOST_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_64_HOST_COMBO_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_x86_64_HOST_TRIPLE)
-
-define convert-to-host-clang-flags
- $(strip \
- $(call subst-clang-incompatible-x86_64-flags,\
- $(filter-out $(CLANG_CONFIG_x86_64_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-CLANG_HOST_GLOBAL_CFLAGS := \
- $(call convert-to-host-clang-flags,$(HOST_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_EXTRA_CFLAGS)
-
-CLANG_HOST_GLOBAL_CONLYFLAGS := \
- $(call convert-to-host-clang-flags,$(HOST_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_EXTRA_CONLYFLAGS)
-
-CLANG_HOST_GLOBAL_CPPFLAGS := \
- $(call convert-to-host-clang-flags,$(HOST_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_EXTRA_CPPFLAGS)
-
-CLANG_HOST_GLOBAL_LDFLAGS := \
- $(call convert-to-host-clang-flags,$(HOST_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_x86_64_HOST_EXTRA_LDFLAGS)
-
HOST_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-x86_64.a
diff --git a/core/clang/HOST_x86_common.mk b/core/clang/HOST_x86_common.mk
deleted file mode 100644
index 690c0f6..0000000
--- a/core/clang/HOST_x86_common.mk
+++ /dev/null
@@ -1,55 +0,0 @@
-# Shared by HOST_x86.mk and HOST_x86_64.mk.
-
-ifeq ($(HOST_OS),darwin)
-CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_ASFLAGS := \
- -integrated-as
-
-CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CFLAGS := \
- -integrated-as
-
-CLANG_CONFIG_x86_DARWIN_HOST_EXTRA_CFLAGS += -fstack-protector-strong
-endif
-
-ifeq ($(HOST_OS),linux)
-CLANG_CONFIG_x86_LINUX_HOST_EXTRA_ASFLAGS := \
- --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
- --sysroot $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
- -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin
-
-CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CFLAGS := \
- --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)
-
-CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CFLAGS += -fstack-protector-strong
-
-ifneq ($(strip $($(clang_2nd_arch_prefix)HOST_IS_64_BIT)),)
-CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CPPFLAGS := \
- --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
- --sysroot $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
- -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8 \
- -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/x86_64-linux \
- -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/backward
-
-CLANG_CONFIG_x86_LINUX_HOST_EXTRA_LDFLAGS := \
- --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
- --sysroot $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
- -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin \
- -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8 \
- -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8 \
- -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/lib64/
-else
-CLANG_CONFIG_x86_LINUX_HOST_EXTRA_CPPFLAGS := \
- --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
- --sysroot $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
- -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8 \
- -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/x86_64-linux/32 \
- -isystem $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/include/c++/4.8/backward
-
-CLANG_CONFIG_x86_LINUX_HOST_EXTRA_LDFLAGS := \
- --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \
- --sysroot $($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \
- -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin \
- -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8/32 \
- -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/lib/gcc/x86_64-linux/4.8/32 \
- -L$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/lib32/
-endif
-endif # Linux
diff --git a/core/clang/TARGET_arm.mk b/core/clang/TARGET_arm.mk
index 5c1bf6f..9c1a836 100644
--- a/core/clang/TARGET_arm.mk
+++ b/core/clang/TARGET_arm.mk
@@ -1,72 +1,8 @@
-
-include $(BUILD_SYSTEM)/clang/arm.mk
-
-CLANG_CONFIG_arm_TARGET_TRIPLE := arm-linux-androideabi
-CLANG_CONFIG_arm_TARGET_TOOLCHAIN_PREFIX := \
- $($(clang_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/$(CLANG_CONFIG_arm_TARGET_TRIPLE)/bin
-
-CLANG_CONFIG_arm_TARGET_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_arm_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_arm_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_arm_TARGET_TOOLCHAIN_PREFIX)
-
-CLANG_CONFIG_arm_TARGET_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_arm_EXTRA_CFLAGS) \
- -target $(CLANG_CONFIG_arm_TARGET_TRIPLE) \
- $(CLANG_CONFIG_arm_TARGET_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_arm_TARGET_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_arm_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_arm_TARGET_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_arm_EXTRA_CPPFLAGS) \
- -target $(CLANG_CONFIG_arm_TARGET_TRIPLE)
-
-CLANG_CONFIG_arm_TARGET_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_arm_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_arm_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_arm_TARGET_TOOLCHAIN_PREFIX)
-
-
-define $(clang_2nd_arch_prefix)convert-to-clang-flags
- $(strip \
- $(call subst-clang-incompatible-arm-flags,\
- $(filter-out $(CLANG_CONFIG_arm_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_arm_TARGET_EXTRA_CFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CONLYFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_arm_TARGET_EXTRA_CONLYFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CPPFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_arm_TARGET_EXTRA_CPPFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_LDFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_arm_TARGET_EXTRA_LDFLAGS)
-
-$(clang_2nd_arch_prefix)RS_TRIPLE := armv7-linux-androideabi
+$(clang_2nd_arch_prefix)RS_TRIPLE := renderscript32-linux-androideabi
$(clang_2nd_arch_prefix)RS_TRIPLE_CFLAGS :=
$(clang_2nd_arch_prefix)RS_COMPAT_TRIPLE := armv7-none-linux-gnueabi
$(clang_2nd_arch_prefix)TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-arm-android.a
# Address sanitizer clang config
-$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-arm-android
$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_LINKER := /system/bin/linker_asan
diff --git a/core/clang/TARGET_arm64.mk b/core/clang/TARGET_arm64.mk
index 15b0172..9a67b6b 100644
--- a/core/clang/TARGET_arm64.mk
+++ b/core/clang/TARGET_arm64.mk
@@ -1,70 +1,8 @@
-
-include $(BUILD_SYSTEM)/clang/arm64.mk
-
-CLANG_CONFIG_arm64_TARGET_TRIPLE := aarch64-linux-android
-CLANG_CONFIG_arm64_TARGET_TOOLCHAIN_PREFIX := \
- $(TARGET_TOOLCHAIN_ROOT)/$(CLANG_CONFIG_arm64_TARGET_TRIPLE)/bin
-
-CLANG_CONFIG_arm64_TARGET_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_arm64_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_arm64_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_arm64_TARGET_TOOLCHAIN_PREFIX)
-
-CLANG_CONFIG_arm64_TARGET_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_arm64_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_arm64_TARGET_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_arm64_TARGET_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_arm64_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_arm64_TARGET_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_arm64_EXTRA_CPPFLAGS) \
-
-CLANG_CONFIG_arm64_TARGET_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_arm64_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_arm64_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_arm64_TARGET_TOOLCHAIN_PREFIX)
-
-
-define convert-to-clang-flags
- $(strip \
- $(call subst-clang-incompatible-arm64-flags,\
- $(filter-out $(CLANG_CONFIG_arm64_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-CLANG_TARGET_GLOBAL_CFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_arm64_TARGET_EXTRA_CFLAGS)
-
-CLANG_TARGET_GLOBAL_CONLYFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_arm64_TARGET_EXTRA_CONLYFLAGS)
-
-CLANG_TARGET_GLOBAL_CPPFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_arm64_TARGET_EXTRA_CPPFLAGS)
-
-CLANG_TARGET_GLOBAL_LDFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_arm64_TARGET_EXTRA_LDFLAGS)
-
-RS_TRIPLE := aarch64-linux-android
+RS_TRIPLE := renderscript64-linux-android
RS_TRIPLE_CFLAGS :=
RS_COMPAT_TRIPLE := aarch64-linux-android
TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-aarch64-android.a
# Address sanitizer clang config
-ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-aarch64-android
ADDRESS_SANITIZER_LINKER := /system/bin/linker_asan64
diff --git a/core/clang/TARGET_mips.mk b/core/clang/TARGET_mips.mk
index 1a0176a..dfd99b2 100644
--- a/core/clang/TARGET_mips.mk
+++ b/core/clang/TARGET_mips.mk
@@ -1,67 +1,8 @@
-
-include $(BUILD_SYSTEM)/clang/mips.mk
-
-CLANG_CONFIG_mips_TARGET_TRIPLE := mipsel-linux-android
-CLANG_CONFIG_mips_TARGET_TOOLCHAIN_PREFIX := \
- $($(clang_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/mips64el-linux-android/bin
-
-CLANG_CONFIG_mips_TARGET_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_mips_EXTRA_ASFLAGS) \
- -fPIC \
- -target $(CLANG_CONFIG_mips_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_mips_TARGET_TOOLCHAIN_PREFIX)
-
-CLANG_CONFIG_mips_TARGET_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_mips_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_mips_TARGET_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_mips_TARGET_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_mips_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_mips_TARGET_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_mips_EXTRA_CPPFLAGS) \
-
-CLANG_CONFIG_mips_TARGET_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_mips_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_mips_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_mips_TARGET_TOOLCHAIN_PREFIX)
-
-
-define $(clang_2nd_arch_prefix)convert-to-clang-flags
- $(strip \
- $(call subst-clang-incompatible-mips-flags,\
- $(filter-out $(CLANG_CONFIG_mips_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_mips_TARGET_EXTRA_CFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CONLYFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_mips_TARGET_EXTRA_CONLYFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CPPFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_mips_TARGET_EXTRA_CPPFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_LDFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_mips_TARGET_EXTRA_LDFLAGS)
-
-$(clang_2nd_arch_prefix)RS_TRIPLE := armv7-linux-androideabi
+$(clang_2nd_arch_prefix)RS_TRIPLE := renderscript32-linux-androideabi
$(clang_2nd_arch_prefix)RS_TRIPLE_CFLAGS :=
RS_COMPAT_TRIPLE := mipsel-linux-android
$(clang_2nd_arch_prefix)TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-mipsel-android.a
+
+# Address sanitizer clang config
+$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_LINKER := /system/bin/linker_asan
diff --git a/core/clang/TARGET_mips64.mk b/core/clang/TARGET_mips64.mk
index 104fb70..a3684cc 100644
--- a/core/clang/TARGET_mips64.mk
+++ b/core/clang/TARGET_mips64.mk
@@ -1,66 +1,8 @@
-
-include $(BUILD_SYSTEM)/clang/mips64.mk
-
-CLANG_CONFIG_mips64_TARGET_TRIPLE := mips64el-linux-android
-CLANG_CONFIG_mips64_TARGET_TOOLCHAIN_PREFIX := \
- $(TARGET_TOOLCHAIN_ROOT)/$(CLANG_CONFIG_mips64_TARGET_TRIPLE)/bin
-
-CLANG_CONFIG_mips64_TARGET_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_mips64_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_mips64_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_mips64_TARGET_TOOLCHAIN_PREFIX)
-
-CLANG_CONFIG_mips64_TARGET_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_mips64_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_mips64_TARGET_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_mips64_TARGET_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_mips64_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_mips64_TARGET_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_mips64_EXTRA_CPPFLAGS) \
-
-CLANG_CONFIG_mips64_TARGET_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_mips64_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_mips64_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_mips64_TARGET_TOOLCHAIN_PREFIX)
-
-
-define convert-to-clang-flags
- $(strip \
- $(call subst-clang-incompatible-mips64-flags,\
- $(filter-out $(CLANG_CONFIG_mips64_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-CLANG_TARGET_GLOBAL_CFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_mips64_TARGET_EXTRA_CFLAGS)
-
-CLANG_TARGET_GLOBAL_CONLYFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_mips64_TARGET_EXTRA_CONLYFLAGS)
-
-CLANG_TARGET_GLOBAL_CPPFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_mips64_TARGET_EXTRA_CPPFLAGS)
-
-CLANG_TARGET_GLOBAL_LDFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_mips64_TARGET_EXTRA_LDFLAGS)
-
-RS_TRIPLE := aarch64-linux-android
+RS_TRIPLE := renderscript64-linux-android
RS_TRIPLE_CFLAGS :=
RS_COMPAT_TRIPLE := mips64el-linux-android
TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-mips64el-android.a
+
+# Address sanitizer clang config
+$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_LINKER := /system/bin/linker_asan64
diff --git a/core/clang/TARGET_x86.mk b/core/clang/TARGET_x86.mk
index 741768b..1b9c78c 100644
--- a/core/clang/TARGET_x86.mk
+++ b/core/clang/TARGET_x86.mk
@@ -1,77 +1,8 @@
-
-include $(BUILD_SYSTEM)/clang/x86.mk
-
-CLANG_CONFIG_x86_TARGET_TRIPLE := i686-linux-android
-# NOTE: There is no i686-linux-android prebuilt, so we must hardcode the
-# x86_64 target instead.
-CLANG_CONFIG_x86_TARGET_TOOLCHAIN_PREFIX := \
- $($(clang_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/x86_64-linux-android/bin
-
-CLANG_CONFIG_x86_TARGET_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_x86_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_x86_TARGET_TOOLCHAIN_PREFIX)
-
-CLANG_CONFIG_x86_TARGET_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_TARGET_EXTRA_ASFLAGS) \
- -mstackrealign
-
-# -mstackrealign is needed to realign stack in native code
-# that could be called from JNI, so that movaps instruction
-# will work on assumed stack aligned local variables.
-
-CLANG_CONFIG_x86_TARGET_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_x86_TARGET_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_CPPFLAGS) \
-
-CLANG_CONFIG_x86_TARGET_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_x86_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_x86_TARGET_TOOLCHAIN_PREFIX)
-
-
-define $(clang_2nd_arch_prefix)convert-to-clang-flags
- $(strip \
- $(call subst-clang-incompatible-x86-flags,\
- $(filter-out $(CLANG_CONFIG_x86_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_x86_TARGET_EXTRA_CFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CONLYFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_x86_TARGET_EXTRA_CONLYFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_CPPFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_x86_TARGET_EXTRA_CPPFLAGS)
-
-$(clang_2nd_arch_prefix)CLANG_TARGET_GLOBAL_LDFLAGS := \
- $(call $(clang_2nd_arch_prefix)convert-to-clang-flags,$($(clang_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_x86_TARGET_EXTRA_LDFLAGS)
-
-$(clang_2nd_arch_prefix)RS_TRIPLE := armv7-linux-androideabi
+$(clang_2nd_arch_prefix)RS_TRIPLE := renderscript32-linux-androideabi
$(clang_2nd_arch_prefix)RS_TRIPLE_CFLAGS := -D__i386__
$(clang_2nd_arch_prefix)RS_COMPAT_TRIPLE := i686-linux-android
$(clang_2nd_arch_prefix)TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-i686-android.a
# Address sanitizer clang config
-$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-i686-android
$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_LINKER := /system/bin/linker_asan
diff --git a/core/clang/TARGET_x86_64.mk b/core/clang/TARGET_x86_64.mk
index e44382d..0d3ee3f 100644
--- a/core/clang/TARGET_x86_64.mk
+++ b/core/clang/TARGET_x86_64.mk
@@ -1,65 +1,4 @@
-
-include $(BUILD_SYSTEM)/clang/x86_64.mk
-
-CLANG_CONFIG_x86_64_TARGET_TRIPLE := x86_64-linux-android
-CLANG_CONFIG_x86_64_TARGET_TOOLCHAIN_PREFIX := \
- $(TARGET_TOOLCHAIN_ROOT)/$(CLANG_CONFIG_x86_64_TARGET_TRIPLE)/bin
-
-CLANG_CONFIG_x86_64_TARGET_EXTRA_ASFLAGS := \
- $(CLANG_CONFIG_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_ASFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_ASFLAGS) \
- -target $(CLANG_CONFIG_x86_64_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_x86_64_TARGET_TOOLCHAIN_PREFIX)
-
-CLANG_CONFIG_x86_64_TARGET_EXTRA_CFLAGS := \
- $(CLANG_CONFIG_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CFLAGS) \
- $(CLANG_CONFIG_x86_64_TARGET_EXTRA_ASFLAGS)
-
-CLANG_CONFIG_x86_64_TARGET_EXTRA_CONLYFLAGS := \
- $(CLANG_CONFIG_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CONLYFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CONLYFLAGS)
-
-CLANG_CONFIG_x86_64_TARGET_EXTRA_CPPFLAGS := \
- $(CLANG_CONFIG_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_CPPFLAGS) \
-
-CLANG_CONFIG_x86_64_TARGET_EXTRA_LDFLAGS := \
- $(CLANG_CONFIG_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_TARGET_EXTRA_LDFLAGS) \
- $(CLANG_CONFIG_x86_64_EXTRA_LDFLAGS) \
- -target $(CLANG_CONFIG_x86_64_TARGET_TRIPLE) \
- -B$(CLANG_CONFIG_x86_64_TARGET_TOOLCHAIN_PREFIX)
-
-
-define convert-to-clang-flags
- $(strip \
- $(call subst-clang-incompatible-x86_64-flags,\
- $(filter-out $(CLANG_CONFIG_x86_64_UNKNOWN_CFLAGS),\
- $(1))))
-endef
-
-CLANG_TARGET_GLOBAL_CFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CFLAGS)) \
- $(CLANG_CONFIG_x86_64_TARGET_EXTRA_CFLAGS)
-
-CLANG_TARGET_GLOBAL_CONLYFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CONLYFLAGS)) \
- $(CLANG_CONFIG_x86_64_TARGET_EXTRA_CONLYFLAGS)
-
-CLANG_TARGET_GLOBAL_CPPFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_CPPFLAGS)) \
- $(CLANG_CONFIG_x86_64_TARGET_EXTRA_CPPFLAGS)
-
-CLANG_TARGET_GLOBAL_LDFLAGS := \
- $(call convert-to-clang-flags,$(TARGET_GLOBAL_LDFLAGS)) \
- $(CLANG_CONFIG_x86_64_TARGET_EXTRA_LDFLAGS)
-
-RS_TRIPLE := aarch64-linux-android
+RS_TRIPLE := renderscript64-linux-android
RS_TRIPLE_CFLAGS := -D__x86_64__
RS_COMPAT_TRIPLE := x86_64-linux-android
diff --git a/core/clang/arm.mk b/core/clang/arm.mk
deleted file mode 100644
index 4053bb2..0000000
--- a/core/clang/arm.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Clang flags for arm arch, target or host.
-
-CLANG_CONFIG_arm_EXTRA_ASFLAGS :=
-
-CLANG_CONFIG_arm_EXTRA_CFLAGS :=
-
-ifneq (,$(filter krait,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
- # Android's clang support's krait as a CPU whereas GCC doesn't. Specify
- # -mcpu here rather than the more normal core/combo/arch/arm/armv7-a-neon.mk.
- CLANG_CONFIG_arm_EXTRA_CFLAGS += -mcpu=krait -mfpu=neon-vfpv4
-endif
-
-CLANG_CONFIG_arm_EXTRA_CPPFLAGS :=
-
-CLANG_CONFIG_arm_EXTRA_LDFLAGS :=
-
-# Include common unknown flags
-CLANG_CONFIG_arm_UNKNOWN_CFLAGS := \
- $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
- -mthumb-interwork \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers \
- -fno-align-jumps \
- -fno-builtin-sin \
- -fno-caller-saves \
- -fno-early-inlining \
- -fno-move-loop-invariants \
- -fno-partial-inlining \
- -fno-strict-volatile-bitfields \
- -fno-tree-copy-prop \
- -fno-tree-loop-optimize
-
-define subst-clang-incompatible-arm-flags
- $(subst -march=armv5te,-march=armv5t,\
- $(subst -march=armv5e,-march=armv5,\
- $(1)))
-endef
diff --git a/core/clang/arm64.mk b/core/clang/arm64.mk
deleted file mode 100644
index cad7321..0000000
--- a/core/clang/arm64.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Clang flags for arm64 arch, target or host.
-
-CLANG_CONFIG_arm64_EXTRA_ASFLAGS :=
-
-CLANG_CONFIG_arm64_EXTRA_CFLAGS :=
-
-CLANG_CONFIG_arm64_EXTRA_LDFLAGS :=
-
-# Include common unknown flags
-CLANG_CONFIG_arm64_UNKNOWN_CFLAGS := \
- $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers \
- -fno-strict-volatile-bitfields \
- -fno-align-jumps
-
-# We don't have any arm64 flags to substitute yet.
-define subst-clang-incompatible-arm64-flags
- $(1)
-endef
diff --git a/core/clang/config.mk b/core/clang/config.mk
index 6cc3446..be43a26 100644
--- a/core/clang/config.mk
+++ b/core/clang/config.mk
@@ -1,114 +1,13 @@
## Clang configurations.
-LLVM_PREBUILTS_PATH := $(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/bin
LLVM_RTLIB_PATH := $(LLVM_PREBUILTS_PATH)/../lib64/clang/$(LLVM_RELEASE_VERSION)/lib/linux/
-CLANG := $(LLVM_PREBUILTS_PATH)/clang$(BUILD_EXECUTABLE_SUFFIX)
-CLANG_CXX := $(LLVM_PREBUILTS_PATH)/clang++$(BUILD_EXECUTABLE_SUFFIX)
-LLVM_AS := $(LLVM_PREBUILTS_PATH)/llvm-as$(BUILD_EXECUTABLE_SUFFIX)
-LLVM_LINK := $(LLVM_PREBUILTS_PATH)/llvm-link$(BUILD_EXECUTABLE_SUFFIX)
-
CLANG_TBLGEN := $(BUILD_OUT_EXECUTABLES)/clang-tblgen$(BUILD_EXECUTABLE_SUFFIX)
LLVM_TBLGEN := $(BUILD_OUT_EXECUTABLES)/llvm-tblgen$(BUILD_EXECUTABLE_SUFFIX)
-# RenderScript-specific tools
-# These are tied to the version of LLVM directly in external/, so they might
-# trail the host prebuilts being used for the rest of the build process.
-RS_LLVM_PREBUILTS_VERSION := clang-2690385
-RS_LLVM_PREBUILTS_BASE := prebuilts/clang/host
-RS_LLVM_PREBUILTS_PATH := $(RS_LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(RS_LLVM_PREBUILTS_VERSION)/bin
-RS_CLANG := $(RS_LLVM_PREBUILTS_PATH)/clang$(BUILD_EXECUTABLE_SUFFIX)
-RS_LLVM_AS := $(RS_LLVM_PREBUILTS_PATH)/llvm-as$(BUILD_EXECUTABLE_SUFFIX)
-RS_LLVM_LINK := $(RS_LLVM_PREBUILTS_PATH)/llvm-link$(BUILD_EXECUTABLE_SUFFIX)
-
-# Clang flags for all host or target rules
-CLANG_CONFIG_EXTRA_ASFLAGS :=
-CLANG_CONFIG_EXTRA_CFLAGS :=
-CLANG_CONFIG_EXTRA_CONLYFLAGS := -std=gnu99
-CLANG_CONFIG_EXTRA_CPPFLAGS :=
-CLANG_CONFIG_EXTRA_LDFLAGS :=
-
-CLANG_CONFIG_EXTRA_CFLAGS += \
- -D__compiler_offsetof=__builtin_offsetof
-
-# Help catch common 32/64-bit errors.
-CLANG_CONFIG_EXTRA_CFLAGS += \
- -Werror=int-conversion
-
-# Disable overly aggressive warning for macros defined with a leading underscore
-# This used to happen in AndroidConfig.h, which was included everywhere.
-# TODO: can we remove this now?
-CLANG_CONFIG_EXTRA_CFLAGS += \
- -Wno-reserved-id-macro
-
-# Disable overly aggressive warning for format strings.
-# Bug: 20148343
-CLANG_CONFIG_EXTRA_CFLAGS += \
- -Wno-format-pedantic
-
-# Workaround for ccache with clang.
-# See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html.
-CLANG_CONFIG_EXTRA_CFLAGS += \
- -Wno-unused-command-line-argument
-
-# Disable -Winconsistent-missing-override until we can clean up the existing
-# codebase for it.
-CLANG_CONFIG_EXTRA_CPPFLAGS += \
- -Wno-inconsistent-missing-override
-
-# Force clang to always output color diagnostics. Ninja will strip the ANSI
-# color codes if it is not running in a terminal.
-ifdef BUILDING_WITH_NINJA
-CLANG_CONFIG_EXTRA_CFLAGS += \
- -fcolor-diagnostics
-endif
-
-CLANG_CONFIG_UNKNOWN_CFLAGS := \
- -finline-functions \
- -finline-limit=64 \
- -fno-canonical-system-headers \
- -Wno-clobbered \
- -fno-devirtualize \
- -fno-tree-sra \
- -fprefetch-loop-arrays \
- -funswitch-loops \
- -Werror=unused-but-set-parameter \
- -Werror=unused-but-set-variable \
- -Wmaybe-uninitialized \
- -Wno-error=clobbered \
- -Wno-error=maybe-uninitialized \
- -Wno-error=unused-but-set-parameter \
- -Wno-error=unused-but-set-variable \
- -Wno-free-nonheap-object \
- -Wno-literal-suffix \
- -Wno-maybe-uninitialized \
- -Wno-old-style-declaration \
- -Wno-psabi \
- -Wno-unused-but-set-parameter \
- -Wno-unused-but-set-variable \
- -Wno-unused-local-typedefs \
- -Wunused-but-set-parameter \
- -Wunused-but-set-variable \
- -fdiagnostics-color \
- -fdebug-prefix-map=/proc/self/cwd=
-
-# Clang flags for all host rules
-CLANG_CONFIG_HOST_EXTRA_ASFLAGS :=
-CLANG_CONFIG_HOST_EXTRA_CFLAGS :=
-CLANG_CONFIG_HOST_EXTRA_CPPFLAGS :=
-CLANG_CONFIG_HOST_EXTRA_LDFLAGS :=
-
-# Clang flags for all host cross rules
-CLANG_CONFIG_HOST_CROSS_EXTRA_ASFLAGS :=
-CLANG_CONFIG_HOST_CROSS_EXTRA_CFLAGS :=
-CLANG_CONFIG_HOST_CROSS_EXTRA_CPPFLAGS :=
-CLANG_CONFIG_HOST_CROSS_EXTRA_LDFLAGS :=
-
-# Clang flags for all target rules
-CLANG_CONFIG_TARGET_EXTRA_ASFLAGS :=
-CLANG_CONFIG_TARGET_EXTRA_CFLAGS := -nostdlibinc
-CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS := -nostdlibinc
-CLANG_CONFIG_TARGET_EXTRA_LDFLAGS :=
+define convert-to-clang-flags
+$(strip $(filter-out $(CLANG_CONFIG_UNKNOWN_CFLAGS),$(1)))
+endef
CLANG_DEFAULT_UB_CHECKS := \
bool \
@@ -165,17 +64,27 @@
include $(BUILD_SYSTEM)/clang/TARGET_$(TARGET_2ND_ARCH).mk
endif
-ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS := -fno-omit-frame-pointer
-ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS := -Wl,-u,__asan_preinit
-
-ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES :=
-ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES := libasan
-
# This allows us to use the superset of functionality that compiler-rt
# provides to Clang (for supporting features like -ftrapv).
COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES := libcompiler_rt-extras
-ifeq ($(HOST_PREFER_32_BIT),true)
-# We don't have 32-bit prebuilt libLLVM/libclang, so force to build them from source.
-FORCE_BUILD_LLVM_COMPONENTS := true
-endif
+# A list of projects that are allowed to set LOCAL_CLANG to false.
+# INTERNAL_LOCAL_CLANG_EXCEPTION_PROJECTS is defined later in other config.mk.
+LOCAL_CLANG_EXCEPTION_PROJECTS = \
+ bionic/tests/ \
+ device/huawei/angler/ \
+ device/lge/bullhead/ \
+ external/gentoo/integration/ \
+ hardware/qcom/ \
+ $(INTERNAL_LOCAL_CLANG_EXCEPTION_PROJECTS)
+
+# Find $1 in the exception project list.
+define find_in_local_clang_exception_projects
+$(subst $(space),, \
+ $(foreach project,$(LOCAL_CLANG_EXCEPTION_PROJECTS), \
+ $(if $(filter $(project)%,$(1)),$(project)) \
+ ) \
+)
+endef
+
+include $(BUILD_SYSTEM)/clang/tidy.mk
diff --git a/core/clang/mips.mk b/core/clang/mips.mk
deleted file mode 100644
index 4a8f812..0000000
--- a/core/clang/mips.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# Clang flags for mips arch, target or host.
-
-CLANG_CONFIG_mips_EXTRA_ASFLAGS :=
-CLANG_CONFIG_mips_EXTRA_CFLAGS :=
-CLANG_CONFIG_mips_EXTRA_LDFLAGS :=
-
-# Include common unknown flags
-CLANG_CONFIG_mips_UNKNOWN_CFLAGS := \
- $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
- -fno-strict-volatile-bitfields \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers \
- -msynci \
- -mno-synci \
- -mno-fused-madd
-
-# Temporary workaround for Mips clang++ problem, creates
-# relocated ptrs in read-only pic .gcc_exception_table;
-# permanent fix pending at http://reviews.llvm.org/D9669
-CLANG_CONFIG_mips_UNKNOWN_CFLAGS += -Wl,--warn-shared-textrel
-
-# We don't have any mips flags to substitute yet.
-define subst-clang-incompatible-mips-flags
- $(1)
-endef
diff --git a/core/clang/mips64.mk b/core/clang/mips64.mk
deleted file mode 100644
index 1b72e05..0000000
--- a/core/clang/mips64.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# Clang flags for mips64 arch, target or host.
-
-CLANG_CONFIG_mips64_EXTRA_ASFLAGS :=
-CLANG_CONFIG_mips64_EXTRA_CFLAGS :=
-CLANG_CONFIG_mips64_EXTRA_LDFLAGS :=
-
-# Include common unknown flags
-CLANG_CONFIG_mips64_UNKNOWN_CFLAGS := \
- $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
- -fno-strict-volatile-bitfields \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers \
- -msynci \
- -mno-synci \
- -mno-fused-madd
-
-# Temporary workaround for Mips clang++ problem creating
-# relocated ptrs in read-only pic .gcc_exception_table;
-# permanent fix pending at http://reviews.llvm.org/D9669
-CLANG_CONFIG_mips64_UNKNOWN_CFLAGS += -Wl,--warn-shared-textrel
-
-# We don't have any mips64 flags to substitute yet.
-define subst-clang-incompatible-mips64-flags
- $(1)
-endef
diff --git a/core/clang/tidy.mk b/core/clang/tidy.mk
new file mode 100644
index 0000000..868f7bc
--- /dev/null
+++ b/core/clang/tidy.mk
@@ -0,0 +1,42 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# 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.
+#
+
+# Returns 2nd word of $(1) if $(2) has prefix of the 1st word of $(1).
+define find_default_local_tidy_check2
+$(if $(filter $(word 1,$(1))%,$(2)/),$(word 2,$(1)))
+endef
+
+# Returns 2nd part of $(1) if $(2) has prefix of the 1st part of $(1).
+define find_default_local_tidy_check
+$(call find_default_local_tidy_check2,$(subst :,$(space),$(1)),$(2))
+endef
+
+# Returns the default tidy check list for local project path $(1).
+# Match $(1) with all patterns in DEFAULT_LOCAL_TIDY_CHECKS and use the last
+# most specific pattern.
+define default_global_tidy_checks
+$(lastword \
+ $(DEFAULT_GLOBAL_TIDY_CHECKS) \
+ $(foreach pattern,$(DEFAULT_LOCAL_TIDY_CHECKS), \
+ $(call find_default_local_tidy_check,$(pattern),$(1)) \
+ ) \
+)
+endef
+
+# Default filter contains current directory $1 and DEFAULT_TIDY_HEADER_DIRS.
+define default_tidy_header_filter
+ -header-filter="($(subst $(space),,$1|$(DEFAULT_TIDY_HEADER_DIRS)))"
+endef
diff --git a/core/clang/versions.mk b/core/clang/versions.mk
index 81bd3b8..c5cc690 100644
--- a/core/clang/versions.mk
+++ b/core/clang/versions.mk
@@ -1,5 +1,4 @@
## Clang/LLVM release versions.
-LLVM_RELEASE_VERSION := 3.8
-LLVM_PREBUILTS_VERSION ?= clang-2690385
+LLVM_PREBUILTS_VERSION ?= clang-3859424
LLVM_PREBUILTS_BASE ?= prebuilts/clang/host
diff --git a/core/clang/x86.mk b/core/clang/x86.mk
deleted file mode 100644
index 69c3fb2..0000000
--- a/core/clang/x86.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-# Clang flags for x86 arch, target or host.
-
-CLANG_CONFIG_x86_EXTRA_ASFLAGS := \
- -msse3
-CLANG_CONFIG_x86_EXTRA_CFLAGS :=
-CLANG_CONFIG_x86_EXTRA_LDFLAGS :=
-
-# Include common unknown flags
-CLANG_CONFIG_x86_UNKNOWN_CFLAGS := \
- $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
- -finline-limit=300 \
- -fno-inline-functions-called-once \
- -mfpmath=sse \
- -mbionic
-
-# We don't have any x86 flags to substitute yet.
-define subst-clang-incompatible-x86-flags
- $(1)
-endef
diff --git a/core/clang/x86_64.mk b/core/clang/x86_64.mk
deleted file mode 100644
index cba10d4..0000000
--- a/core/clang/x86_64.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# Clang flags for x86_64 arch, target or host.
-
-CLANG_CONFIG_x86_64_EXTRA_ASFLAGS :=
-CLANG_CONFIG_x86_64_EXTRA_CFLAGS :=
-CLANG_CONFIG_x86_64_EXTRA_LDFLAGS :=
-
-# Include common unknown flags
-CLANG_CONFIG_x86_64_UNKNOWN_CFLAGS := \
- $(CLANG_CONFIG_UNKNOWN_CFLAGS) \
- -finline-limit=300 \
- -fno-inline-functions-called-once \
- -mfpmath=sse \
- -mbionic
-
-# We don't have any x86_64 flags to substitute yet.
-define subst-clang-incompatible-x86_64-flags
- $(1)
-endef
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index e46d934..0e1c88d 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -14,7 +14,7 @@
#
# Don't bother with the cleanspecs if you are running mm/mmm
-ifeq ($(ONE_SHOT_MAKEFILE)$(dont_bother),)
+ifeq ($(ONE_SHOT_MAKEFILE)$(dont_bother)$(NO_ANDROID_CLEANSPEC),)
INTERNAL_CLEAN_STEPS :=
@@ -142,174 +142,7 @@
INTERNAL_CLEAN_STEPS :=
INTERNAL_CLEAN_BUILD_VERSION :=
-endif # if not ONE_SHOT_MAKEFILE dont_bother
-
-# Since products and build variants (unfortunately) share the same
-# PRODUCT_OUT staging directory, things can get out of sync if different
-# build configurations are built in the same tree. The following logic
-# will notice when the configuration has changed and remove the files
-# necessary to keep things consistent.
-
-previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk
-
-# A change in the list of aapt configs warrants an installclean, too.
-aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG))
-
-current_build_config := \
- $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)-{$(aapt_config_list)}
-current_sanitize_target := $(strip $(SANITIZE_TARGET))
-ifeq (,$(current_sanitize_target))
- current_sanitize_target := false
-endif
-aapt_config_list :=
-force_installclean := false
-force_objclean := false
-
-# Read the current state from the file, if present.
-# Will set PREVIOUS_BUILD_CONFIG.
-#
-PREVIOUS_BUILD_CONFIG :=
-PREVIOUS_SANITIZE_TARGET :=
--include $(previous_build_config_file)
-PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG))
-PREVIOUS_SANITIZE_TARGET := $(strip $(PREVIOUS_SANITIZE_TARGET))
-
-ifdef PREVIOUS_BUILD_CONFIG
- ifneq "$(current_build_config)" "$(PREVIOUS_BUILD_CONFIG)"
- $(info *** Build configuration changed: "$(PREVIOUS_BUILD_CONFIG)" -> "$(current_build_config)")
- ifneq ($(DISABLE_AUTO_INSTALLCLEAN),true)
- force_installclean := true
- else
- $(info DISABLE_AUTO_INSTALLCLEAN is set; skipping auto-clean. Your tree may be in an inconsistent state.)
- endif
- endif
-endif # else, this is the first build, so no need to clean.
-
-ifdef PREVIOUS_SANITIZE_TARGET
- ifneq "$(current_sanitize_target)" "$(PREVIOUS_SANITIZE_TARGET)"
- $(info *** SANITIZE_TARGET changed: "$(PREVIOUS_SANITIZE_TARGET)" -> "$(current_sanitize_target)")
- force_objclean := true
- endif
-endif # else, this is the first build, so no need to clean.
-
-# Write the new state to the file.
-#
-ifneq ($(PREVIOUS_BUILD_CONFIG)-$(PREVIOUS_SANITIZE_TARGET),$(current_build_config)-$(current_sanitize_target))
-$(shell \
- mkdir -p $(dir $(previous_build_config_file)) && \
- echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \
- $(previous_build_config_file) && \
- echo "PREVIOUS_SANITIZE_TARGET := $(current_sanitize_target)" >> \
- $(previous_build_config_file) \
- )
-endif
-PREVIOUS_BUILD_CONFIG :=
-PREVIOUS_SANITIZE_TARGET :=
-previous_build_config_file :=
-current_build_config :=
-
-#
-# installclean logic
-#
-
-# The files/dirs to delete during an installclean. This includes the
-# non-common APPS directory, which may contain the wrong resources.
-#
-# Deletes all of the files that change between different build types,
-# like "make user" vs. "make sdk". This lets you work with different
-# build types without having to do a full clean each time. E.g.:
-#
-# $ make -j8 all
-# $ make installclean
-# $ make -j8 user
-# $ make installclean
-# $ make -j8 sdk
-#
-installclean_files := \
- $(HOST_OUT)/obj/NOTICE_FILES \
- $(HOST_OUT)/sdk \
- $(PRODUCT_OUT)/*.img \
- $(PRODUCT_OUT)/*.ini \
- $(PRODUCT_OUT)/*.txt \
- $(PRODUCT_OUT)/*.xlb \
- $(PRODUCT_OUT)/*.zip \
- $(PRODUCT_OUT)/kernel \
- $(PRODUCT_OUT)/data \
- $(PRODUCT_OUT)/skin \
- $(PRODUCT_OUT)/obj/APPS \
- $(PRODUCT_OUT)/obj/NOTICE_FILES \
- $(PRODUCT_OUT)/obj/PACKAGING \
- $(PRODUCT_OUT)/recovery \
- $(PRODUCT_OUT)/root \
- $(PRODUCT_OUT)/system \
- $(PRODUCT_OUT)/system_other \
- $(PRODUCT_OUT)/vendor \
- $(PRODUCT_OUT)/oem \
- $(PRODUCT_OUT)/dex_bootjars \
- $(PRODUCT_OUT)/obj/JAVA_LIBRARIES \
- $(PRODUCT_OUT)/obj/FAKE \
- $(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \
- $(PRODUCT_OUT)/obj/EXECUTABLES/logd_intermediates \
- $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libfs_mgr_intermediates \
- $(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \
- $(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \
- $(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates \
- $(PRODUCT_OUT)/obj/ETC/sepolicy.recovery_intermediates \
- $(PRODUCT_OUT)/obj/ETC/init.environ.rc_intermediates
-
-# The files/dirs to delete during a dataclean, which removes any files
-# in the staging and emulator data partitions.
-dataclean_files := \
- $(PRODUCT_OUT)/data/* \
- $(PRODUCT_OUT)/data-qemu/* \
- $(PRODUCT_OUT)/userdata-qemu.img
-
-# The files/dirs to delete during an objclean, which removes any files
-# in the staging and emulator data partitions.
-objclean_files := \
- $(TARGET_OUT_INTERMEDIATES) \
- $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES)
-
-# make sure *_OUT is set so that we won't result in deleting random parts
-# of the filesystem.
-ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT)))
- $(error both HOST_OUT and PRODUCT_OUT should be set at this point.)
-endif
-
-# Define the rules for commandline invocation.
-.PHONY: dataclean
-dataclean: FILES := $(dataclean_files)
-dataclean:
- $(hide) rm -rf $(FILES)
- @echo "Deleted emulator userdata images."
-
-.PHONY: installclean
-installclean: FILES := $(installclean_files)
-installclean: dataclean
- $(hide) rm -rf $(FILES)
- @echo "Deleted images and staging directories."
-
-.PHONY: objclean
-objclean: FILES := $(objclean_files)
-objclean:
- $(hide) rm -rf $(FILES)
- @echo "Deleted images and staging directories."
-
-ifeq "$(force_installclean)" "true"
- $(info *** Forcing "make installclean"...)
- $(info *** rm -rf $(dataclean_files) $(installclean_files))
- $(shell rm -rf $(dataclean_files) $(installclean_files))
- $(info *** Done with the cleaning, now starting the real build.)
-endif
-force_installclean :=
-
-ifeq "$(force_objclean)" "true"
- $(info *** Forcing cleanup of intermediate files...)
- $(info *** rm -rf $(objclean_files))
- $(shell rm -rf $(objclean_files))
- $(info *** Done with the cleaning, now starting the real build.)
-endif
-force_objclean :=
+endif # if not ONE_SHOT_MAKEFILE dont_bother NO_ANDROID_CLEANSPEC
###########################################################
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index f7567b4..a865597 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -2,315 +2,360 @@
## Clear out values of all variables used by rule templates.
###########################################################
-LOCAL_MODULE:=
-LOCAL_MODULE_PATH:=
-LOCAL_MODULE_RELATIVE_PATH :=
-LOCAL_MODULE_STEM:=
-LOCAL_DONT_CHECK_MODULE:=
-LOCAL_CHECKED_MODULE:=
+# '',true
+LOCAL_32_BIT_ONLY:=
+LOCAL_AAPT_FLAGS:=
+LOCAL_AAPT_INCLUDE_ALL_RESOURCES:=
+LOCAL_ADDITIONAL_CERTIFICATES:=
+LOCAL_ADDITIONAL_DEPENDENCIES:=
+LOCAL_ADDITIONAL_HTML_DIR:=
+LOCAL_ADDITIONAL_JAVA_DIR:=
+LOCAL_AIDL_INCLUDES:=
+LOCAL_ALLOW_UNDEFINED_SYMBOLS:=
+LOCAL_ANNOTATION_PROCESSORS:=
+LOCAL_ANNOTATION_PROCESSOR_CLASSES:=
+LOCAL_APK_LIBRARIES:=
+LOCAL_ARM_MODE:=
+LOCAL_ASFLAGS:=
+LOCAL_ASSET_DIR:=
LOCAL_BUILT_MODULE:=
LOCAL_BUILT_MODULE_STEM:=
-OVERRIDE_BUILT_MODULE_PATH:=
-LOCAL_INSTALLED_MODULE:=
-LOCAL_INSTALLED_MODULE_STEM:=
-LOCAL_PICKUP_FILES:=
-LOCAL_UNINSTALLABLE_MODULE:=
-LOCAL_INTERMEDIATE_TARGETS:=
-LOCAL_UNSTRIPPED_PATH:=
-LOCAL_MODULE_CLASS:=
-LOCAL_MODULE_SUFFIX:=
-LOCAL_PACKAGE_NAME:=
-LOCAL_OVERRIDES_PACKAGES:=
-LOCAL_EXPORT_PACKAGE_RESOURCES:=
-LOCAL_MANIFEST_PACKAGE_NAME:=
-LOCAL_PACKAGE_SPLITS:=
-LOCAL_REQUIRED_MODULES:=
-LOCAL_ACP_UNAVAILABLE:=
-LOCAL_MODULE_TAGS:=
-LOCAL_SRC_FILES:=
-LOCAL_SRC_FILES_EXCLUDE:=
-LOCAL_PREBUILT_OBJ_FILES:=
-LOCAL_STATIC_JAVA_LIBRARIES:=
-LOCAL_STATIC_JAVA_AAR_LIBRARIES:=
-LOCAL_STATIC_LIBRARIES:=
-# Group static libraries with "-Wl,--start-group" and "-Wl,--end-group" when linking.
-LOCAL_GROUP_STATIC_LIBRARIES:=
-LOCAL_WHOLE_STATIC_LIBRARIES:=
-LOCAL_SHARED_LIBRARIES:=
-LOCAL_IS_HOST_MODULE:=
LOCAL_CC:=
-LOCAL_CXX:=
-LOCAL_CPP_EXTENSION:=
-LOCAL_NO_DEFAULT_COMPILER_FLAGS:=
-LOCAL_FDO_SUPPORT:=
-LOCAL_ARM_MODE:=
-LOCAL_YACCFLAGS:=
-LOCAL_ASFLAGS:=
+LOCAL_CERTIFICATE:=
LOCAL_CFLAGS:=
-LOCAL_CPPFLAGS:=
+LOCAL_CHECKED_MODULE:=
+LOCAL_C_INCLUDES:=
+LOCAL_CLANG:=
LOCAL_CLANG_ASFLAGS:=
LOCAL_CLANG_CFLAGS:=
LOCAL_CLANG_CONLYFLAGS:=
LOCAL_CLANG_CPPFLAGS:=
-LOCAL_CONLYFLAGS:=
-LOCAL_RTTI_FLAG:=
-LOCAL_C_INCLUDES:=
-LOCAL_EXPORT_C_INCLUDE_DIRS:=
-LOCAL_LDFLAGS:=
LOCAL_CLANG_LDFLAGS:=
-LOCAL_LDLIBS:=
-LOCAL_AAPT_FLAGS:=
-LOCAL_AAPT_INCLUDE_ALL_RESOURCES:=
-LOCAL_SYSTEM_SHARED_LIBRARIES:=none
-LOCAL_PREBUILT_LIBS:=
-LOCAL_PREBUILT_EXECUTABLES:=
-LOCAL_PREBUILT_JAVA_LIBRARIES:=
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
-LOCAL_PREBUILT_STRIP_COMMENTS:=
-LOCAL_INTERMEDIATE_SOURCES:=
-LOCAL_INTERMEDIATE_SOURCE_DIR:=
-LOCAL_JAVACFLAGS:=
-LOCAL_JAVA_LIBRARIES:=
-LOCAL_JAVA_LAYERS_FILE:=
-LOCAL_NO_STANDARD_LIBRARIES:=
LOCAL_CLASSPATH:=
-LOCAL_JACK_CLASSPATH:=
-LOCAL_DROIDDOC_USE_STANDARD_DOCLET:=
-LOCAL_DROIDDOC_SOURCE_PATH:=
-LOCAL_DROIDDOC_TEMPLATE_DIR:=
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=
+LOCAL_COMPATIBILITY_SUITE:=
+LOCAL_COMPATIBILITY_SUPPORT_FILES:=
+LOCAL_CONLYFLAGS:=
+LOCAL_COPY_HEADERS:=
+LOCAL_COPY_HEADERS_TO:=
+LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES:=
+LOCAL_CPP_EXTENSION:=
+LOCAL_CPPFLAGS:=
+LOCAL_CPP_STD:=
+LOCAL_C_STD:=
+LOCAL_CTS_TEST_PACKAGE:=
+LOCAL_CTS_TEST_RUNNER:=
+LOCAL_CXX:=
+LOCAL_CXX_STL := default
+LOCAL_DATA_BINDING:=
+LOCAL_DEX_PREOPT_APP_IMAGE:=
+LOCAL_DEX_PREOPT_FLAGS:=
+LOCAL_DEX_PREOPT_GENERATE_PROFILE:=
+LOCAL_DEX_PREOPT_IMAGE_LOCATION:=
+LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING:=
+LOCAL_DEX_PREOPT:= # '',true,false,nostripping
+LOCAL_DONT_CHECK_MODULE:=
+# Don't delete the META_INF dir when merging static Java libraries.
+LOCAL_DONT_DELETE_JAR_META_INF:=
+LOCAL_DPI_FILE_STEM:=
+LOCAL_DPI_VARIANTS:=
LOCAL_DROIDDOC_ASSET_DIR:=
LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=
-LOCAL_DROIDDOC_OPTIONS:=
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=
LOCAL_DROIDDOC_HTML_DIR:=
+LOCAL_DROIDDOC_OPTIONS:=
+LOCAL_DROIDDOC_SOURCE_PATH:=
LOCAL_DROIDDOC_STUB_OUT_DIR:=
-LOCAL_ADDITIONAL_HTML_DIR:=
-LOCAL_ASSET_DIR:=
-LOCAL_RESOURCE_DIR:=
+LOCAL_DROIDDOC_TEMPLATE_DIR:=
+LOCAL_DROIDDOC_USE_STANDARD_DOCLET:=
+LOCAL_DX_FLAGS:=
+LOCAL_EMMA_COVERAGE_FILTER:=
+LOCAL_EMMA_INSTRUMENT:=
+LOCAL_ERROR_PRONE_FLAGS:=
+LOCAL_EXPORT_CFLAGS:=
+LOCAL_EXPORT_C_INCLUDE_DEPS:=
+LOCAL_EXPORT_C_INCLUDE_DIRS:=
+LOCAL_EXPORT_HEADER_LIBRARY_HEADERS:=
+LOCAL_EXPORT_PACKAGE_RESOURCES:=
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS:=
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS:=
+LOCAL_EXTRACT_APK:=
+LOCAL_EXTRACT_DPI_APK:=
+LOCAL_FDO_SUPPORT:=
+LOCAL_FINDBUGS_FLAGS:=
+LOCAL_FORCE_STATIC_EXECUTABLE:=
+LOCAL_FULL_LIBS_MANIFEST_FILES:=
+LOCAL_FULL_MANIFEST_FILE:=
+LOCAL_GCNO_FILES:=
+LOCAL_GENERATED_SOURCES:=
+# Group static libraries with "-Wl,--start-group" and "-Wl,--end-group" when linking.
+LOCAL_GROUP_STATIC_LIBRARIES:=
+LOCAL_GTEST:=true
+LOCAL_HAL_STATIC_LIBRARIES:=
+LOCAL_HEADER_LIBRARIES:=
+LOCAL_INIT_RC:=
+LOCAL_INSTALLED_MODULE:=
+LOCAL_INSTALLED_MODULE_STEM:=
+LOCAL_INSTRUMENTATION_FOR:=
+LOCAL_INTERMEDIATE_SOURCE_DIR:=
+LOCAL_INTERMEDIATE_SOURCES:=
+LOCAL_INTERMEDIATE_TARGETS:=
+LOCAL_IS_HOST_MODULE:=
+LOCAL_IS_RUNTIME_RESOURCE_OVERLAY:=
+LOCAL_JACK_CLASSPATH:=
+LOCAL_JACK_COVERAGE_EXCLUDE_FILTER:=
+LOCAL_JACK_COVERAGE_INCLUDE_FILTER:=
+# '' (ie disabled), disabled, full, incremental, javac_frontend
+LOCAL_JACK_ENABLED:=$(DEFAULT_JACK_ENABLED)
+LOCAL_JACK_FLAGS:=
+LOCAL_JACK_PLUGIN:=
+LOCAL_JACK_PLUGIN_PATH:=
+LOCAL_JACK_PROGUARD_FLAGS:=
+LOCAL_JAR_EXCLUDE_FILES:=
+LOCAL_JAR_EXCLUDE_PACKAGES:=
+LOCAL_JARJAR_RULES:=
+LOCAL_JAR_MANIFEST:=
+LOCAL_JAR_PACKAGES:=
+LOCAL_JAR_PROCESSOR:=
+LOCAL_JAR_PROCESSOR_ARGS:=
+LOCAL_JAVACFLAGS:=
+LOCAL_JAVA_LANGUAGE_VERSION:=
+LOCAL_JAVA_LAYERS_FILE:=
+LOCAL_JAVA_LIBRARIES:=
LOCAL_JAVA_RESOURCE_DIRS:=
LOCAL_JAVA_RESOURCE_FILES:=
-LOCAL_GENERATED_SOURCES:=
-LOCAL_COPY_HEADERS_TO:=
-LOCAL_COPY_HEADERS:=
-LOCAL_FORCE_STATIC_EXECUTABLE:=
-LOCAL_ADDITIONAL_DEPENDENCIES:=
-LOCAL_STRIP_MODULE:=
-LOCAL_PACK_MODULE_RELOCATIONS:=
LOCAL_JNI_SHARED_LIBRARIES:=
LOCAL_JNI_SHARED_LIBRARIES_ABI:=
-LOCAL_PREBUILT_JNI_LIBS:=
-LOCAL_JAR_MANIFEST:=
-LOCAL_INSTRUMENTATION_FOR:=
-LOCAL_APK_LIBRARIES:=
-LOCAL_RES_LIBRARIES:=
-LOCAL_MANIFEST_INSTRUMENTATION_FOR:=
-LOCAL_AIDL_INCLUDES:=
-LOCAL_VTS_INCLUDES:=
-LOCAL_JARJAR_RULES:=
-LOCAL_ADDITIONAL_JAVA_DIR:=
-LOCAL_ALLOW_UNDEFINED_SYMBOLS:=
-LOCAL_DX_FLAGS:=
-LOCAL_JACK_ENABLED:=$(DEFAULT_JACK_ENABLED) # '' (ie disabled), disabled, full, incremental
-LOCAL_JACK_FLAGS:=
-LOCAL_JACK_COVERAGE_INCLUDE_FILTER:=
-LOCAL_JACK_COVERAGE_EXCLUDE_FILTER:=
-LOCAL_JILL_FLAGS:=
-LOCAL_CERTIFICATE:=
-LOCAL_SDK_VERSION:=
-LOCAL_MIN_SDK_VERSION:=
-LOCAL_SDK_RES_VERSION:=
-LOCAL_NDK_STL_VARIANT:=
-LOCAL_EMMA_INSTRUMENT:=
-LOCAL_PROGUARD_ENABLED:= # '',full,custom,nosystem,disabled,obfuscation,optimization
-LOCAL_PROGUARD_FLAGS:=
-LOCAL_JACK_PROGUARD_FLAGS:=
-LOCAL_PROGUARD_FLAG_FILES:=
-LOCAL_TEST_MODULE_TO_PROGUARD_WITH:=
-LOCAL_EMMA_COVERAGE_FILTER:=
-LOCAL_WARNINGS_ENABLE:=
-LOCAL_FULL_MANIFEST_FILE:=
+LOCAL_LDFLAGS:=
+LOCAL_LDLIBS:=
+LOCAL_LOGTAGS_FILES:=
LOCAL_MANIFEST_FILE:=
-LOCAL_FULL_LIBS_MANIFEST_FILES:=
-LOCAL_RENDERSCRIPT_INCLUDES:=
-LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE:=
+LOCAL_MANIFEST_INSTRUMENTATION_FOR:=
+LOCAL_MANIFEST_PACKAGE_NAME:=
+LOCAL_MIN_SDK_VERSION:=
+LOCAL_MODULE:=
+LOCAL_MODULE_CLASS:=
+LOCAL_MODULE_HOST_ARCH:=
+LOCAL_MODULE_HOST_ARCH_WARN:=
+LOCAL_MODULE_HOST_CROSS_ARCH:=
+LOCAL_MODULE_HOST_CROSS_ARCH_WARN:=
+LOCAL_MODULE_HOST_OS:=
+LOCAL_MODULE_OWNER:=
+LOCAL_MODULE_PATH:=
+LOCAL_MODULE_RELATIVE_PATH :=
+LOCAL_MODULE_STEM:=
+LOCAL_MODULE_SUFFIX:=
+LOCAL_MODULE_SYMLINKS:=
+LOCAL_MODULE_TAGS:=
+LOCAL_MODULE_TARGET_ARCH:=
+LOCAL_MODULE_TARGET_ARCH_WARN:=
+LOCAL_MODULE_UNSUPPORTED_HOST_ARCH:=
+LOCAL_MODULE_UNSUPPORTED_HOST_ARCH_WARN:=
+LOCAL_MODULE_UNSUPPORTED_HOST_CROSS_ARCH:=
+LOCAL_MODULE_UNSUPPORTED_HOST_CROSS_ARCH_WARN:=
+LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH:=
+LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN:=
+LOCAL_MULTILIB:=
+LOCAL_NDK_STL_VARIANT:=
+LOCAL_NDK_VERSION:=current
+LOCAL_NO_CRT:=
+LOCAL_NO_DEFAULT_COMPILER_FLAGS:=
+LOCAL_NO_FPIE :=
+LOCAL_NO_LIBCOMPILER_RT:=
+LOCAL_NO_LIBGCC:=
+LOCAL_NO_NOTICE_FILE:=
+LOCAL_NO_PIC:=
+LOCAL_NOSANITIZE:=
+LOCAL_NO_STANDARD_LIBRARIES:=
+LOCAL_NO_STATIC_ANALYZER:=
+LOCAL_NOTICE_FILE:=
+LOCAL_ODM_MODULE:=
+LOCAL_OEM_MODULE:=
+LOCAL_OVERRIDES_PACKAGES:=
+LOCAL_PACKAGE_NAME:=
+LOCAL_PACKAGE_SPLITS:=
+LOCAL_PACK_MODULE_RELOCATIONS:=
+LOCAL_PICKUP_FILES:=
+LOCAL_POST_INSTALL_CMD:=
+LOCAL_POST_LINK_CMD:=
+LOCAL_PREBUILT_COVERAGE_ARCHIVE:=
+LOCAL_PREBUILT_EXECUTABLES:=
+LOCAL_PREBUILT_JAVA_LIBRARIES:=
+LOCAL_PREBUILT_JNI_LIBS:=
+LOCAL_PREBUILT_LIBS:=
+LOCAL_PREBUILT_MODULE_FILE:=
+LOCAL_PREBUILT_OBJ_FILES:=
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES:=
+LOCAL_PREBUILT_STRIP_COMMENTS:=
+LOCAL_PRIVILEGED_MODULE:=
+# '',full,custom,nosystem,disabled,obfuscation,optimization
+LOCAL_PROGUARD_ENABLED:=
+LOCAL_PROGUARD_FLAG_FILES:=
+LOCAL_PROGUARD_FLAGS:=
+LOCAL_PROPRIETARY_MODULE:=
+LOCAL_PROTOC_FLAGS:=
+# lite(default),micro,nano,full,nanopb-c,nanopb-c-enable_malloc
+LOCAL_PROTOC_OPTIMIZE_TYPE:=
+LOCAL_PROTO_JAVA_OUTPUT_PARAMS:=
+LOCAL_RECORDED_MODULE_TYPE:=
LOCAL_RENDERSCRIPT_CC:=
LOCAL_RENDERSCRIPT_COMPATIBILITY:=
LOCAL_RENDERSCRIPT_FLAGS:=
+LOCAL_RENDERSCRIPT_INCLUDES:=
+LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE:=
LOCAL_RENDERSCRIPT_TARGET_API:=
-LOCAL_DEX_PREOPT:= # '',true,false,nostripping
-LOCAL_DEX_PREOPT_IMAGE_LOCATION:=
-LOCAL_DEX_PREOPT_FLAGS:=
-LOCAL_PROTOC_OPTIMIZE_TYPE:= # lite(default),micro,nano,full,nanopb-c,nanopb-c-enable_malloc
-LOCAL_PROTOC_FLAGS:=
-LOCAL_PROTO_JAVA_OUTPUT_PARAMS:=
-LOCAL_VTSC_FLAGS:=
-LOCAL_NO_CRT:=
-LOCAL_NO_LIBGCC:=
-LOCAL_PROPRIETARY_MODULE:=
-LOCAL_OEM_MODULE:=
-LOCAL_ODM_MODULE:=
-LOCAL_PRIVILEGED_MODULE:=
-LOCAL_MODULE_OWNER:=
-LOCAL_COMPATIBILITY_SUITE:=
-LOCAL_COMPATIBILITY_SUPPORT_FILES:=
-LOCAL_CTS_TEST_PACKAGE:=
-LOCAL_CTS_TEST_RUNNER:=
-LOCAL_CLANG:=
-LOCAL_JAR_EXCLUDE_FILES:=
-LOCAL_JAR_PACKAGES:=
-LOCAL_JAR_EXCLUDE_PACKAGES:=
-LOCAL_SOURCE_FILES_ALL_GENERATED:= # '',true
-# Don't delete the META_INF dir when merging static Java libraries.
-LOCAL_DONT_DELETE_JAR_META_INF:=
-LOCAL_DONT_DELETE_JAR_DIRS:=
-LOCAL_ADDITIONAL_CERTIFICATES:=
-LOCAL_PREBUILT_MODULE_FILE:=
-LOCAL_POST_LINK_CMD:=
-LOCAL_POST_INSTALL_CMD:=
-LOCAL_HAL_STATIC_LIBRARIES:=
-LOCAL_RMTYPEDEFS:=
-LOCAL_NO_SYNTAX_CHECK:=
-LOCAL_NO_STATIC_ANALYZER:=
-LOCAL_32_BIT_ONLY:= # '',true
-LOCAL_MULTILIB:=
-LOCAL_MODULE_TARGET_ARCH:=
-LOCAL_MODULE_TARGET_ARCH_WARN:=
-LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH:=
-LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN:=
-LOCAL_MODULE_HOST_ARCH:=
-LOCAL_MODULE_HOST_ARCH_WARN:=
-LOCAL_MODULE_UNSUPPORTED_HOST_ARCH:=
-LOCAL_MODULE_UNSUPPORTED_HOST_ARCH_WARN:=
-LOCAL_MODULE_HOST_CROSS_ARCH:=
-LOCAL_MODULE_HOST_CROSS_ARCH_WARN:=
-LOCAL_MODULE_UNSUPPORTED_HOST_CROSS_ARCH:=
-LOCAL_MODULE_UNSUPPORTED_HOST_CROSS_ARCH_WARN:=
-LOCAL_NO_FPIE :=
-LOCAL_CXX_STL := default
-LOCAL_NATIVE_COVERAGE :=
-LOCAL_DPI_VARIANTS:=
-LOCAL_DPI_FILE_STEM:=
-LOCAL_SANITIZE:=
-LOCAL_SANITIZE_RECOVER:=
-LOCAL_DATA_BINDING:=
-LOCAL_DBUS_PROXY_PREFIX:=
-LOCAL_INIT_RC:=
-LOCAL_MODULE_HOST_OS:=
-LOCAL_FINDBUGS_FLAGS:=
-LOCAL_NOTICE_FILE:=
-LOCAL_USE_AAPT2:=$(USE_AAPT2)
-LOCAL_STATIC_ANDROID_LIBRARIES:=
-LOCAL_SHARED_ANDROID_LIBRARIES:=
# Used to replace the installed file of a presigned prebuilt apk in PDK fusion build,
# to avoid installing the presigned apks with classes.dex unstripped.
LOCAL_REPLACE_PREBUILT_APK_INSTALLED:=
-LOCAL_EXTRACT_APK:=
-LOCAL_EXTRACT_DPI_APK:=
+LOCAL_REQUIRED_MODULES:=
+LOCAL_RES_LIBRARIES:=
+LOCAL_RESOURCE_DIR:=
+LOCAL_RMTYPEDEFS:=
+LOCAL_RRO_THEME:=
+LOCAL_RTTI_FLAG:=
+LOCAL_SANITIZE:=
+LOCAL_SANITIZE_DIAG:=
+LOCAL_SANITIZE_RECOVER:=
+LOCAL_SDK_RES_VERSION:=
+LOCAL_SDK_VERSION:=
+LOCAL_SHARED_ANDROID_LIBRARIES:=
+LOCAL_SHARED_LIBRARIES:=
+# '',true
+LOCAL_SOURCE_FILES_ALL_GENERATED:=
+LOCAL_SRC_FILES:=
+LOCAL_SRC_FILES_EXCLUDE:=
+LOCAL_STATIC_ANDROID_LIBRARIES:=
+LOCAL_STATIC_JAVA_AAR_LIBRARIES:=
+LOCAL_STATIC_JAVA_LIBRARIES:=
+LOCAL_STATIC_LIBRARIES:=
+LOCAL_STRIP_MODULE:=
+LOCAL_SYSTEM_SHARED_LIBRARIES:=none
+LOCAL_TEST_DATA:=
+LOCAL_TEST_MODULE_TO_PROGUARD_WITH:=
+LOCAL_TIDY:=
+LOCAL_TIDY_CHECKS:=
+LOCAL_TIDY_FLAGS:=
+LOCAL_UNINSTALLABLE_MODULE:=
+LOCAL_UNSTRIPPED_PATH:=
+LOCAL_USE_AAPT2:=$(USE_AAPT2)
+LOCAL_USE_VNDK:=
+LOCAL_VENDOR_MODULE:=
+LOCAL_VTSC_FLAGS:=
+LOCAL_VTS_INCLUDES:=
+LOCAL_WARNINGS_ENABLE:=
+LOCAL_WHOLE_STATIC_LIBRARIES:=
+LOCAL_YACCFLAGS:=
+OVERRIDE_BUILT_MODULE_PATH:=
# arch specific variables
-LOCAL_SRC_FILES_$(TARGET_ARCH):=
-LOCAL_SRC_FILES_EXCLUDE_$(TARGET_ARCH):=
-LOCAL_CFLAGS_$(TARGET_ARCH):=
-LOCAL_CLANG_CFLAGS_$(TARGET_ARCH):=
-LOCAL_CPPFLAGS_$(TARGET_ARCH):=
-LOCAL_CLANG_CPPFLAGS_$(TARGET_ARCH):=
-LOCAL_C_INCLUDES_$(TARGET_ARCH):=
LOCAL_ASFLAGS_$(TARGET_ARCH):=
+LOCAL_CFLAGS_$(TARGET_ARCH):=
+LOCAL_C_INCLUDES_$(TARGET_ARCH):=
LOCAL_CLANG_ASFLAGS_$(TARGET_ARCH):=
-LOCAL_LDFLAGS_$(TARGET_ARCH):=
+LOCAL_CLANG_CFLAGS_$(TARGET_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(TARGET_ARCH):=
LOCAL_CLANG_LDFLAGS_$(TARGET_ARCH):=
-LOCAL_SHARED_LIBRARIES_$(TARGET_ARCH):=
-LOCAL_STATIC_LIBRARIES_$(TARGET_ARCH):=
-LOCAL_WHOLE_STATIC_LIBRARIES_$(TARGET_ARCH):=
-LOCAL_GENERATED_SOURCES_$(TARGET_ARCH):=
-LOCAL_REQUIRED_MODULES_$(TARGET_ARCH):=
LOCAL_CLANG_$(TARGET_ARCH):=
-LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH):=
-LOCAL_STRIP_MODULE_$(TARGET_ARCH):=
+LOCAL_CPPFLAGS_$(TARGET_ARCH):=
+LOCAL_GENERATED_SOURCES_$(TARGET_ARCH):=
+LOCAL_HEADER_LIBRARIES_$(TARGET_ARCH):=
+LOCAL_LDFLAGS_$(TARGET_ARCH):=
LOCAL_PACK_MODULE_RELOCATIONS_$(TARGET_ARCH):=
+LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH):=
+LOCAL_REQUIRED_MODULES_$(TARGET_ARCH):=
+LOCAL_SHARED_LIBRARIES_$(TARGET_ARCH):=
+LOCAL_SRC_FILES_EXCLUDE_$(TARGET_ARCH):=
+LOCAL_SRC_FILES_$(TARGET_ARCH):=
+LOCAL_STATIC_LIBRARIES_$(TARGET_ARCH):=
+LOCAL_STRIP_MODULE_$(TARGET_ARCH):=
+LOCAL_WHOLE_STATIC_LIBRARIES_$(TARGET_ARCH):=
ifdef TARGET_2ND_ARCH
-LOCAL_SRC_FILES_$(TARGET_2ND_ARCH):=
-LOCAL_SRC_FILES_EXCLUDE_$(TARGET_2ND_ARCH):=
-LOCAL_CFLAGS_$(TARGET_2ND_ARCH):=
-LOCAL_CLANG_CFLAGS_$(TARGET_2ND_ARCH):=
-LOCAL_CPPFLAGS_$(TARGET_2ND_ARCH):=
-LOCAL_CLANG_CPPFLAGS_$(TARGET_2ND_ARCH):=
-LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH):=
LOCAL_ASFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_CFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH):=
LOCAL_CLANG_ASFLAGS_$(TARGET_2ND_ARCH):=
-LOCAL_LDFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_CLANG_CFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(TARGET_2ND_ARCH):=
LOCAL_CLANG_LDFLAGS_$(TARGET_2ND_ARCH):=
-LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH):=
-LOCAL_STATIC_LIBRARIES_$(TARGET_2ND_ARCH):=
-LOCAL_WHOLE_STATIC_LIBRARIES_$(TARGET_2ND_ARCH):=
-LOCAL_GENERATED_SOURCES_$(TARGET_2ND_ARCH):=
-LOCAL_REQUIRED_MODULES_$(TARGET_2ND_ARCH):=
LOCAL_CLANG_$(TARGET_2ND_ARCH):=
-LOCAL_PREBUILT_JNI_LIBS_$(TARGET_2ND_ARCH):=
-LOCAL_STRIP_MODULE_$(TARGET_2ND_ARCH):=
+LOCAL_CPPFLAGS_$(TARGET_2ND_ARCH):=
+LOCAL_GENERATED_SOURCES_$(TARGET_2ND_ARCH):=
+LOCAL_HEADER_LIBRARIES_$(TARGET_2ND_ARCH):=
+LOCAL_LDFLAGS_$(TARGET_2ND_ARCH):=
LOCAL_PACK_MODULE_RELOCATIONS_$(TARGET_2ND_ARCH):=
+LOCAL_PREBUILT_JNI_LIBS_$(TARGET_2ND_ARCH):=
+LOCAL_REQUIRED_MODULES_$(TARGET_2ND_ARCH):=
+LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH):=
+LOCAL_SRC_FILES_EXCLUDE_$(TARGET_2ND_ARCH):=
+LOCAL_SRC_FILES_$(TARGET_2ND_ARCH):=
+LOCAL_STATIC_LIBRARIES_$(TARGET_2ND_ARCH):=
+LOCAL_STRIP_MODULE_$(TARGET_2ND_ARCH):=
+LOCAL_WHOLE_STATIC_LIBRARIES_$(TARGET_2ND_ARCH):=
endif
-LOCAL_SRC_FILES_$(HOST_ARCH):=
-LOCAL_SRC_FILES_EXCLUDE_$(HOST_ARCH):=
-LOCAL_CFLAGS_$(HOST_ARCH):=
-LOCAL_CLANG_CFLAGS_$(HOST_ARCH):=
-LOCAL_CPPFLAGS_$(HOST_ARCH):=
-LOCAL_CLANG_CPPFLAGS_$(HOST_ARCH):=
-LOCAL_C_INCLUDES_$(HOST_ARCH):=
LOCAL_ASFLAGS_$(HOST_ARCH):=
+LOCAL_CFLAGS_$(HOST_ARCH):=
+LOCAL_C_INCLUDES_$(HOST_ARCH):=
LOCAL_CLANG_ASFLAGS_$(HOST_ARCH):=
-LOCAL_LDFLAGS_$(HOST_ARCH):=
+LOCAL_CLANG_CFLAGS_$(HOST_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(HOST_ARCH):=
+LOCAL_CLANG_$(HOST_ARCH):=
LOCAL_CLANG_LDFLAGS_$(HOST_ARCH):=
+LOCAL_CPPFLAGS_$(HOST_ARCH):=
+LOCAL_GENERATED_SOURCES_$(HOST_ARCH):=
+LOCAL_HEADER_LIBRARIES_$(HOST_ARCH):=
+LOCAL_LDFLAGS_$(HOST_ARCH):=
+LOCAL_REQUIRED_MODULES_$(HOST_ARCH):=
LOCAL_SHARED_LIBRARIES_$(HOST_ARCH):=
+LOCAL_SRC_FILES_EXCLUDE_$(HOST_ARCH):=
+LOCAL_SRC_FILES_$(HOST_ARCH):=
LOCAL_STATIC_LIBRARIES_$(HOST_ARCH):=
LOCAL_WHOLE_STATIC_LIBRARIES_$(HOST_ARCH):=
-LOCAL_GENERATED_SOURCES_$(HOST_ARCH):=
-LOCAL_REQUIRED_MODULES_$(HOST_ARCH):=
-LOCAL_CLANG_$(HOST_ARCH):=
ifdef HOST_2ND_ARCH
-LOCAL_SRC_FILES_$(HOST_2ND_ARCH):=
-LOCAL_SRC_FILES_EXCLUDE_$(HOST_2ND_ARCH):=
-LOCAL_CFLAGS_$(HOST_2ND_ARCH):=
-LOCAL_CLANG_CFLAGS_$(HOST_2ND_ARCH):=
-LOCAL_CPPFLAGS_$(HOST_2ND_ARCH):=
-LOCAL_CLANG_CPPFLAGS_$(HOST_2ND_ARCH):=
-LOCAL_C_INCLUDES_$(HOST_2ND_ARCH):=
LOCAL_ASFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_C_INCLUDES_$(HOST_2ND_ARCH):=
LOCAL_CLANG_ASFLAGS_$(HOST_2ND_ARCH):=
-LOCAL_LDFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CLANG_CFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CLANG_CPPFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CLANG_$(HOST_2ND_ARCH):=
LOCAL_CLANG_LDFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_CPPFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_GENERATED_SOURCES_$(HOST_2ND_ARCH):=
+LOCAL_HEADER_LIBRARIES_$(HOST_2ND_ARCH):=
+LOCAL_LDFLAGS_$(HOST_2ND_ARCH):=
+LOCAL_REQUIRED_MODULES_$(HOST_2ND_ARCH):=
LOCAL_SHARED_LIBRARIES_$(HOST_2ND_ARCH):=
+LOCAL_SRC_FILES_EXCLUDE_$(HOST_2ND_ARCH):=
+LOCAL_SRC_FILES_$(HOST_2ND_ARCH):=
LOCAL_STATIC_LIBRARIES_$(HOST_2ND_ARCH):=
LOCAL_WHOLE_STATIC_LIBRARIES_$(HOST_2ND_ARCH):=
-LOCAL_GENERATED_SOURCES_$(HOST_2ND_ARCH):=
-LOCAL_REQUIRED_MODULES_$(HOST_2ND_ARCH):=
-LOCAL_CLANG_$(HOST_2ND_ARCH):=
endif
-LOCAL_SRC_FILES_$(HOST_OS):=
-LOCAL_STATIC_LIBRARIES_$(HOST_OS):=
-LOCAL_SHARED_LIBRARIES_$(HOST_OS):=
+LOCAL_ASFLAGS_$(HOST_OS):=
LOCAL_CFLAGS_$(HOST_OS):=
+LOCAL_C_INCLUDES_$(HOST_OS):=
LOCAL_CPPFLAGS_$(HOST_OS):=
+LOCAL_GENERATED_SOURCES_$(HOST_OS):=
+LOCAL_HEADER_LIBRARIES_$(HOST_OS):=
LOCAL_LDFLAGS_$(HOST_OS):=
LOCAL_LDLIBS_$(HOST_OS):=
-LOCAL_ASFLAGS_$(HOST_OS):=
-LOCAL_C_INCLUDES_$(HOST_OS):=
-LOCAL_GENERATED_SOURCES_$(HOST_OS):=
LOCAL_REQUIRED_MODULES_$(HOST_OS):=
+LOCAL_SHARED_LIBRARIES_$(HOST_OS):=
+LOCAL_SRC_FILES_$(HOST_OS):=
+LOCAL_STATIC_LIBRARIES_$(HOST_OS):=
ifdef HOST_CROSS_OS
-LOCAL_SRC_FILES_$(HOST_CROSS_OS):=
-LOCAL_STATIC_LIBRARIES_$(HOST_CROSS_OS):=
-LOCAL_SHARED_LIBRARIES_$(HOST_CROSS_OS):=
+LOCAL_ASFLAGS_$(HOST_CROSS_OS):=
LOCAL_CFLAGS_$(HOST_CROSS_OS):=
+LOCAL_C_INCLUDES_$(HOST_CROSS_OS):=
LOCAL_CPPFLAGS_$(HOST_CROSS_OS):=
+LOCAL_GENERATED_SOURCES_$(HOST_CROSS_OS):=
+LOCAL_HEADER_LIBRARIES_$(HOST_CROSS_OS):=
LOCAL_LDFLAGS_$(HOST_CROSS_OS):=
LOCAL_LDLIBS_$(HOST_CROSS_OS):=
-LOCAL_ASFLAGS_$(HOST_CROSS_OS):=
-LOCAL_C_INCLUDES_$(HOST_CROSS_OS):=
-LOCAL_GENERATED_SOURCES_$(HOST_CROSS_OS):=
LOCAL_REQUIRED_MODULES_$(HOST_CROSS_OS):=
+LOCAL_SHARED_LIBRARIES_$(HOST_CROSS_OS):=
+LOCAL_SRC_FILES_$(HOST_CROSS_OS):=
+LOCAL_STATIC_LIBRARIES_$(HOST_CROSS_OS):=
endif
LOCAL_SRC_FILES_$(HOST_OS)_$(HOST_ARCH):=
@@ -324,47 +369,59 @@
endif
endif
-LOCAL_SRC_FILES_32:=
-LOCAL_SRC_FILES_64:=
-LOCAL_SRC_FILES_EXCLUDE_32:=
-LOCAL_SRC_FILES_EXCLUDE_64:=
-LOCAL_SHARED_LIBRARIES_32:=
-LOCAL_SHARED_LIBRARIES_64:=
-LOCAL_STATIC_LIBRARIES_32:=
-LOCAL_STATIC_LIBRARIES_64:=
-LOCAL_WHOLE_STATIC_LIBRARIES_32:=
-LOCAL_WHOLE_STATIC_LIBRARIES_64:=
-LOCAL_GENERATED_SOURCES_32:=
-LOCAL_GENERATED_SOURCES_64:=
-LOCAL_CFLAGS_32:=
-LOCAL_CFLAGS_64:=
-LOCAL_CPPFLAGS_32:=
-LOCAL_CPPFLAGS_64:=
-LOCAL_LDFLAGS_32:=
-LOCAL_LDFLAGS_64:=
LOCAL_ASFLAGS_32:=
LOCAL_ASFLAGS_64:=
+LOCAL_CFLAGS_32:=
+LOCAL_CFLAGS_64:=
+LOCAL_C_INCLUDES_32:=
+LOCAL_C_INCLUDES_64:=
+LOCAL_CLANG_32:=
+LOCAL_CLANG_64:=
+LOCAL_CLANG_ASFLAGS_32:=
+LOCAL_CLANG_ASFLAGS_64:=
LOCAL_CLANG_CFLAGS_32:=
LOCAL_CLANG_CFLAGS_64:=
LOCAL_CLANG_CPPFLAGS_32:=
LOCAL_CLANG_CPPFLAGS_64:=
LOCAL_CLANG_LDFLAGS_32:=
LOCAL_CLANG_LDFLAGS_64:=
-LOCAL_CLANG_ASFLAGS_32:=
-LOCAL_CLANG_ASFLAGS_64:=
-LOCAL_C_INCLUDES_32:=
-LOCAL_C_INCLUDES_64:=
+LOCAL_CPPFLAGS_32:=
+LOCAL_CPPFLAGS_64:=
+LOCAL_GENERATED_SOURCES_32:=
+LOCAL_GENERATED_SOURCES_64:=
+LOCAL_HEADER_LIBRARIES_32:=
+LOCAL_HEADER_LIBRARIES_64:=
+LOCAL_INIT_RC_32:=
+LOCAL_INIT_RC_64:=
+LOCAL_LDFLAGS_32:=
+LOCAL_LDFLAGS_64:=
LOCAL_MODULE_PATH_32:=
LOCAL_MODULE_PATH_64:=
LOCAL_MODULE_STEM_32:=
LOCAL_MODULE_STEM_64:=
-LOCAL_CLANG_32:=
-LOCAL_CLANG_64:=
-LOCAL_INIT_RC_32:=
-LOCAL_INIT_RC_64:=
-LOCAL_JAVA_LANGUAGE_VERSION:=
-LOCAL_IS_RUNTIME_RESOURCE_OVERLAY:=
-LOCAL_RRO_THEME:=
+LOCAL_MODULE_SYMLINKS_32:=
+LOCAL_MODULE_SYMLINKS_64:=
+LOCAL_SHARED_LIBRARIES_32:=
+LOCAL_SHARED_LIBRARIES_64:=
+LOCAL_SRC_FILES_32:=
+LOCAL_SRC_FILES_64:=
+LOCAL_SRC_FILES_EXCLUDE_32:=
+LOCAL_SRC_FILES_EXCLUDE_64:=
+LOCAL_STATIC_LIBRARIES_32:=
+LOCAL_STATIC_LIBRARIES_64:=
+LOCAL_WHOLE_STATIC_LIBRARIES_32:=
+LOCAL_WHOLE_STATIC_LIBRARIES_64:=
+
+# Aux specific variables
+LOCAL_AUX_ARCH :=
+LOCAL_AUX_CPU :=
+LOCAL_AUX_OS :=
+LOCAL_AUX_OS_VARIANT :=
+LOCAL_AUX_SUBARCH :=
+LOCAL_AUX_TOOLCHAIN :=
+LOCAL_CUSTOM_BUILD_STEP_INPUT:=
+LOCAL_CUSTOM_BUILD_STEP_OUTPUT:=
+LOCAL_IS_AUX_MODULE :=
# Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
# iterate over thousands of entries every time.
diff --git a/core/combo/HOST_CROSS_windows-x86.mk b/core/combo/HOST_CROSS_windows-x86.mk
index 6180a26..d924901 100644
--- a/core/combo/HOST_CROSS_windows-x86.mk
+++ b/core/combo/HOST_CROSS_windows-x86.mk
@@ -17,49 +17,7 @@
# Settings to use MinGW as a cross-compiler under Linux
# Included by combo/select.make
-$(combo_var_prefix)GLOBAL_CFLAGS += -DUSE_MINGW -DWIN32_LEAN_AND_MEAN
-$(combo_var_prefix)GLOBAL_CFLAGS += -Wno-unused-parameter
-$(combo_var_prefix)GLOBAL_CFLAGS += --sysroot prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32
-$(combo_var_prefix)GLOBAL_CFLAGS += -m32
-$(combo_var_prefix)GLOBAL_LDFLAGS += -m32
-TOOLS_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/bin/x86_64-w64-mingw32-
-$(combo_var_prefix)C_INCLUDES += prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/include
-$(combo_var_prefix)C_INCLUDES += prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/lib/gcc/x86_64-w64-mingw32/4.8.3/include
-$(combo_var_prefix)GLOBAL_LD_DIRS += -Lprebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib32
-
-# Workaround differences in inttypes.h between host and target.
-# See bug 12708004.
-$(combo_var_prefix)GLOBAL_CFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
-# Use C99-compliant printf functions (%zd).
-$(combo_var_prefix)GLOBAL_CFLAGS += -D__USE_MINGW_ANSI_STDIO=1
-# Admit to using >= Vista. Both are needed because of <_mingw.h>.
-$(combo_var_prefix)GLOBAL_CFLAGS += -D_WIN32_WINNT=0x0600 -DWINVER=0x0600
-# Get 64-bit off_t and related functions.
-$(combo_var_prefix)GLOBAL_CFLAGS += -D_FILE_OFFSET_BITS=64
-
-$(combo_var_prefix)CC := $(TOOLS_PREFIX)gcc
-$(combo_var_prefix)CXX := $(TOOLS_PREFIX)g++
-$(combo_var_prefix)AR := $(TOOLS_PREFIX)ar
-$(combo_var_prefix)NM := $(TOOLS_PREFIX)nm
-$(combo_var_prefix)OBJDUMP := $(TOOLS_PREFIX)objdump
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OBJDUMP) -x $(1) | grep "^Name" | cut -f3 -d" " > $(2)
$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)NM) -g -f p $(1) | cut -f1-2 -d" " >> $(2)
endef
-
-$(combo_var_prefix)GLOBAL_LDFLAGS += \
- --enable-stdcall-fixup
-
-ifneq ($(strip $(BUILD_HOST_static)),)
-# Statically-linked binaries are desirable for sandboxed environment
-$(combo_var_prefix)GLOBAL_LDFLAGS += -static
-endif # BUILD_HOST_static
-
-$(combo_var_prefix)SHLIB_SUFFIX := .dll
-$(combo_var_prefix)EXECUTABLE_SUFFIX := .exe
-
-$(combo_var_prefix)IS_64_BIT :=
-
-# The mingw gcc is 4.8, 4.9 is required for color diagnostics
-$(combo_var_prefix)UNKNOWN_CFLAGS := -fdiagnostics-color
diff --git a/core/combo/HOST_CROSS_windows-x86_64.mk b/core/combo/HOST_CROSS_windows-x86_64.mk
index e9b19cf..d924901 100644
--- a/core/combo/HOST_CROSS_windows-x86_64.mk
+++ b/core/combo/HOST_CROSS_windows-x86_64.mk
@@ -17,49 +17,7 @@
# Settings to use MinGW as a cross-compiler under Linux
# Included by combo/select.make
-$(combo_var_prefix)GLOBAL_CFLAGS += -DUSE_MINGW -DWIN32_LEAN_AND_MEAN
-$(combo_var_prefix)GLOBAL_CFLAGS += -Wno-unused-parameter
-$(combo_var_prefix)GLOBAL_CFLAGS += --sysroot prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32
-$(combo_var_prefix)GLOBAL_CFLAGS += -m64
-$(combo_var_prefix)GLOBAL_LDFLAGS += -m64
-TOOLS_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/bin/x86_64-w64-mingw32-
-$(combo_var_prefix)C_INCLUDES += prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/include
-$(combo_var_prefix)C_INCLUDES += prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/lib/gcc/x86_64-w64-mingw32/4.8.3/include
-$(combo_var_prefix)GLOBAL_LD_DIRS += -Lprebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib64
-
-# Workaround differences in inttypes.h between host and target.
-# See bug 12708004.
-$(combo_var_prefix)GLOBAL_CFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
-# Use C99-compliant printf functions (%zd).
-$(combo_var_prefix)GLOBAL_CFLAGS += -D__USE_MINGW_ANSI_STDIO=1
-# Admit to using >= Vista. Both are needed because of <_mingw.h>.
-$(combo_var_prefix)GLOBAL_CFLAGS += -D_WIN32_WINNT=0x0600 -DWINVER=0x0600
-# Get 64-bit off_t and related functions.
-$(combo_var_prefix)GLOBAL_CFLAGS += -D_FILE_OFFSET_BITS=64
-
-$(combo_var_prefix)CC := $(TOOLS_PREFIX)gcc
-$(combo_var_prefix)CXX := $(TOOLS_PREFIX)g++
-$(combo_var_prefix)AR := $(TOOLS_PREFIX)ar
-$(combo_var_prefix)NM := $(TOOLS_PREFIX)nm
-$(combo_var_prefix)OBJDUMP := $(TOOLS_PREFIX)objdump
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OBJDUMP) -x $(1) | grep "^Name" | cut -f3 -d" " > $(2)
$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)NM) -g -f p $(1) | cut -f1-2 -d" " >> $(2)
endef
-
-$(combo_var_prefix)GLOBAL_LDFLAGS += \
- --enable-stdcall-fixup
-
-ifneq ($(strip $(BUILD_HOST_static)),)
-# Statically-linked binaries are desirable for sandboxed environment
-$(combo_var_prefix)GLOBAL_LDFLAGS += -static
-endif # BUILD_HOST_static
-
-$(combo_var_prefix)SHLIB_SUFFIX := .dll
-$(combo_var_prefix)EXECUTABLE_SUFFIX := .exe
-
-$(combo_var_prefix)IS_64_BIT := true
-
-# The mingw gcc is 4.8, 4.9 is required for color diagnostics
-$(combo_var_prefix)UNKNOWN_CFLAGS := -fdiagnostics-color
diff --git a/core/combo/HOST_darwin-x86.mk b/core/combo/HOST_darwin-x86.mk
index fc56e52..9a55cb5 100644
--- a/core/combo/HOST_darwin-x86.mk
+++ b/core/combo/HOST_darwin-x86.mk
@@ -17,45 +17,10 @@
# Configuration for Darwin (Mac OS X) on x86.
# Included by combo/select.mk
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -m32
-$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -m32
-
-ifneq ($(strip $(BUILD_HOST_static)),)
-# Statically-linked binaries are desirable for sandboxed environment
-$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -static
-endif # BUILD_HOST_static
-
-# Workaround differences in inttypes.h between host and target.
-# See bug 12708004.
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
-
-include $(BUILD_COMBOS)/mac_version.mk
-
-$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_ROOT := prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1
-$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_ROOT)/bin/i686-apple-darwin$(gcc_darwin_version)
-$(combo_2nd_arch_prefix)HOST_CC := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)-gcc
-$(combo_2nd_arch_prefix)HOST_CXX := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)-g++
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_macho,$(1),$(2))
endef
-# gcc location for clang; to be updated when clang is updated
-# HOST_TOOLCHAIN_ROOT is a Darwin-specific define
-$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_ROOT)
-
-$(combo_2nd_arch_prefix)HOST_AR := $(AR)
-
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -isysroot $(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version) -DMACOSX_DEPLOYMENT_TARGET=$(mac_sdk_version)
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CPPFLAGS += -isystem $(mac_sdk_path)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
-$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -isysroot $(mac_sdk_root) -Wl,-syslibroot,$(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version)
-
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -fPIC -funwind-tables
-$(combo_2nd_arch_prefix)HOST_NO_UNDEFINED_LDFLAGS := -Wl,-undefined,error
-
-$(combo_2nd_arch_prefix)HOST_SHLIB_SUFFIX := .dylib
-$(combo_2nd_arch_prefix)HOST_JNILIB_SUFFIX := .jnilib
-
$(combo_2nd_arch_prefix)HOST_GLOBAL_ARFLAGS := cqs
############################################################
@@ -66,14 +31,13 @@
define transform-host-o-to-shared-lib-inner
$(hide) $(PRIVATE_CXX) \
-dynamiclib -single_module -read_only_relocs suppress \
- $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_LD_DIRS) \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_HOST_GLOBAL_LDFLAGS) \
) \
$(PRIVATE_ALL_OBJECTS) \
$(addprefix -force_load , $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_SHARED_LIBRARIES) \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
$(PRIVATE_LDLIBS) \
-o $@ \
-install_name @rpath/$(notdir $@) \
@@ -84,18 +48,17 @@
define transform-host-o-to-executable-inner
$(hide) $(PRIVATE_CXX) \
- -Wl,-rpath,@loader_path/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
- -Wl,-rpath,@loader_path/$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
+ $(foreach path,$(PRIVATE_RPATHS), \
+ -Wl,-rpath,@loader_path/$(path)) \
-o $@ \
-Wl,-headerpad_max_install_names \
- $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_LD_DIRS) \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_HOST_GLOBAL_LDFLAGS) \
) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(PRIVATE_ALL_SHARED_LIBRARIES) \
$(PRIVATE_ALL_OBJECTS) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
$(PRIVATE_LDFLAGS) \
$(PRIVATE_LDLIBS)
endef
diff --git a/core/combo/HOST_darwin-x86_64.mk b/core/combo/HOST_darwin-x86_64.mk
index 251455f..6cca167 100644
--- a/core/combo/HOST_darwin-x86_64.mk
+++ b/core/combo/HOST_darwin-x86_64.mk
@@ -17,45 +17,10 @@
# Configuration for Darwin (Mac OS X) on x86_64.
# Included by combo/select.mk
-HOST_GLOBAL_CFLAGS += -m64
-HOST_GLOBAL_LDFLAGS += -m64
-
-ifneq ($(strip $(BUILD_HOST_static)),)
-# Statically-linked binaries are desirable for sandboxed environment
-HOST_GLOBAL_LDFLAGS += -static
-endif # BUILD_HOST_static
-
-# Workaround differences in inttypes.h between host and target.
-# See bug 12708004.
-HOST_GLOBAL_CFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
-
-include $(BUILD_COMBOS)/mac_version.mk
-
-HOST_TOOLCHAIN_ROOT := prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1
-HOST_TOOLCHAIN_PREFIX := $(HOST_TOOLCHAIN_ROOT)/bin/i686-apple-darwin$(gcc_darwin_version)
-HOST_CC := $(HOST_TOOLCHAIN_PREFIX)-gcc
-HOST_CXX := $(HOST_TOOLCHAIN_PREFIX)-g++
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_macho,$(1),$(2))
endef
-# gcc location for clang; to be updated when clang is updated
-# HOST_TOOLCHAIN_ROOT is a Darwin-specific define
-HOST_TOOLCHAIN_FOR_CLANG := $(HOST_TOOLCHAIN_ROOT)
-
-HOST_AR := $(AR)
-
-HOST_GLOBAL_CFLAGS += -isysroot $(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version) -DMACOSX_DEPLOYMENT_TARGET=$(mac_sdk_version)
-HOST_GLOBAL_CPPFLAGS += -isystem $(mac_sdk_path)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
-HOST_GLOBAL_LDFLAGS += -isysroot $(mac_sdk_root) -Wl,-syslibroot,$(mac_sdk_root) -mmacosx-version-min=$(mac_sdk_version)
-
-HOST_GLOBAL_CFLAGS += -fPIC -funwind-tables
-HOST_NO_UNDEFINED_LDFLAGS := -Wl,-undefined,error
-
-HOST_SHLIB_SUFFIX := .dylib
-HOST_JNILIB_SUFFIX := .jnilib
-
HOST_GLOBAL_ARFLAGS := cqs
# We Reuse the following functions with the same name from HOST_darwin-x86.mk:
diff --git a/core/combo/HOST_linux-x86.mk b/core/combo/HOST_linux-x86.mk
index 169e2d2..4e83dc4 100644
--- a/core/combo/HOST_linux-x86.mk
+++ b/core/combo/HOST_linux-x86.mk
@@ -17,46 +17,10 @@
# Configuration for builds hosted on linux-x86.
# Included by combo/select.mk
-ifeq ($(strip $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)),)
-$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/bin/x86_64-linux-
-endif
-$(combo_2nd_arch_prefix)HOST_CC := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)gcc
-$(combo_2nd_arch_prefix)HOST_CXX := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)g++
-$(combo_2nd_arch_prefix)HOST_AR := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)ar
-$(combo_2nd_arch_prefix)HOST_READELF := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)readelf
-$(combo_2nd_arch_prefix)HOST_NM := $($(combo_2nd_arch_prefix)HOST_TOOLCHAIN_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-# gcc location for clang; to be updated when clang is updated
-$(combo_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8
-
-# We expect SSE3 floating point math.
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -msse3 -mfpmath=sse -m32 -Wa,--noexecstack -march=prescott
-$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -m32 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--no-undefined-version
-
-ifneq ($(strip $(BUILD_HOST_static)),)
-# Statically-linked binaries are desirable for sandboxed environment
-$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -static
-endif # BUILD_HOST_static
-
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -fPIC \
- -no-canonical-prefixes \
-
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector
-
-# Workaround differences in inttypes.h between host and target.
-# See bug 12708004.
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
-
-# We build a 32-bit host art, and right now that also means building *all* host libraries
-# both 32- and 64-bit (whether art uses them or not --- 9d59f417767991246848c3e101cb27d2dfea5988).
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1
-
-$(combo_2nd_arch_prefix)HOST_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
############################################################
## Macros after this line are shared by the 64-bit config.
diff --git a/core/combo/HOST_linux-x86_64.mk b/core/combo/HOST_linux-x86_64.mk
index 9766f2b..845733f 100644
--- a/core/combo/HOST_linux-x86_64.mk
+++ b/core/combo/HOST_linux-x86_64.mk
@@ -17,37 +17,6 @@
# Configuration for builds hosted on linux-x86_64.
# Included by combo/select.mk
-ifeq ($(strip $(HOST_TOOLCHAIN_PREFIX)),)
-HOST_TOOLCHAIN_PREFIX := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/bin/x86_64-linux-
-endif
-HOST_CC := $(HOST_TOOLCHAIN_PREFIX)gcc
-HOST_CXX := $(HOST_TOOLCHAIN_PREFIX)g++
-HOST_AR := $(HOST_TOOLCHAIN_PREFIX)ar
-HOST_READELF := $(HOST_TOOLCHAIN_PREFIX)readelf
-HOST_NM := $(HOST_TOOLCHAIN_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-
-# gcc location for clang; to be updated when clang is updated
-HOST_TOOLCHAIN_FOR_CLANG := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8
-
-HOST_GLOBAL_CFLAGS += -m64 -Wa,--noexecstack
-HOST_GLOBAL_LDFLAGS += -m64 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--no-undefined-version
-
-ifneq ($(strip $(BUILD_HOST_static)),)
-# Statically-linked binaries are desirable for sandboxed environment
-HOST_GLOBAL_LDFLAGS += -static
-endif # BUILD_HOST_static
-
-HOST_GLOBAL_CFLAGS += -fPIC \
- -no-canonical-prefixes \
-
-HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector
-
-# Workaround differences in inttypes.h between host and target.
-# See bug 12708004.
-HOST_GLOBAL_CFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
-
-HOST_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 510aae5..2e179f6 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -33,15 +33,6 @@
TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT := armv5te
endif
-# Decouple NDK library selection with platform compiler version
-$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.9
-
-ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.9
-else
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
-endif
-
TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_$(combo_2nd_arch_prefix)ARCH)/$(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT).mk
ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
$(error Unknown ARM architecture version: $(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT))
@@ -50,146 +41,10 @@
include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
include $(BUILD_SYSTEM)/combo/fdo.mk
-# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)),)
-$(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-$($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)
-$(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/arm-linux-androideabi-
-endif
-
-$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc
-$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++
-$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar
-$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy
-$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld
-$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf
-$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip
-$(combo_2nd_arch_prefix)TARGET_NM := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-$(combo_2nd_arch_prefix)TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
-$(combo_2nd_arch_prefix)TARGET_arm_CFLAGS := -O2 \
- -fomit-frame-pointer \
- -fstrict-aliasing \
- -funswitch-loops
-
-# Modules can choose to compile some source as thumb.
-$(combo_2nd_arch_prefix)TARGET_thumb_CFLAGS := -mthumb \
- -Os \
- -fomit-frame-pointer \
- -fno-strict-aliasing
-
-# Set FORCE_ARM_DEBUGGING to "true" in your buildspec.mk
-# or in your environment to force a full arm build, even for
-# files that are normally built as thumb; this can make
-# gdb debugging easier. Don't forget to do a clean build.
-#
-# NOTE: if you try to build a -O0 build with thumb, several
-# of the libraries (libpv, libwebcore, libkjs) need to be built
-# with -mlong-calls. When built at -O0, those libraries are
-# too big for a thumb "BL <label>" to go from one end to the other.
-ifeq ($(FORCE_ARM_DEBUGGING),true)
- $(combo_2nd_arch_prefix)TARGET_arm_CFLAGS += -fno-omit-frame-pointer -fno-strict-aliasing
- $(combo_2nd_arch_prefix)TARGET_thumb_CFLAGS += -marm -fno-omit-frame-pointer
-endif
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += \
- -msoft-float \
- -ffunction-sections \
- -fdata-sections \
- -funwind-tables \
- -fstack-protector-strong \
- -Wa,--noexecstack \
- -Werror=format-security \
- -D_FORTIFY_SOURCE=2 \
- -fno-short-enums \
- -no-canonical-prefixes \
- -fno-canonical-system-headers \
- $(arch_variant_cflags) \
-
-# The "-Wunused-but-set-variable" option often breaks projects that enable
-# "-Wall -Werror" due to a commom idiom "ALOGV(mesg)" where ALOGV is turned
-# into no-op in some builds while mesg is defined earlier. So we explicitly
-# disable "-Wunused-but-set-variable" here.
-ifneq ($(filter 4.6 4.6.% 4.7 4.7.% 4.8 4.9, $($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)),)
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -fno-builtin-sin \
- -fno-strict-volatile-bitfields
-endif
-
-# This is to avoid the dreaded warning compiler message:
-# note: the mangling of 'va_list' has changed in GCC 4.4
-#
-# The fact that the mangling changed does not affect the NDK ABI
-# very fortunately (since none of the exposed APIs used va_list
-# in their exported C++ functions). Also, GCC 4.5 has already
-# removed the warning from the compiler.
-#
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -Wno-psabi
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += \
- -Wl,-z,noexecstack \
- -Wl,-z,relro \
- -Wl,-z,now \
- -Wl,--build-id=md5 \
- -Wl,--warn-shared-textrel \
- -Wl,--fatal-warnings \
- -Wl,--icf=safe \
- -Wl,--hash-style=gnu \
- -Wl,--no-undefined-version \
- $(arch_variant_ldflags)
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -mthumb-interwork
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
-
-# More flags/options can be added here
-$(combo_2nd_arch_prefix)TARGET_RELEASE_CFLAGS := \
- -DNDEBUG \
- -g \
- -Wstrict-aliasing=2 \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers
-
-libc_root := bionic/libc
-libm_root := bionic/libm
-
-
-## on some hosts, the target cross-compiler is not available so do not run this command
-ifneq ($(wildcard $($(combo_2nd_arch_prefix)TARGET_CC)),)
-# We compile with the global cflags to ensure that
-# any flags which affect libgcc are correctly taken
-# into account.
-$(combo_2nd_arch_prefix)TARGET_LIBGCC := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) \
- $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-libgcc-file-name)
-$(combo_2nd_arch_prefix)TARGET_LIBATOMIC := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) \
- $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-file-name=libatomic.a)
-$(combo_2nd_arch_prefix)TARGET_LIBGCOV := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) \
- $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-file-name=libgcov.a)
-endif
-
-KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
-KERNEL_HEADERS_COMMON += $(libc_root)/kernel/common
-KERNEL_HEADERS_ARCH := $(libc_root)/kernel/uapi/asm-$(TARGET_$(combo_2nd_arch_prefix)ARCH)
-KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
-
-$(combo_2nd_arch_prefix)TARGET_C_INCLUDES := \
- $(libc_root)/arch-arm/include \
- $(libc_root)/include \
- $(KERNEL_HEADERS) \
- $(libm_root)/include \
- $(libm_root)/include/arm \
-
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_STATIC_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_DYNAMIC_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-$(combo_2nd_arch_prefix)TARGET_CRTEND_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
-
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-$(combo_2nd_arch_prefix)TARGET_CRTEND_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
-
$(combo_2nd_arch_prefix)TARGET_PACK_MODULE_RELOCATIONS := true
$(combo_2nd_arch_prefix)TARGET_LINKER := /system/bin/linker
diff --git a/core/combo/TARGET_linux-arm64.mk b/core/combo/TARGET_linux-arm64.mk
index 6a1d861..a3f59a7 100644
--- a/core/combo/TARGET_linux-arm64.mk
+++ b/core/combo/TARGET_linux-arm64.mk
@@ -33,15 +33,6 @@
TARGET_ARCH_VARIANT := armv8
endif
-# Decouple NDK library selection with platform compiler version
-TARGET_NDK_GCC_VERSION := 4.9
-
-ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-TARGET_GCC_VERSION := 4.9
-else
-TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
-endif
-
TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
$(error Unknown ARM architecture version: $(TARGET_ARCH_VARIANT))
@@ -50,119 +41,10 @@
include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
include $(BUILD_SYSTEM)/combo/fdo.mk
-# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/aarch64/aarch64-linux-android-$(TARGET_GCC_VERSION)
-TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/aarch64-linux-android-
-endif
-
-TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc
-TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++
-TARGET_AR := $(TARGET_TOOLS_PREFIX)ar
-TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy
-TARGET_LD := $(TARGET_TOOLS_PREFIX)ld
-TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf
-TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip
-TARGET_NM := $(TARGET_TOOLS_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
-TARGET_GLOBAL_CFLAGS += \
- -fno-strict-aliasing \
-
-TARGET_GLOBAL_CFLAGS += \
- -fstack-protector-strong \
- -ffunction-sections \
- -fdata-sections \
- -funwind-tables \
- -Wa,--noexecstack \
- -Werror=format-security \
- -D_FORTIFY_SOURCE=2 \
- -fno-short-enums \
- -no-canonical-prefixes \
- -fno-canonical-system-headers \
- $(arch_variant_cflags) \
-
-# Help catch common 32/64-bit errors.
-TARGET_GLOBAL_CFLAGS += \
- -Werror=pointer-to-int-cast \
- -Werror=int-to-pointer-cast \
- -Werror=implicit-function-declaration \
-
-TARGET_GLOBAL_CFLAGS += -fno-strict-volatile-bitfields
-
-# This is to avoid the dreaded warning compiler message:
-# note: the mangling of 'va_list' has changed in GCC 4.4
-#
-# The fact that the mangling changed does not affect the NDK ABI
-# very fortunately (since none of the exposed APIs used va_list
-# in their exported C++ functions). Also, GCC 4.5 has already
-# removed the warning from the compiler.
-#
-TARGET_GLOBAL_CFLAGS += -Wno-psabi
-
-TARGET_GLOBAL_LDFLAGS += \
- -Wl,-z,noexecstack \
- -Wl,-z,relro \
- -Wl,-z,now \
- -Wl,--build-id=md5 \
- -Wl,--warn-shared-textrel \
- -Wl,--fatal-warnings \
- -Wl,-maarch64linux \
- -Wl,--hash-style=gnu \
- -Wl,--fix-cortex-a53-843419 \
- -fuse-ld=gold \
- -Wl,--icf=safe \
- -Wl,--no-undefined-version \
- $(arch_variant_ldflags)
-
-# Disable transitive dependency library symbol resolving.
-TARGET_GLOBAL_LDFLAGS += -Wl,--allow-shlib-undefined
-
-TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
-
-# More flags/options can be added here
-TARGET_RELEASE_CFLAGS := \
- -DNDEBUG \
- -O2 -g \
- -Wstrict-aliasing=2 \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers
-
-libc_root := bionic/libc
-libm_root := bionic/libm
-
-TARGET_LIBGCC := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
- -print-libgcc-file-name)
-TARGET_LIBATOMIC := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
- -print-file-name=libatomic.a)
-TARGET_LIBGCOV := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
- -print-file-name=libgcov.a)
-
-KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
-KERNEL_HEADERS_COMMON += $(libc_root)/kernel/common
-KERNEL_HEADERS_ARCH := $(libc_root)/kernel/uapi/asm-$(TARGET_ARCH)
-KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
-
-TARGET_C_INCLUDES := \
- $(libc_root)/arch-arm64/include \
- $(libc_root)/include \
- $(KERNEL_HEADERS) \
- $(libm_root)/include \
- $(libm_root)/include/arm64 \
-
-TARGET_CRTBEGIN_STATIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-TARGET_CRTEND_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
-
-TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-TARGET_CRTEND_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
-
TARGET_PACK_MODULE_RELOCATIONS := true
TARGET_LINKER := /system/bin/linker64
diff --git a/core/combo/TARGET_linux-mips.mk b/core/combo/TARGET_linux-mips.mk
index 186d88f..ba76969 100644
--- a/core/combo/TARGET_linux-mips.mk
+++ b/core/combo/TARGET_linux-mips.mk
@@ -33,15 +33,6 @@
TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT := mips32r2-fp
endif
-# Decouple NDK library selection with platform compiler version
-$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.9
-
-ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.9
-else
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
-endif
-
TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_$(combo_2nd_arch_prefix)ARCH)/$(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT).mk
ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
$(error Unknown MIPS architecture variant: $(TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT))
@@ -50,121 +41,10 @@
include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
include $(BUILD_SYSTEM)/combo/fdo.mk
-# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)),)
-$(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mips64el-linux-android-$($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)
-$(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/mips64el-linux-android-
-endif
-
-$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc
-$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++
-$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar
-$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy
-$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld
-$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf
-$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip
-$(combo_2nd_arch_prefix)TARGET_NM := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-$(combo_2nd_arch_prefix)TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
-TARGET_mips_CFLAGS := -O2 \
- -fomit-frame-pointer \
- -fno-strict-aliasing \
- -funswitch-loops
-
-# Set FORCE_MIPS_DEBUGGING to "true" in your buildspec.mk
-# or in your environment to gdb debugging easier.
-# Don't forget to do a clean build.
-ifeq ($(FORCE_MIPS_DEBUGGING),true)
- TARGET_mips_CFLAGS += -fno-omit-frame-pointer
-endif
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += \
- $(TARGET_mips_CFLAGS) \
- -U__unix -U__unix__ -Umips \
- -ffunction-sections \
- -fdata-sections \
- -funwind-tables \
- -fstack-protector-strong \
- -Wa,--noexecstack \
- -Werror=format-security \
- -D_FORTIFY_SOURCE=2 \
- -no-canonical-prefixes \
- -fno-canonical-system-headers \
- $(arch_variant_cflags) \
-
-ifneq ($(ARCH_MIPS_PAGE_SHIFT),)
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -DPAGE_SHIFT=$(ARCH_MIPS_PAGE_SHIFT)
-endif
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += \
- -Wl,-z,noexecstack \
- -Wl,-z,relro \
- -Wl,-z,now \
- -Wl,--build-id=md5 \
- -Wl,--warn-shared-textrel \
- -Wl,--fatal-warnings \
- -Wl,--no-undefined-version \
- $(arch_variant_ldflags)
-
-# Disable transitive dependency library symbol resolving.
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--allow-shlib-undefined
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
-
-# More flags/options can be added here
-$(combo_2nd_arch_prefix)TARGET_RELEASE_CFLAGS := \
- -DNDEBUG \
- -g \
- -Wstrict-aliasing=2 \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers
-
-libc_root := bionic/libc
-libm_root := bionic/libm
-
-
-## on some hosts, the target cross-compiler is not available so do not run this command
-ifneq ($(wildcard $($(combo_2nd_arch_prefix)TARGET_CC)),)
-# We compile with the global cflags to ensure that
-# any flags which affect libgcc are correctly taken
-# into account.
-$(combo_2nd_arch_prefix)TARGET_LIBGCC := \
- $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-file-name=libgcc.a)
-$(combo_2nd_arch_prefix)TARGET_LIBATOMIC := \
- $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-file-name=libatomic.a)
-LIBGCC_EH := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) -print-file-name=libgcc_eh.a)
-ifneq ($(LIBGCC_EH),libgcc_eh.a)
- $(combo_2nd_arch_prefix)TARGET_LIBGCC += $(LIBGCC_EH)
-endif
-$(combo_2nd_arch_prefix)TARGET_LIBGCOV := $(shell $($(combo_2nd_arch_prefix)TARGET_CC) $($(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) \
- --print-file-name=libgcov.a)
-endif
-
-KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
-KERNEL_HEADERS_COMMON += $(libc_root)/kernel/common
-KERNEL_HEADERS_ARCH := $(libc_root)/kernel/uapi/asm-mips # mips covers both mips and mips64.
-KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
-
-$(combo_2nd_arch_prefix)TARGET_C_INCLUDES := \
- $(libc_root)/arch-mips/include \
- $(libc_root)/include \
- $(KERNEL_HEADERS) \
- $(libm_root)/include \
- $(libm_root)/include/mips \
-
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_STATIC_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_DYNAMIC_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-$(combo_2nd_arch_prefix)TARGET_CRTEND_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
-
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-$(combo_2nd_arch_prefix)TARGET_CRTEND_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
-
$(combo_2nd_arch_prefix)TARGET_PACK_MODULE_RELOCATIONS := true
$(combo_2nd_arch_prefix)TARGET_LINKER := /system/bin/linker
diff --git a/core/combo/TARGET_linux-mips64.mk b/core/combo/TARGET_linux-mips64.mk
index 3e1f61a..b498d1f 100644
--- a/core/combo/TARGET_linux-mips64.mk
+++ b/core/combo/TARGET_linux-mips64.mk
@@ -33,15 +33,6 @@
TARGET_ARCH_VARIANT := mips64r6
endif
-# Decouple NDK library selection with platform compiler version
-TARGET_NDK_GCC_VERSION := 4.9
-
-ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-TARGET_GCC_VERSION := 4.9
-else
-TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
-endif
-
TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
$(error Unknown MIPS architecture variant: $(TARGET_ARCH_VARIANT))
@@ -50,130 +41,10 @@
include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
include $(BUILD_SYSTEM)/combo/fdo.mk
-# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/mips/mips64el-linux-android-$(TARGET_GCC_VERSION)
-TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/mips64el-linux-android-
-endif
-
-TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc
-TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++
-TARGET_AR := $(TARGET_TOOLS_PREFIX)ar
-TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy
-TARGET_LD := $(TARGET_TOOLS_PREFIX)ld
-TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf
-TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip
-TARGET_NM := $(TARGET_TOOLS_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
-TARGET_mips_CFLAGS := -O2 \
- -fomit-frame-pointer \
- -fno-strict-aliasing \
- -funswitch-loops
-
-# Set FORCE_MIPS_DEBUGGING to "true" in your buildspec.mk
-# or in your environment to gdb debugging easier.
-# Don't forget to do a clean build.
-ifeq ($(FORCE_MIPS_DEBUGGING),true)
- TARGET_mips_CFLAGS += -fno-omit-frame-pointer
-endif
-
-TARGET_GLOBAL_CFLAGS += \
- $(TARGET_mips_CFLAGS) \
- -U__unix -U__unix__ -Umips \
- -ffunction-sections \
- -fdata-sections \
- -funwind-tables \
- -fstack-protector-strong \
- -Wa,--noexecstack \
- -Werror=format-security \
- -D_FORTIFY_SOURCE=2 \
- -no-canonical-prefixes \
- -fno-canonical-system-headers \
- $(arch_variant_cflags) \
-
-# Help catch common 32/64-bit errors.
-TARGET_GLOBAL_CFLAGS += \
- -Werror=pointer-to-int-cast \
- -Werror=int-to-pointer-cast \
- -Werror=implicit-function-declaration \
-
-ifneq ($(ARCH_MIPS_PAGE_SHIFT),)
-TARGET_GLOBAL_CFLAGS += -DPAGE_SHIFT=$(ARCH_MIPS_PAGE_SHIFT)
-endif
-
-TARGET_GLOBAL_LDFLAGS += \
- -Wl,-z,noexecstack \
- -Wl,-z,relro \
- -Wl,-z,now \
- -Wl,--build-id=md5 \
- -Wl,--warn-shared-textrel \
- -Wl,--fatal-warnings \
- -Wl,--no-undefined-version \
- $(arch_variant_ldflags)
-
-# Disable transitive dependency library symbol resolving.
-TARGET_GLOBAL_LDFLAGS += -Wl,--allow-shlib-undefined
-
-TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
-
-# More flags/options can be added here
-TARGET_RELEASE_CFLAGS := \
- -DNDEBUG \
- -g \
- -Wstrict-aliasing=2 \
- -fgcse-after-reload \
- -frerun-cse-after-loop \
- -frename-registers
-
-libc_root := bionic/libc
-libm_root := bionic/libm
-
-
-## on some hosts, the target cross-compiler is not available so do not run this command
-ifneq ($(wildcard $(TARGET_CC)),)
-# We compile with the global cflags to ensure that
-# any flags which affect libgcc are correctly taken
-# into account.
-TARGET_LIBGCC := \
- $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) -print-file-name=libgcc.a)
-TARGET_LIBATOMIC := \
- $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) -print-file-name=libatomic.a)
-LIBGCC_EH := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) -print-file-name=libgcc_eh.a)
-ifneq ($(LIBGCC_EH),libgcc_eh.a)
- TARGET_LIBGCC += $(LIBGCC_EH)
-endif
-TARGET_LIBGCOV := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
- --print-file-name=libgcov.a)
-endif
-
-KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
-KERNEL_HEADERS_COMMON += $(libc_root)/kernel/common
-KERNEL_HEADERS_ARCH := $(libc_root)/kernel/uapi/asm-mips
-# TODO: perhaps use $(libc_root)/kernel/uapi/asm-$(TARGET_ARCH) instead of asm-mips ?
-KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
-
-TARGET_C_INCLUDES := \
- $(libc_root)/arch-mips64/include \
- $(libc_root)/include \
- $(KERNEL_HEADERS) \
- $(libm_root)/include \
- $(libm_root)/include/mips \
-
-# TODO: perhaps use $(libm_root)/include/mips64 instead of mips ?
-
-TARGET_CRTBEGIN_STATIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-TARGET_CRTEND_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
-
-TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-TARGET_CRTEND_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
-
TARGET_PACK_MODULE_RELOCATIONS := true
TARGET_LINKER := /system/bin/linker64
diff --git a/core/combo/TARGET_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
index 558ec3b..2c4614b 100644
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -22,15 +22,6 @@
TARGET_$(combo_2nd_arch_prefix)ARCH_VARIANT := x86
endif
-# Decouple NDK library selection with platform compiler version
-$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.9
-
-ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.9
-else
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
-endif
-
# Include the arch-variant-specific configuration file.
# Its role is to define various ARCH_X86_HAVE_XXX feature macros,
# plus initial values for TARGET_GLOBAL_CFLAGS
@@ -43,108 +34,10 @@
include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
include $(BUILD_SYSTEM)/combo/fdo.mk
-# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)),)
-$(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/x86_64-linux-android-$($(combo_2nd_arch_prefix)TARGET_GCC_VERSION)
-$(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/x86_64-linux-android-
-endif
-
-$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc
-$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++
-$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar
-$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy
-$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld
-$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf
-$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip
-$(combo_2nd_arch_prefix)TARGET_NM := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-ifneq ($(wildcard $($(combo_2nd_arch_prefix)TARGET_CC)),)
-$(combo_2nd_arch_prefix)TARGET_LIBGCC := \
- $(shell $($(combo_2nd_arch_prefix)TARGET_CC) -m32 -print-file-name=libgcc.a)
-$(combo_2nd_arch_prefix)TARGET_LIBATOMIC := \
- $(shell $($(combo_2nd_arch_prefix)TARGET_CC) -m32 -print-file-name=libatomic.a)
-$(combo_2nd_arch_prefix)TARGET_LIBGCOV := \
- $(shell $($(combo_2nd_arch_prefix)TARGET_CC) -m32 -print-file-name=libgcov.a)
-endif
-
-$(combo_2nd_arch_prefix)TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
-libc_root := bionic/libc
-libm_root := bionic/libm
-
-KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
-KERNEL_HEADERS_COMMON += $(libc_root)/kernel/common
-KERNEL_HEADERS_ARCH := $(libc_root)/kernel/uapi/asm-x86 # x86 covers both x86 and x86_64.
-KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += \
- -O2 \
- -Wa,--noexecstack \
- -Werror=format-security \
- -D_FORTIFY_SOURCE=2 \
- -Wstrict-aliasing=2 \
- -ffunction-sections \
- -finline-functions \
- -finline-limit=300 \
- -fno-short-enums \
- -fstrict-aliasing \
- -funswitch-loops \
- -funwind-tables \
- -fstack-protector-strong \
- -m32 \
- -no-canonical-prefixes \
- -fno-canonical-system-headers \
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += $(arch_variant_cflags)
-
-ifeq ($(ARCH_X86_HAVE_SSSE3),true) # yes, really SSSE3, not SSE3!
- $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -DUSE_SSSE3 -mssse3
-endif
-ifeq ($(ARCH_X86_HAVE_SSE4),true)
- $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -msse4
-endif
-ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
- $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -msse4.1
-endif
-ifeq ($(ARCH_X86_HAVE_SSE4_2),true)
- $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -msse4.2
-endif
-ifeq ($(ARCH_X86_HAVE_AVX),true)
- $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -mavx
-endif
-ifeq ($(ARCH_X86_HAVE_AES_NI),true)
- $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += -maes
-endif
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -m32
-
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,-z,noexecstack
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,-z,relro -Wl,-z,now
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--build-id=md5
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--warn-shared-textrel
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--fatal-warnings
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--gc-sections
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--hash-style=gnu
-$(combo_2nd_arch_prefix)TARGET_GLOBAL_LDFLAGS += -Wl,--no-undefined-version
-
-$(combo_2nd_arch_prefix)TARGET_C_INCLUDES := \
- $(libc_root)/arch-x86/include \
- $(libc_root)/include \
- $(KERNEL_HEADERS) \
- $(libm_root)/include \
- $(libm_root)/include/i387 \
-
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_STATIC_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_DYNAMIC_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-$(combo_2nd_arch_prefix)TARGET_CRTEND_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
-
-$(combo_2nd_arch_prefix)TARGET_CRTBEGIN_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-$(combo_2nd_arch_prefix)TARGET_CRTEND_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
-
$(combo_2nd_arch_prefix)TARGET_PACK_MODULE_RELOCATIONS := true
$(combo_2nd_arch_prefix)TARGET_LINKER := /system/bin/linker
diff --git a/core/combo/TARGET_linux-x86_64.mk b/core/combo/TARGET_linux-x86_64.mk
index 12166ec..d2172d6 100644
--- a/core/combo/TARGET_linux-x86_64.mk
+++ b/core/combo/TARGET_linux-x86_64.mk
@@ -22,15 +22,6 @@
TARGET_ARCH_VARIANT := x86_64
endif
-# Decouple NDK library selection with platform compiler version
-TARGET_NDK_GCC_VERSION := 4.9
-
-ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-TARGET_GCC_VERSION := 4.9
-else
-TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
-endif
-
# Include the arch-variant-specific configuration file.
# Its role is to define various ARCH_X86_HAVE_XXX feature macros,
# plus initial values for TARGET_GLOBAL_CFLAGS
@@ -43,117 +34,10 @@
include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
include $(BUILD_SYSTEM)/combo/fdo.mk
-# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
-ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/x86_64-linux-android-$(TARGET_GCC_VERSION)
-TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/x86_64-linux-android-
-endif
-
-TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc
-TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++
-TARGET_AR := $(TARGET_TOOLS_PREFIX)ar
-TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy
-TARGET_LD := $(TARGET_TOOLS_PREFIX)ld
-TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf
-TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip
-TARGET_NM := $(TARGET_TOOLS_PREFIX)nm
-
define $(combo_var_prefix)transform-shared-lib-to-toc
$(call _gen_toc_command_for_elf,$(1),$(2))
endef
-ifneq ($(wildcard $(TARGET_CC)),)
-TARGET_LIBGCC := \
- $(shell $(TARGET_CC) -m64 -print-file-name=libgcc.a)
-TARGET_LIBATOMIC := \
- $(shell $(TARGET_CC) -m64 -print-file-name=libatomic.a)
-TARGET_LIBGCOV := \
- $(shell $(TARGET_CC) -m64 -print-file-name=libgcov.a)
-endif
-
-TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
-
-libc_root := bionic/libc
-libm_root := bionic/libm
-
-KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
-KERNEL_HEADERS_COMMON += $(libc_root)/kernel/common
-KERNEL_HEADERS_ARCH := $(libc_root)/kernel/uapi/asm-x86 # x86 covers both x86 and x86_64.
-KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
-
-TARGET_GLOBAL_CFLAGS += \
- -O2 \
- -Wa,--noexecstack \
- -Werror=format-security \
- -D_FORTIFY_SOURCE=2 \
- -Wstrict-aliasing=2 \
- -ffunction-sections \
- -finline-functions \
- -finline-limit=300 \
- -fno-short-enums \
- -fstrict-aliasing \
- -funswitch-loops \
- -funwind-tables \
- -fstack-protector-strong \
- -m64 \
- -no-canonical-prefixes \
- -fno-canonical-system-headers
-
-# Help catch common 32/64-bit errors.
-TARGET_GLOBAL_CFLAGS += \
- -Werror=pointer-to-int-cast \
- -Werror=int-to-pointer-cast \
- -Werror=implicit-function-declaration \
-
-TARGET_GLOBAL_CFLAGS += $(arch_variant_cflags)
-
-ifeq ($(ARCH_X86_HAVE_SSSE3),true) # yes, really SSSE3, not SSE3!
- TARGET_GLOBAL_CFLAGS += -DUSE_SSSE3 -mssse3
-endif
-ifeq ($(ARCH_X86_HAVE_SSE4),true)
- TARGET_GLOBAL_CFLAGS += -msse4
-endif
-ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
- TARGET_GLOBAL_CFLAGS += -msse4.1
-endif
-ifeq ($(ARCH_X86_HAVE_SSE4_2),true)
- TARGET_GLOBAL_CFLAGS += -msse4.2
-endif
-ifeq ($(ARCH_X86_HAVE_POPCNT),true)
- TARGET_GLOBAL_CFLAGS += -mpopcnt
-endif
-ifeq ($(ARCH_X86_HAVE_AVX),true)
- TARGET_GLOBAL_CFLAGS += -mavx
-endif
-ifeq ($(ARCH_X86_HAVE_AES_NI),true)
- TARGET_GLOBAL_CFLAGS += -maes
-endif
-
-TARGET_GLOBAL_LDFLAGS += -m64
-
-TARGET_GLOBAL_LDFLAGS += -Wl,-z,noexecstack
-TARGET_GLOBAL_LDFLAGS += -Wl,-z,relro -Wl,-z,now
-TARGET_GLOBAL_LDFLAGS += -Wl,--build-id=md5
-TARGET_GLOBAL_LDFLAGS += -Wl,--warn-shared-textrel
-TARGET_GLOBAL_LDFLAGS += -Wl,--fatal-warnings
-TARGET_GLOBAL_LDFLAGS += -Wl,--gc-sections
-TARGET_GLOBAL_LDFLAGS += -Wl,--hash-style=gnu
-TARGET_GLOBAL_LDFLAGS += -Wl,--no-undefined-version
-
-TARGET_C_INCLUDES := \
- $(libc_root)/arch-x86_64/include \
- $(libc_root)/include \
- $(KERNEL_HEADERS) \
- $(libm_root)/include \
- $(libm_root)/include/amd64 \
-
-TARGET_CRTBEGIN_STATIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-TARGET_CRTEND_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
-
-TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-TARGET_CRTEND_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
-
TARGET_LINKER := /system/bin/linker64
TARGET_GLOBAL_YASM_FLAGS := -f elf64 -m amd64
diff --git a/core/combo/arch/arm/armv5te.mk b/core/combo/arch/arm/armv5te.mk
index 88e57b7..bd75695 100644
--- a/core/combo/arch/arm/armv5te.mk
+++ b/core/combo/arch/arm/armv5te.mk
@@ -2,14 +2,3 @@
# Generating binaries for the ARMv5TE architecture and higher
#
-# Note: Hard coding the 'tune' value here is probably not ideal,
-# and a better solution should be found in the future.
-#
-arch_variant_cflags := \
- -march=armv5te \
- -mtune=xscale \
- -D__ARM_ARCH_5__ \
- -D__ARM_ARCH_5T__ \
- -D__ARM_ARCH_5E__ \
- -D__ARM_ARCH_5TE__
-
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index 5d5b050..01d2235 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -5,50 +5,3 @@
ARCH_ARM_HAVE_VFP := true
ARCH_ARM_HAVE_VFP_D32 := true
ARCH_ARM_HAVE_NEON := true
-
-local_arch_has_lpae := false
-
-ifneq (,$(filter cortex-a15 krait denver,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
- # TODO: krait is not a cortex-a15, we set the variant to cortex-a15 so that
- # hardware divide operations are generated. This should be removed and a
- # krait CPU variant added to GCC. For clang we specify -mcpu for krait in
- # core/clang/arm.mk.
- arch_variant_cflags := -mcpu=cortex-a15
-
- local_arch_has_lpae := true
- arch_variant_ldflags := \
- -Wl,--no-fix-cortex-a8
-else
-ifeq ($(strip $(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)),cortex-a8)
- arch_variant_cflags := -mcpu=cortex-a8
- arch_variant_ldflags := \
- -Wl,--fix-cortex-a8
-else
-ifneq (,$(filter cortex-a7 cortex-a53 cortex-a53.a57,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
- arch_variant_cflags := -mcpu=cortex-a7
-
- local_arch_has_lpae := true
- arch_variant_ldflags := \
- -Wl,--no-fix-cortex-a8
-else
- arch_variant_cflags := -march=armv7-a
- # Generic ARM might be a Cortex A8 -- better safe than sorry
- arch_variant_ldflags := \
- -Wl,--fix-cortex-a8
-endif
-endif
-endif
-
-ifeq (true,$(local_arch_has_lpae))
- # Fake an ARM compiler flag as these processors support LPAE which GCC/clang
- # don't advertise.
- # TODO This is a hack and we need to add it for each processor that supports LPAE until some
- # better solution comes around. See Bug 27340895
- arch_variant_cflags += -D__ARM_FEATURE_LPAE=1
-endif
-
-local_arch_has_lpae :=
-
-arch_variant_cflags += \
- -mfloat-abi=softfp \
- -mfpu=neon
diff --git a/core/combo/arch/arm/armv7-a.mk b/core/combo/arch/arm/armv7-a.mk
index 4a51977..0c2f04d 100644
--- a/core/combo/arch/arm/armv7-a.mk
+++ b/core/combo/arch/arm/armv7-a.mk
@@ -3,14 +3,3 @@
#
ARCH_ARM_HAVE_ARMV7A := true
ARCH_ARM_HAVE_VFP := true
-
-# Note: Hard coding the 'tune' value here is probably not ideal,
-# and a better solution should be found in the future.
-#
-arch_variant_cflags := \
- -march=armv7-a \
- -mfloat-abi=softfp \
- -mfpu=vfpv3-d16
-
-arch_variant_ldflags := \
- -Wl,--fix-cortex-a8
diff --git a/core/combo/arch/arm64/armv8-a.mk b/core/combo/arch/arm64/armv8-a.mk
index 5e27e5a..e69de29 100644
--- a/core/combo/arch/arm64/armv8-a.mk
+++ b/core/combo/arch/arm64/armv8-a.mk
@@ -1,5 +0,0 @@
-ifneq (,$(filter cortex-a53,$(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)))
- arch_variant_cflags := -mcpu=cortex-a53
-else
- arch_variant_cflags :=
-endif
diff --git a/core/combo/arch/mips/mips32-fp.mk b/core/combo/arch/mips/mips32-fp.mk
index 912ff63..4b09bc1 100644
--- a/core/combo/arch/mips/mips32-fp.mk
+++ b/core/combo/arch/mips/mips32-fp.mk
@@ -3,11 +3,3 @@
ARCH_MIPS_HAS_FPU :=true
ARCH_HAVE_ALIGNED_DOUBLES :=true
-arch_variant_cflags := \
- -mips32 \
- -mfp32 \
- -modd-spreg \
- -mno-synci
-
-arch_variant_ldflags := \
- -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2-fp-xburst.mk b/core/combo/arch/mips/mips32r2-fp-xburst.mk
index 09b3bc2..83fb12e 100644
--- a/core/combo/arch/mips/mips32r2-fp-xburst.mk
+++ b/core/combo/arch/mips/mips32r2-fp-xburst.mk
@@ -4,13 +4,3 @@
ARCH_MIPS_HAS_FPU :=true
ARCH_HAVE_ALIGNED_DOUBLES :=true
-arch_variant_cflags := \
- -mips32r2 \
- -mfp32 \
- -modd-spreg \
- -mno-fused-madd \
- -Wa,-mmxu \
- -mno-synci
-
-arch_variant_ldflags := \
- -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2-fp.mk b/core/combo/arch/mips/mips32r2-fp.mk
index 9acb018..97c14c3 100644
--- a/core/combo/arch/mips/mips32r2-fp.mk
+++ b/core/combo/arch/mips/mips32r2-fp.mk
@@ -3,11 +3,3 @@
ARCH_MIPS_HAS_FPU :=true
ARCH_HAVE_ALIGNED_DOUBLES :=true
-arch_variant_cflags := \
- -mips32r2 \
- -mfp32 \
- -modd-spreg \
- -msynci
-
-arch_variant_ldflags := \
- -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2dsp-fp.mk b/core/combo/arch/mips/mips32r2dsp-fp.mk
index c4b49b6..522b6b9 100644
--- a/core/combo/arch/mips/mips32r2dsp-fp.mk
+++ b/core/combo/arch/mips/mips32r2dsp-fp.mk
@@ -5,12 +5,3 @@
ARCH_MIPS_DSP_REV :=1
ARCH_MIPS_HAS_FPU :=true
ARCH_HAVE_ALIGNED_DOUBLES :=true
-arch_variant_cflags := \
- -mips32r2 \
- -mfp32 \
- -modd-spreg \
- -mdsp \
- -msynci
-
-arch_variant_ldflags := \
- -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2dspr2-fp.mk b/core/combo/arch/mips/mips32r2dspr2-fp.mk
index 8b05ffc..886d378 100644
--- a/core/combo/arch/mips/mips32r2dspr2-fp.mk
+++ b/core/combo/arch/mips/mips32r2dspr2-fp.mk
@@ -5,12 +5,3 @@
ARCH_MIPS_DSP_REV :=2
ARCH_MIPS_HAS_FPU :=true
ARCH_HAVE_ALIGNED_DOUBLES :=true
-arch_variant_cflags := \
- -mips32r2 \
- -mfp32 \
- -modd-spreg \
- -mdspr2 \
- -msynci
-
-arch_variant_ldflags := \
- -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r6.mk b/core/combo/arch/mips/mips32r6.mk
index 315aa60..7bc6cac 100644
--- a/core/combo/arch/mips/mips32r6.mk
+++ b/core/combo/arch/mips/mips32r6.mk
@@ -2,11 +2,3 @@
# Generating binaries for MIPS32R6/hard-float/little-endian
ARCH_MIPS_REV6 := true
-arch_variant_cflags := \
- -mips32r6 \
- -mfp64 \
- -mno-odd-spreg \
- -msynci
-
-arch_variant_ldflags := \
- -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips64/mips64r2.mk b/core/combo/arch/mips64/mips64r2.mk
index c5710d0..54aa387 100644
--- a/core/combo/arch/mips64/mips64r2.mk
+++ b/core/combo/arch/mips64/mips64r2.mk
@@ -4,7 +4,3 @@
ARCH_MIPS_HAS_FPU :=true
ARCH_HAVE_ALIGNED_DOUBLES :=true
-arch_variant_cflags := \
- -mips64r2 \
- -msynci
-
diff --git a/core/combo/arch/mips64/mips64r6.mk b/core/combo/arch/mips64/mips64r6.mk
index 443de20..42d6c9e 100644
--- a/core/combo/arch/mips64/mips64r6.mk
+++ b/core/combo/arch/mips64/mips64r6.mk
@@ -1,7 +1,3 @@
# Configuration for Android on mips64r6.
-ARCH_MIPS_REV6 := true
-arch_variant_cflags := \
- -mips64r6 \
- -msynci
-
+ARCH_MIPS64_REV6 := true
diff --git a/core/combo/arch/x86/atom.mk b/core/combo/arch/x86/atom.mk
index 3800350..d313a9a 100644
--- a/core/combo/arch/x86/atom.mk
+++ b/core/combo/arch/x86/atom.mk
@@ -7,9 +7,3 @@
ARCH_X86_HAVE_SSSE3 := true
ARCH_X86_HAVE_MOVBE := true
ARCH_X86_HAVE_POPCNT := false # popcnt is not supported by current Atom CPUs
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=atom \
- -mfpmath=sse \
-
diff --git a/core/combo/arch/x86/haswell.mk b/core/combo/arch/x86/haswell.mk
index b3922c0..50c27b4 100644
--- a/core/combo/arch/x86/haswell.mk
+++ b/core/combo/arch/x86/haswell.mk
@@ -9,9 +9,3 @@
ARCH_X86_HAVE_AVX := true
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := true
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=core-avx2 \
- -mfpmath=sse \
-
diff --git a/core/combo/arch/x86/ivybridge.mk b/core/combo/arch/x86/ivybridge.mk
index c9fc33b..44035d8 100644
--- a/core/combo/arch/x86/ivybridge.mk
+++ b/core/combo/arch/x86/ivybridge.mk
@@ -9,9 +9,3 @@
ARCH_X86_HAVE_AVX := true
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := false
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=core-avx-i \
- -mfpmath=sse \
-
diff --git a/core/combo/arch/x86/sandybridge.mk b/core/combo/arch/x86/sandybridge.mk
index bca5953..a4c1bd9 100644
--- a/core/combo/arch/x86/sandybridge.mk
+++ b/core/combo/arch/x86/sandybridge.mk
@@ -5,13 +5,7 @@
ARCH_X86_HAVE_SSE4 := true
ARCH_X86_HAVE_SSE4_1 := true
ARCH_X86_HAVE_SSE4_2 := true
-ARCH_X86_HAVE_AES_NI := true
-ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AES_NI := false
+ARCH_X86_HAVE_AVX := false
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := false
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=corei7-avx \
- -mfpmath=sse \
-
diff --git a/core/combo/arch/x86/silvermont.mk b/core/combo/arch/x86/silvermont.mk
index d064b1d..70b718c 100644
--- a/core/combo/arch/x86/silvermont.mk
+++ b/core/combo/arch/x86/silvermont.mk
@@ -11,9 +11,3 @@
ARCH_X86_HAVE_AES_NI := true
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := true
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=slm \
- -mfpmath=sse \
-
diff --git a/core/combo/arch/x86/x86.mk b/core/combo/arch/x86/x86.mk
index f070426..a55cc7a 100644
--- a/core/combo/arch/x86/x86.mk
+++ b/core/combo/arch/x86/x86.mk
@@ -11,9 +11,3 @@
ARCH_X86_HAVE_SSSE3 := false
ARCH_X86_HAVE_MOVBE := false
ARCH_X86_HAVE_POPCNT := false
-
-
-# Some intrinsic functions used by libcxx only exist for prescott or newer CPUs.
-arch_variant_cflags := \
- -march=prescott \
-
diff --git a/core/combo/arch/x86/x86_64.mk b/core/combo/arch/x86/x86_64.mk
new file mode 100644
index 0000000..fc2a087
--- /dev/null
+++ b/core/combo/arch/x86/x86_64.mk
@@ -0,0 +1,12 @@
+# This file is used as the second (32-bit) architecture when building a generic
+# x86_64 64-bit platform image. (full_x86_64-eng / sdk_x86_64-eng)
+#
+# The generic 'x86' variant cannot be used, since it resets some flags used
+# by the 'x86_64' variant.
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_MOVBE := false # Only supported on Atom.
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
diff --git a/core/combo/arch/x86_64/haswell.mk b/core/combo/arch/x86_64/haswell.mk
index 6067eee..f9c6ebd 100644
--- a/core/combo/arch/x86_64/haswell.mk
+++ b/core/combo/arch/x86_64/haswell.mk
@@ -9,7 +9,3 @@
ARCH_X86_HAVE_AVX := true
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := true
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=core-avx2
diff --git a/core/combo/arch/x86_64/ivybridge.mk b/core/combo/arch/x86_64/ivybridge.mk
index 90e23a9..69011d6 100644
--- a/core/combo/arch/x86_64/ivybridge.mk
+++ b/core/combo/arch/x86_64/ivybridge.mk
@@ -9,7 +9,3 @@
ARCH_X86_HAVE_AVX := true
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := false
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=core-avx-i
diff --git a/core/combo/arch/x86_64/sandybridge.mk b/core/combo/arch/x86_64/sandybridge.mk
index 865548c..2092d19 100644
--- a/core/combo/arch/x86_64/sandybridge.mk
+++ b/core/combo/arch/x86_64/sandybridge.mk
@@ -5,11 +5,7 @@
ARCH_X86_HAVE_SSE4 := true
ARCH_X86_HAVE_SSE4_1 := true
ARCH_X86_HAVE_SSE4_2 := true
-ARCH_X86_HAVE_AES_NI := true
-ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AES_NI := false
+ARCH_X86_HAVE_AVX := false
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := false
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=corei7-avx
diff --git a/core/combo/arch/x86_64/silvermont.mk b/core/combo/arch/x86_64/silvermont.mk
index 6c953a3..70b718c 100644
--- a/core/combo/arch/x86_64/silvermont.mk
+++ b/core/combo/arch/x86_64/silvermont.mk
@@ -11,7 +11,3 @@
ARCH_X86_HAVE_AES_NI := true
ARCH_X86_HAVE_POPCNT := true
ARCH_X86_HAVE_MOVBE := true
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=slm \
diff --git a/core/combo/arch/x86_64/x86_64.mk b/core/combo/arch/x86_64/x86_64.mk
index 08dd9cd..26a9d0f 100755
--- a/core/combo/arch/x86_64/x86_64.mk
+++ b/core/combo/arch/x86_64/x86_64.mk
@@ -11,8 +11,3 @@
ARCH_X86_HAVE_SSE4 := true
ARCH_X86_HAVE_SSE4_1 := true
ARCH_X86_HAVE_SSE4_2 := true
-
-
-# CFLAGS for this arch
-arch_variant_cflags := \
- -march=x86-64
diff --git a/core/combo/mac_version.mk b/core/combo/mac_version.mk
deleted file mode 100644
index 51394c6..0000000
--- a/core/combo/mac_version.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# Detect Mac OS X and SDK versions.
-# Output variables:
-# build_mac_version
-# mac_sdk_version
-# mac_sdk_root
-# gcc_darwin_version
-
-ifndef build_mac_version
-
-build_mac_version := $(shell sw_vers -productVersion)
-
-mac_sdk_versions_supported := 10.8 10.9 10.10 10.11
-ifneq ($(strip $(MAC_SDK_VERSION)),)
-mac_sdk_version := $(MAC_SDK_VERSION)
-ifeq ($(filter $(mac_sdk_version),$(mac_sdk_versions_supported)),)
-$(warning ****************************************************************)
-$(warning * MAC_SDK_VERSION $(MAC_SDK_VERSION) isn't one of the supported $(mac_sdk_versions_supported))
-$(warning ****************************************************************)
-$(error Stop.)
-endif
-else
-mac_sdk_versions_installed := $(shell xcodebuild -showsdks | grep macosx | sed -e "s/.*macosx//g")
-mac_sdk_version := $(firstword $(filter $(mac_sdk_versions_installed), $(mac_sdk_versions_supported)))
-ifeq ($(mac_sdk_version),)
-mac_sdk_version := $(firstword $(mac_sdk_versions_supported))
-$(warning none of the installed SDKs ($mac_sdk_versions_installed) match supported versions ($(mac_sdk_versions_supported)), trying $(mac_sdk_version))
-endif
-endif
-
-mac_sdk_path := $(shell xcode-select -print-path)
-# try /Applications/Xcode*.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.?.sdk
-# or /Volume/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.?.sdk
-mac_sdk_root := $(mac_sdk_path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(mac_sdk_version).sdk
-ifeq ($(wildcard $(mac_sdk_root)),)
-# try legacy /Developer/SDKs/MacOSX10.?.sdk
-$(warning no SDK $(mac_sdk_version) at $(mac_sdk_root), trying legacy dir)
-mac_sdk_root := /Developer/SDKs/MacOSX$(mac_sdk_version).sdk
-endif
-ifeq ($(wildcard $(mac_sdk_root)),)
-$(warning *****************************************************)
-$(warning * Can not find SDK $(mac_sdk_version) at $(mac_sdk_root))
-$(warning *****************************************************)
-$(error Stop.)
-endif
-
-ifeq ($(mac_sdk_version),10.6)
- gcc_darwin_version := 10
-else
- gcc_darwin_version := 11
-endif
-
-endif # ifndef build_mac_version
diff --git a/core/combo/select.mk b/core/combo/select.mk
index df12e7e..5e181b9 100644
--- a/core/combo/select.mk
+++ b/core/combo/select.mk
@@ -28,21 +28,8 @@
# Set reasonable defaults for the various variables
-$(combo_var_prefix)CC := $(CC)
-$(combo_var_prefix)CXX := $(CXX)
-$(combo_var_prefix)AR := $(AR)
-$(combo_var_prefix)STRIP := $(STRIP)
-
-$(combo_var_prefix)GLOBAL_CFLAGS := -fno-exceptions -Wno-multichar
-$(combo_var_prefix)RELEASE_CFLAGS := -O2 -g -fno-strict-aliasing
-$(combo_var_prefix)GLOBAL_CPPFLAGS :=
-$(combo_var_prefix)GLOBAL_LDFLAGS :=
$(combo_var_prefix)GLOBAL_ARFLAGS := crsPD
-$(combo_var_prefix)GLOBAL_LD_DIRS :=
-$(combo_var_prefix)EXECUTABLE_SUFFIX :=
-$(combo_var_prefix)SHLIB_SUFFIX := .so
-$(combo_var_prefix)JNILIB_SUFFIX := $($(combo_var_prefix)SHLIB_SUFFIX)
$(combo_var_prefix)STATIC_LIB_SUFFIX := .a
# Now include the combo for this specific target.
diff --git a/core/config.mk b/core/config.mk
index 2847d34..f5e0aa6 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -31,6 +31,37 @@
backslash := \a
backslash := $(patsubst %a,%,$(backslash))
+# this turns off the suffix rules built into make
+.SUFFIXES:
+
+# this turns off the RCS / SCCS implicit rules of GNU Make
+% : RCS/%,v
+% : RCS/%
+% : %,v
+% : s.%
+% : SCCS/s.%
+
+# If a rule fails, delete $@.
+.DELETE_ON_ERROR:
+
+# Check for broken versions of make.
+ifndef KATI
+ifneq (1,$(strip $(shell expr $(MAKE_VERSION) \>= 3.81)))
+$(warning ********************************************************************************)
+$(warning * You are using version $(MAKE_VERSION) of make.)
+$(warning * Android can only be built by versions 3.81 and higher.)
+$(warning * see https://source.android.com/source/download.html)
+$(warning ********************************************************************************)
+$(error stopping)
+endif
+endif
+
+# Used to force goals to build. Only use for conditionally defined goals.
+.PHONY: FORCE
+FORCE:
+
+ORIGINAL_MAKECMDGOALS := $(MAKECMDGOALS)
+
# Tell python not to spam the source tree with .pyc files. This
# only has an effect on python 2.6 and above.
export PYTHONDONTWRITEBYTECODE := 1
@@ -40,25 +71,6 @@
$(error Please remove --color=always from your $$GREP_OPTIONS)
endif
-# Standard source directories.
-SRC_DOCS:= $(TOPDIR)docs
-# TODO: Enforce some kind of layering; only add include paths
-# when a module links against a particular library.
-# TODO: See if we can remove most of these from the global list.
-SRC_HEADERS := \
- $(TOPDIR)system/core/include \
- $(TOPDIR)system/media/audio/include \
- $(TOPDIR)hardware/libhardware/include \
- $(TOPDIR)hardware/libhardware_legacy/include \
- $(TOPDIR)hardware/ril/include \
- $(TOPDIR)libnativehelper/include \
- $(TOPDIR)frameworks/native/include \
- $(TOPDIR)frameworks/native/opengl/include \
- $(TOPDIR)frameworks/av/include \
- $(TOPDIR)frameworks/base/include
-SRC_HOST_HEADERS:=$(TOPDIR)tools/include
-SRC_LIBRARIES:= $(TOPDIR)libs
-SRC_SERVERS:= $(TOPDIR)servers
SRC_TARGET_DIR := $(TOPDIR)build/target
SRC_API_DIR := $(TOPDIR)prebuilts/sdk/api
SRC_SYSTEM_API_DIR := $(TOPDIR)prebuilts/sdk/system-api
@@ -67,6 +79,10 @@
# Some specific paths to tools
SRC_DROIDDOC_DIR := $(TOPDIR)build/tools/droiddoc
+# Set up efficient math functions which are used in make.
+# Here since this file is included by envsetup as well as during build.
+include $(BUILD_SYSTEM)/math.mk
+
# Various mappings to avoid hard-coding paths all over the place
include $(BUILD_SYSTEM)/pathmap.mk
@@ -80,6 +96,9 @@
BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk
BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk
BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
+BUILD_HEADER_LIBRARY:= $(BUILD_SYSTEM)/header_library.mk
+BUILD_AUX_STATIC_LIBRARY:= $(BUILD_SYSTEM)/aux_static_library.mk
+BUILD_AUX_EXECUTABLE:= $(BUILD_SYSTEM)/aux_executable.mk
BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk
BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk
@@ -114,11 +133,7 @@
# Parse out any modifier targets.
# ###############################################################
-# The 'showcommands' goal says to show the full command
-# lines being executed, instead of a short message about
-# the kind of operation being done.
-SHOW_COMMANDS:= $(filter showcommands,$(MAKECMDGOALS))
-hide := $(if $(SHOW_COMMANDS),,@)
+hide := @
################################################################
# Tools needed in product configuration makefiles.
@@ -166,7 +181,7 @@
# Pruned directory options used when using findleaves.py
# See envsetup.mk for a description of SCAN_EXCLUDE_DIRS
-FIND_LEAVES_EXCLUDES := $(addprefix --prune=, $(OUT_DIR) $(SCAN_EXCLUDE_DIRS) .repo .git)
+FIND_LEAVES_EXCLUDES := $(addprefix --prune=, $(SCAN_EXCLUDE_DIRS) .repo .git)
# The build system exposes several variables for where to find the kernel
# headers:
@@ -198,8 +213,8 @@
# etc.
#
# NOTE: These directories MUST contain post-processed headers using the
-# bionic/libc/kernel/clean_header.py tool. Additionally, the original kernel
-# headers must also be checked in, but in a different subdirectory. By
+# bionic/libc/kernel/tools/clean_header.py tool. Additionally, the original
+# kernel headers must also be checked in, but in a different subdirectory. By
# convention, the originals should be checked into original-kernel-headers
# directory of the same parent dir. For example,
# device/samsung/tuna/kernel-headers <----- post-processed
@@ -234,6 +249,9 @@
endif
TARGET_CPU_ABI2 := $(strip $(TARGET_CPU_ABI2))
+BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE))
+BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
+
# Commands to generate .toc file common to ELF .so files.
define _gen_toc_command_for_elf
$(hide) ($($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)READELF) -d $(1) | grep SONAME || echo "No SONAME for $1") > $(2)
@@ -243,7 +261,7 @@
# Commands to generate .toc file from Darwin dynamic library.
define _gen_toc_command_for_macho
$(hide) otool -l $(1) | grep LC_ID_DYLIB -A 5 > $(2)
-$(hide) nm -gP $(1) | cut -f1-2 -d" " | grep -v U$$ >> $(2)
+$(hide) nm -gP $(1) | cut -f1-2 -d" " | (grep -v U$$ >> $(2) || true)
endef
combo_target := HOST_
@@ -284,9 +302,14 @@
include $(BUILD_SYSTEM)/combo/select.mk
endif
+ifndef KATI
include $(BUILD_SYSTEM)/ccache.mk
include $(BUILD_SYSTEM)/goma.mk
+export CC_WRAPPER
+export CXX_WRAPPER
+endif
+
ifdef TARGET_PREFER_32_BIT
TARGET_PREFER_32_BIT_APPS := true
TARGET_PREFER_32_BIT_EXECUTABLES := true
@@ -340,26 +363,35 @@
TARGET_CPU_ABI_LIST_32_BIT := $(subst $(space),$(comma),$(strip $(TARGET_CPU_ABI_LIST_32_BIT)))
TARGET_CPU_ABI_LIST_64_BIT := $(subst $(space),$(comma),$(strip $(TARGET_CPU_ABI_LIST_64_BIT)))
-# Compute TARGET_TOOLCHAIN_ROOT from TARGET_TOOLS_PREFIX
-# if only TARGET_TOOLS_PREFIX is passed to the make command.
-ifndef TARGET_TOOLCHAIN_ROOT
-TARGET_TOOLCHAIN_ROOT := $(patsubst %/, %, $(dir $(TARGET_TOOLS_PREFIX)))
-TARGET_TOOLCHAIN_ROOT := $(patsubst %/, %, $(dir $(TARGET_TOOLCHAIN_ROOT)))
-TARGET_TOOLCHAIN_ROOT := $(wildcard $(TARGET_TOOLCHAIN_ROOT))
+# GCC version selection
+TARGET_GCC_VERSION := 4.9
+ifdef TARGET_2ND_ARCH
+2ND_TARGET_GCC_VERSION := 4.9
endif
-# Normalize WITH_STATIC_ANALYZER and WITH_SYNTAX_CHECK
+# Normalize WITH_STATIC_ANALYZER
ifeq ($(strip $(WITH_STATIC_ANALYZER)),0)
WITH_STATIC_ANALYZER :=
endif
-ifeq ($(strip $(WITH_SYNTAX_CHECK)),0)
- WITH_SYNTAX_CHECK :=
-endif
# define clang/llvm versions and base directory.
include $(BUILD_SYSTEM)/clang/versions.mk
-# Disable WITH_STATIC_ANALYZER and WITH_SYNTAX_CHECK if tool can't be found
+# Unset WITH_TIDY_ONLY if global WITH_TIDY_ONLY is not true nor 1.
+ifeq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
+ WITH_TIDY_ONLY :=
+endif
+
+PATH_TO_CLANG_TIDY := \
+ $(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/bin/clang-tidy
+ifeq ($(wildcard $(PATH_TO_CLANG_TIDY)),)
+ ifneq (,$(filter 1 true,$(WITH_TIDY)))
+ $(warning *** Disable WITH_TIDY because $(PATH_TO_CLANG_TIDY) does not exist)
+ endif
+ PATH_TO_CLANG_TIDY :=
+endif
+
+# Disable WITH_STATIC_ANALYZER if tool can't be found
SYNTAX_TOOLS_PREFIX := \
$(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/tools/scan-build/libexec
ifneq ($(strip $(WITH_STATIC_ANALYZER)),)
@@ -369,14 +401,6 @@
endif
endif
-# WITH_STATIC_ANALYZER trumps WITH_SYNTAX_CHECK
-ifneq ($(strip $(WITH_STATIC_ANALYZER)),)
- ifneq ($(strip $(WITH_SYNTAX_CHECK)),)
- $(warning *** Disable WITH_SYNTAX_CHECK in the presence of static analyzer WITH_STATIC_ANALYZER)
- WITH_SYNTAX_CHECK :=
- endif
-endif
-
# Pick a Java compiler.
include $(BUILD_SYSTEM)/combo/javac.mk
@@ -455,8 +479,9 @@
#
# Tools that are prebuilts for TARGET_BUILD_APPS
#
+prebuilt_sdk_tools := prebuilts/sdk/tools
+prebuilt_sdk_tools_bin := $(prebuilt_sdk_tools)/$(HOST_OS)/bin
-ACP := $(HOST_OUT_EXECUTABLES)/acp
AIDL := $(HOST_OUT_EXECUTABLES)/aidl
AAPT := $(HOST_OUT_EXECUTABLES)/aapt
AAPT2 := $(HOST_OUT_EXECUTABLES)/aapt2
@@ -465,18 +490,43 @@
SIGNAPK_JNI_LIBRARY_PATH := $(HOST_OUT_SHARED_LIBRARIES)
LLVM_RS_CC := $(HOST_OUT_EXECUTABLES)/llvm-rs-cc
BCC_COMPAT := $(HOST_OUT_EXECUTABLES)/bcc_compat
+DEPMOD := $(HOST_OUT_EXECUTABLES)/depmod
+#TODO: use a smaller -Xmx value for most libraries;
+# only core.jar and framework.jar need a heap this big.
+ifndef DX_ALT_JAR
DX := $(HOST_OUT_EXECUTABLES)/dx
+DX_COMMAND := $(DX) -JXms16M -JXmx2048M
+else
+DX := $(DX_ALT_JAR)
+DX_COMMAND := java -Xms16M -Xmx2048M -jar $(DX)
+endif
+
MAINDEXCLASSES := $(HOST_OUT_EXECUTABLES)/mainDexClasses
+SOONG_ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/soong_zip
+ZIP2ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/zip2zip
+FILESLIST := $(SOONG_HOST_OUT_EXECUTABLES)/fileslist
+
+SOONG_JAVAC_WRAPPER := $(SOONG_HOST_OUT_EXECUTABLES)/soong_javac_wrapper
+
+# Always use prebuilts for ckati and makeparallel
+prebuilt_build_tools := prebuilts/build-tools
+ifeq ($(filter address,$(SANITIZE_HOST)),)
+prebuilt_build_tools_bin := $(prebuilt_build_tools)/$(HOST_PREBUILT_TAG)/bin
+else
+prebuilt_build_tools_bin := $(prebuilt_build_tools)/$(HOST_PREBUILT_TAG)/asan/bin
+endif
+ACP := $(prebuilt_build_tools_bin)/acp
+CKATI := $(prebuilt_build_tools_bin)/ckati
+IJAR := $(prebuilt_build_tools_bin)/ijar
+MAKEPARALLEL := $(prebuilt_build_tools_bin)/makeparallel
+ZIPTIME := $(prebuilt_build_tools_bin)/ziptime
+
USE_PREBUILT_SDK_TOOLS_IN_PLACE := true
# Override the definitions above for unbundled and PDK builds
ifneq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)))
-prebuilt_sdk_tools := prebuilts/sdk/tools
-prebuilt_sdk_tools_bin := $(prebuilt_sdk_tools)/$(HOST_OS)/bin
-
-ACP := $(prebuilt_sdk_tools_bin)/acp
AIDL := $(prebuilt_sdk_tools_bin)/aidl
AAPT := $(prebuilt_sdk_tools_bin)/aapt
AAPT2 := $(prebuilt_sdk_tools_bin)/aapt2
@@ -494,6 +544,8 @@
BCC_COMPAT := $(prebuilt_sdk_tools_bin)/bcc_compat
endif # TARGET_BUILD_PDK
endif # TARGET_BUILD_APPS || TARGET_BUILD_PDK
+prebuilt_sdk_tools :=
+prebuilt_sdk_tools_bin :=
# ---------------------------------------------------------------
@@ -508,11 +560,11 @@
BISON_PKGDATADIR := $(PWD)/external/bison/data
BISON := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/bison/bison
YACC := $(BISON) -d
+BISON_DATA := $(wildcard external/bison/data/* external/bison/data/*/*)
YASM := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/yasm/yasm
DOXYGEN:= doxygen
-AIDL_CPP := $(HOST_OUT_EXECUTABLES)/aidl-cpp$(HOST_EXECUTABLE_SUFFIX)
ifeq ($(HOST_OS),linux)
BREAKPAD_DUMP_SYMS := $(HOST_OUT_EXECUTABLES)/dump_syms
else
@@ -520,8 +572,11 @@
BREAKPAD_GENERATE_SYMBOLS := false
endif
PROTOC := $(HOST_OUT_EXECUTABLES)/aprotoc$(HOST_EXECUTABLE_SUFFIX)
+NANOPB_SRCS := external/nanopb-c/generator/protoc-gen-nanopb \
+ $(wildcard external/nanopb-c/generator/*.py \
+ external/nanopb-c/generator/google/*.py \
+ external/nanopb-c/generator/proto/*.py)
VTSC := $(HOST_OUT_EXECUTABLES)/vtsc$(HOST_EXECUTABLE_SUFFIX)
-DBUS_GENERATOR := $(HOST_OUT_EXECUTABLES)/dbus-binding-generator
MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
ifeq (,$(strip $(BOARD_CUSTOM_MKBOOTIMG)))
@@ -529,11 +584,28 @@
else
MKBOOTIMG := $(BOARD_CUSTOM_MKBOOTIMG)
endif
+ifeq (,$(strip $(BOARD_CUSTOM_BPTTOOL)))
+BPTTOOL := $(HOST_OUT_EXECUTABLES)/bpttool$(HOST_EXECUTABLE_SUFFIX)
+else
+BPTTOOL := $(BOARD_CUSTOM_BPTTOOL)
+endif
+ifeq (,$(strip $(BOARD_CUSTOM_AVBTOOL)))
+AVBTOOL := $(HOST_OUT_EXECUTABLES)/avbtool$(HOST_EXECUTABLE_SUFFIX)
+else
+AVBTOOL := $(BOARD_CUSTOM_AVBTOOL)
+endif
APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX)
FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
+ifeq ($(TARGET_USES_MKE2FS),true)
+MAKE_EXT4FS := $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX)
+MKEXTUSERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg_mke2fs.sh
+MKE2FS_CONF := system/extras/ext4_utils/mke2fs.conf
+else
MAKE_EXT4FS := $(HOST_OUT_EXECUTABLES)/make_ext4fs$(HOST_EXECUTABLE_SUFFIX)
-BLK_ALLOC_TO_BASE_FS := $(HOST_OUT_EXECUTABLES)/blk_alloc_to_base_fs$(HOST_EXECUTABLE_SUFFIX)
MKEXTUSERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg.sh
+MKE2FS_CONF :=
+endif
+BLK_ALLOC_TO_BASE_FS := $(HOST_OUT_EXECUTABLES)/blk_alloc_to_base_fs$(HOST_EXECUTABLE_SUFFIX)
MAKE_SQUASHFS := $(HOST_OUT_EXECUTABLES)/mksquashfs$(HOST_EXECUTABLE_SUFFIX)
MKSQUASHFSUSERIMG := $(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh
MAKE_F2FS := $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX)
@@ -543,9 +615,11 @@
E2FSCK := $(HOST_OUT_EXECUTABLES)/e2fsck$(HOST_EXECUTABLE_SUFFIX)
MKTARBALL := build/tools/mktarball.sh
TUNE2FS := $(HOST_OUT_EXECUTABLES)/tune2fs$(HOST_EXECUTABLE_SUFFIX)
-E2FSCK := $(HOST_OUT_EXECUTABLES)/e2fsck$(HOST_EXECUTABLE_SUFFIX)
JARJAR := $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
+DESUGAR := $(HOST_OUT_JAVA_LIBRARIES)/desugar.jar
DATA_BINDING_COMPILER := $(HOST_OUT_JAVA_LIBRARIES)/databinding-compiler.jar
+FAT16COPY := build/tools/fat16copy.py
+CHECK_LINK_TYPE := build/tools/check_link_type.py
ifeq ($(ANDROID_COMPILE_WITH_JACK),true)
DEFAULT_JACK_ENABLED:=full
@@ -553,16 +627,17 @@
DEFAULT_JACK_ENABLED:=
endif
ifneq ($(ANDROID_JACK_EXTRA_ARGS),)
+JACK_DEFAULT_ARGS :=
DEFAULT_JACK_EXTRA_ARGS := $(ANDROID_JACK_EXTRA_ARGS)
else
-DEFAULT_JACK_EXTRA_ARGS := @$(BUILD_SYSTEM)/jack-default.args
+JACK_DEFAULT_ARGS := $(BUILD_SYSTEM)/jack-default.args
+DEFAULT_JACK_EXTRA_ARGS := @$(JACK_DEFAULT_ARGS)
endif
-# Turn off jack warnings by default.
-DEFAULT_JACK_EXTRA_ARGS += --verbose error
PROGUARD := external/proguard/bin/proguard.sh
JAVATAGS := build/tools/java-event-log-tags.py
-RMTYPEDEFS := $(HOST_OUT_EXECUTABLES)/rmtypedefs
+MERGETAGS := build/tools/merge-event-log-tags.py
+BUILD_IMAGE_SRCS := $(wildcard build/tools/releasetools/*.py)
APPEND2SIMG := $(HOST_OUT_EXECUTABLES)/append2simg
VERITY_SIGNER := $(HOST_OUT_EXECUTABLES)/verity_signer
BUILD_VERITY_TREE := $(HOST_OUT_EXECUTABLES)/build_verity_tree
@@ -570,15 +645,10 @@
FUTILITY := $(HOST_OUT_EXECUTABLES)/futility-host
VBOOT_SIGNER := prebuilts/misc/scripts/vboot_signer/vboot_signer.sh
FEC := $(HOST_OUT_EXECUTABLES)/fec
+BRILLO_UPDATE_PAYLOAD := $(HOST_OUT_EXECUTABLES)/brillo_update_payload
-ifndef TARGET_BUILD_APPS
-ZIPTIME := $(HOST_OUT_EXECUTABLES)/ziptime$(HOST_EXECUTABLE_SUFFIX)
-endif
-
-# ijar converts a .jar file to a smaller .jar file which only has its
-# interfaces.
-IJAR := $(HOST_OUT_EXECUTABLES)/ijar$(BUILD_EXECUTABLE_SUFFIX)
DEXDUMP := $(HOST_OUT_EXECUTABLES)/dexdump2$(BUILD_EXECUTABLE_SUFFIX)
+PROFMAN := $(HOST_OUT_EXECUTABLES)/profman
# relocation packer
RELOCATION_PACKER := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/relocation_packer/relocation_packer
@@ -594,13 +664,21 @@
# We may not have the right JAVA_HOME/PATH set up yet when this is run from envsetup.sh.
ifneq ($(CALLED_FROM_SETUP),true)
-HOST_JDK_TOOLS_JAR:= $(shell $(BUILD_SYSTEM)/find-jdk-tools-jar.sh)
+
+# Path to tools.jar, or empty if EXPERIMENTAL_USE_OPENJDK9 is set
+HOST_JDK_TOOLS_JAR :=
+# TODO: Remove HOST_JDK_TOOLS_JAR and all references to it once OpenJDK 8
+# toolchains are no longer supported (i.e. when what is now
+# EXPERIMENTAL_USE_OPENJDK9 becomes the standard). http://b/38418220
+ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
+HOST_JDK_TOOLS_JAR := $(shell $(BUILD_SYSTEM)/find-jdk-tools-jar.sh)
ifneq ($(HOST_JDK_TOOLS_JAR),)
ifeq ($(wildcard $(HOST_JDK_TOOLS_JAR)),)
$(error Error: could not find jdk tools.jar at $(HOST_JDK_TOOLS_JAR), please check if your JDK was installed correctly)
endif
endif
+endif # ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
# Is the host JDK 64-bit version?
HOST_JDK_IS_64BIT_VERSION :=
@@ -616,11 +694,25 @@
MD5SUM:=md5sum
endif
-APICHECK_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
-APICHECK_CLASSPATH := $(APICHECK_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX)
-APICHECK_CLASSPATH := $(APICHECK_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX)
+APICHECK_CLASSPATH_ENTRIES := \
+ $(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX) \
+ $(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX) \
+ $(HOST_JDK_TOOLS_JAR) \
+ )
+APICHECK_CLASSPATH := $(subst $(space),:,$(strip $(APICHECK_CLASSPATH_ENTRIES)))
+
APICHECK_COMMAND := $(APICHECK) -JXmx1024m -J"classpath $(APICHECK_CLASSPATH)"
+# Boolean variable determining if Treble is fully enabled
+PRODUCT_FULL_TREBLE := false
+ifneq ($(PRODUCT_FULL_TREBLE_OVERRIDE),)
+ PRODUCT_FULL_TREBLE := $(PRODUCT_FULL_TREBLE_OVERRIDE)
+else ifeq ($(PRODUCT_SHIPPING_API_LEVEL),)
+ #$(warning no product shipping level defined)
+else ifneq ($(call math_gt_or_eq,$(PRODUCT_SHIPPING_API_LEVEL),26),)
+ PRODUCT_FULL_TREBLE := true
+endif
+
# The default key if not set as LOCAL_CERTIFICATE
ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
@@ -632,158 +724,29 @@
# Set up final options.
# ###############################################################
-ifneq ($(COMMON_GLOBAL_CFLAGS)$(COMMON_GLOBAL_CPPFLAGS),)
-$(warning COMMON_GLOBAL_C(PP)FLAGS changed)
-$(info *** Device configurations are no longer allowed to change the global flags.)
-$(info *** COMMON_GLOBAL_CFLAGS: $(COMMON_GLOBAL_CFLAGS))
-$(info *** COMMON_GLOBAL_CPPFLAGS: $(COMMON_GLOBAL_CPPFLAGS))
-$(error bailing...)
-endif
-
-# These can be changed to modify both host and device modules.
-COMMON_GLOBAL_CFLAGS:= -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -Winit-self -Wpointer-arith
-COMMON_RELEASE_CFLAGS:= -DNDEBUG -UDEBUG
-
-# Force gcc to always output color diagnostics. Ninja will strip the ANSI
-# color codes if it is not running in a terminal.
-ifdef BUILDING_WITH_NINJA
-COMMON_GLOBAL_CFLAGS += -fdiagnostics-color
-endif
-
-COMMON_GLOBAL_CPPFLAGS:= -Wsign-promo
-COMMON_RELEASE_CPPFLAGS:=
-
-GLOBAL_CFLAGS_NO_OVERRIDE := \
- -Werror=int-to-pointer-cast \
- -Werror=pointer-to-int-cast \
-
-GLOBAL_CLANG_CFLAGS_NO_OVERRIDE := \
- -Werror=address-of-temporary \
- -Werror=null-dereference \
- -Werror=return-type \
-
-GLOBAL_CPPFLAGS_NO_OVERRIDE :=
-
-# list of flags to turn specific warnings in to errors
-TARGET_ERROR_FLAGS := -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Werror=date-time
-
# We run gcc/clang with PWD=/proc/self/cwd to remove the $TOP
# from the debug output. That way two builds in two different
# directories will create the same output.
# /proc doesn't exist on Darwin.
ifeq ($(HOST_OS),linux)
RELATIVE_PWD := PWD=/proc/self/cwd
-# Remove this useless prefix from the debug output.
-COMMON_GLOBAL_CFLAGS += -fdebug-prefix-map=/proc/self/cwd=
else
RELATIVE_PWD :=
endif
-# Allow the C/C++ macros __DATE__ and __TIME__ to be set to the
-# build date and time, so that a build may be repeated.
-# Write the date and time to a file so that the command line
-# doesn't change every time, which would cause ninja to rebuild
-# the files.
-$(shell mkdir -p $(OUT_DIR) && \
- $(DATE) "+%b %_d %Y" > $(OUT_DIR)/build_c_date.txt && \
- $(DATE) +%T > $(OUT_DIR)/build_c_time.txt)
-BUILD_DATETIME_C_DATE := $$(cat $(OUT_DIR)/build_c_date.txt)
-BUILD_DATETIME_C_TIME := $$(cat $(OUT_DIR)/build_c_time.txt)
-ifeq ($(OVERRIDE_C_DATE_TIME),true)
-COMMON_GLOBAL_CFLAGS += -Wno-builtin-macro-redefined -D__DATE__="\"$(BUILD_DATETIME_C_DATE)\"" -D__TIME__=\"$(BUILD_DATETIME_C_TIME)\"
-endif
-
-HOST_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
-HOST_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
-
-HOST_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
-HOST_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
-
-TARGET_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
-TARGET_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
-
-TARGET_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
-TARGET_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
-
-HOST_GLOBAL_LD_DIRS += -L$(HOST_OUT_INTERMEDIATE_LIBRARIES)
-TARGET_GLOBAL_LD_DIRS += -L$(TARGET_OUT_INTERMEDIATE_LIBRARIES)
-
-HOST_PROJECT_INCLUDES:= $(SRC_HEADERS) $(SRC_HOST_HEADERS) $(HOST_OUT_HEADERS)
-TARGET_PROJECT_INCLUDES:= $(SRC_HEADERS) $(TARGET_OUT_HEADERS) \
+TARGET_PROJECT_INCLUDES :=
+TARGET_PROJECT_SYSTEM_INCLUDES := \
$(TARGET_DEVICE_KERNEL_HEADERS) $(TARGET_BOARD_KERNEL_HEADERS) \
$(TARGET_PRODUCT_KERNEL_HEADERS)
-# Many host compilers don't support these flags, so we have to make
-# sure to only specify them for the target compilers checked in to
-# the source tree.
-TARGET_GLOBAL_CFLAGS += $(TARGET_ERROR_FLAGS)
-
-HOST_GLOBAL_CFLAGS += $(HOST_RELEASE_CFLAGS)
-HOST_GLOBAL_CPPFLAGS += $(HOST_RELEASE_CPPFLAGS)
-
-TARGET_GLOBAL_CFLAGS += $(TARGET_RELEASE_CFLAGS)
-TARGET_GLOBAL_CPPFLAGS += $(TARGET_RELEASE_CPPFLAGS)
-
ifdef TARGET_2ND_ARCH
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LD_DIRS += -L$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_PROJECT_INCLUDES := $(TARGET_PROJECT_INCLUDES)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CFLAGS += $(TARGET_ERROR_FLAGS)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CFLAGS += $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_RELEASE_CFLAGS)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CPPFLAGS += $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_RELEASE_CPPFLAGS)
-endif
-
-ifdef HOST_2ND_ARCH
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_CFLAGS += $(COMMON_GLOBAL_CFLAGS)
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_LD_DIRS += -L$($(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES)
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_PROJECT_INCLUDES := $(HOST_PROJECT_INCLUDES)
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_CFLAGS += $($(HOST_2ND_ARCH_VAR_PREFIX)HOST_RELEASE_CFLAGS)
-$(HOST_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_CPPFLAGS += $($(HOST_2ND_ARCH_VAR_PREFIX)HOST_RELEASE_CPPFLAGS)
-endif
-
-ifdef HOST_CROSS_OS
-HOST_CROSS_GLOBAL_CFLAGS += $(filter-out $(HOST_CROSS_UNKNOWN_CFLAGS),$(COMMON_GLOBAL_CFLAGS))
-HOST_CROSS_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
-HOST_CROSS_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
-HOST_CROSS_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
-HOST_CROSS_GLOBAL_LD_DIRS += -L$(HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES)
-HOST_CROSS_PROJECT_INCLUDES:= $(SRC_HEADERS) $(SRC_HOST_HEADERS) $(HOST_CROSS_OUT_HEADERS)
-HOST_CROSS_GLOBAL_CFLAGS += $(HOST_CROSS_RELEASE_CFLAGS)
-HOST_CROSS_GLOBAL_CPPFLAGS += $(HOST_CROSS_RELEASE_CPPFLAGS)
-
-ifdef HOST_CROSS_2ND_ARCH
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_GLOBAL_CFLAGS += $(filter-out $($(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_UNKNOWN_CFLAGS),$(COMMON_GLOBAL_CFLAGS))
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_RELEASE_CFLAGS += $(COMMON_RELEASE_CFLAGS)
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_GLOBAL_CPPFLAGS += $(COMMON_GLOBAL_CPPFLAGS)
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_RELEASE_CPPFLAGS += $(COMMON_RELEASE_CPPFLAGS)
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_GLOBAL_LD_DIRS += -L$($(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES)
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_PROJECT_INCLUDES:= $(SRC_HEADERS) $(SRC_HOST_HEADERS) $($(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_HEADERS)
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_GLOBAL_CFLAGS += $($(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_RELEASE_CFLAGS)
-$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_GLOBAL_CPPFLAGS += $($(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_RELEASE_CPPFLAGS)
-endif
-endif
-
-ifdef BRILLO
-# Add a C define that identifies Brillo targets. __BRILLO__ should only be used
-# to differentiate between Brillo and non-Brillo-but-Android environments. Use
-# __ANDROID__ instead to test if something is being built in an Android-derived
-# environment (including Brillo) as opposed to an entirely different
-# environment (e.g. Chrome OS).
-TARGET_GLOBAL_CFLAGS += -D__BRILLO__
-ifdef TARGET_2ND_ARCH
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_CFLAGS += -D__BRILLO__
-endif
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_PROJECT_SYSTEM_INCLUDES := $(TARGET_PROJECT_SYSTEM_INCLUDES)
endif
# allow overriding default Java libraries on a per-target basis
ifeq ($(TARGET_DEFAULT_JAVA_LIBRARIES),)
- TARGET_DEFAULT_JAVA_LIBRARIES := core-oj core-libart core-junit ext framework okhttp
+ TARGET_DEFAULT_JAVA_LIBRARIES := core-oj core-libart ext framework okhttp
endif
# Flags for DEX2OAT
@@ -798,8 +761,11 @@
$(TARGET_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES := default
endif
-# define clang/llvm tools and global flags
-include $(BUILD_SYSTEM)/clang/config.mk
+# These will come from Soong, drop the environment versions
+unexport CLANG
+unexport CLANG_CXX
+unexport CCC_CC
+unexport CCC_CXX
# ###############################################################
# Collect a list of the SDK versions that we could compile against
@@ -858,14 +824,79 @@
RS_PREBUILT_CLCORE := prebuilts/sdk/renderscript/lib/$(TARGET_ARCH)/librsrt_$(TARGET_ARCH).bc
RS_PREBUILT_COMPILER_RT := prebuilts/sdk/renderscript/lib/$(TARGET_ARCH)/libcompiler_rt.a
ifeq (true,$(TARGET_IS_64_BIT))
-RS_PREBUILT_LIBPATH := -L prebuilts/ndk/current/platforms/android-21/arch-$(TARGET_ARCH)/usr/lib64 \
- -L prebuilts/ndk/current/platforms/android-21/arch-$(TARGET_ARCH)/usr/lib
+RS_PREBUILT_LIBPATH := -L prebuilts/ndk/r10/platforms/android-21/arch-$(TARGET_ARCH)/usr/lib64 \
+ -L prebuilts/ndk/r10/platforms/android-21/arch-$(TARGET_ARCH)/usr/lib
else
-RS_PREBUILT_LIBPATH := -L prebuilts/ndk/current/platforms/android-9/arch-$(TARGET_ARCH)/usr/lib
+RS_PREBUILT_LIBPATH := -L prebuilts/ndk/r10/platforms/android-9/arch-$(TARGET_ARCH)/usr/lib
endif
# API Level lists for Renderscript Compat lib.
RSCOMPAT_32BIT_ONLY_API_LEVELS := 8 9 10 11 12 13 14 15 16 17 18 19 20
RSCOMPAT_NO_USAGEIO_API_LEVELS := 8 9 10 11 12 13
+ifeq ($(JAVA_NOT_REQUIRED),true)
+# Remove java and tools from our path so that we make sure nobody uses them.
+unexport ANDROID_JAVA_HOME
+unexport JAVA_HOME
+export ANDROID_BUILD_PATHS:=$(abspath $(BUILD_SYSTEM)/no_java_path):$(ANDROID_BUILD_PATHS)
+export PATH:=$(abspath $(BUILD_SYSTEM)/no_java_path):$(PATH)
+endif
+
+# Projects clean of compiler warnings should be compiled with -Werror.
+# If most modules in a directory such as external/ have warnings,
+# the directory should be in ANDROID_WARNING_ALLOWED_PROJECTS list.
+# When some of its subdirectories are cleaned up, the subdirectories
+# can be added into ANDROID_WARNING_DISALLOWED_PROJECTS list, e.g.
+# external/fio/.
+ANDROID_WARNING_DISALLOWED_PROJECTS := \
+ art/% \
+ bionic/% \
+ external/fio/% \
+ hardware/interfaces/% \
+
+define find_warning_disallowed_projects
+ $(filter $(ANDROID_WARNING_DISALLOWED_PROJECTS),$(1)/)
+endef
+
+# Projects with compiler warnings are compiled without -Werror.
+ANDROID_WARNING_ALLOWED_PROJECTS := \
+ bootable/% \
+ cts/% \
+ dalvik/% \
+ development/% \
+ device/% \
+ external/% \
+ frameworks/% \
+ hardware/% \
+ packages/% \
+ system/% \
+ test/vts/% \
+ tools/adt/idea/android/ultimate/get_modification_time/jni/% \
+ vendor/% \
+
+define find_warning_allowed_projects
+ $(filter $(ANDROID_WARNING_ALLOWED_PROJECTS),$(1)/)
+endef
+
+# These goals don't need to collect and include Android.mks/CleanSpec.mks
+# in the source tree.
+dont_bother_goals := out \
+ snod systemimage-nodeps \
+ stnod systemtarball-nodeps \
+ userdataimage-nodeps userdatatarball-nodeps \
+ cacheimage-nodeps \
+ bptimage-nodeps \
+ vnod vendorimage-nodeps \
+ systemotherimage-nodeps \
+ ramdisk-nodeps \
+ bootimage-nodeps \
+ recoveryimage-nodeps \
+ vbmetaimage-nodeps \
+ product-graph dump-products
+
+ifndef KATI
+include $(BUILD_SYSTEM)/ninja_config.mk
+include $(BUILD_SYSTEM)/soong_config.mk
+endif
+
include $(BUILD_SYSTEM)/dumpvar.mk
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index dbcf276..04aedf4 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -3,6 +3,7 @@
##############################################
my_sanitize := $(strip $(LOCAL_SANITIZE))
+my_sanitize_diag := $(strip $(LOCAL_SANITIZE_DIAG))
# SANITIZE_HOST is only in effect if the module is already using clang (host
# modules that haven't set `LOCAL_CLANG := false` and device modules that
@@ -19,9 +20,8 @@
endif
endif
-# The sanitizer specified by the environment wins over the module.
ifneq ($(my_global_sanitize),)
- my_sanitize := $(my_global_sanitize)
+ my_sanitize := $(my_global_sanitize) $(my_sanitize)
endif
# The sanitizer specified in the product configuration wins over the previous.
@@ -32,10 +32,12 @@
endif
endif
-# Add a filter point for 32-bit vs 64-bit sanitization (to lighten the burden).
-SANITIZE_ARCH ?= 32 64
-ifeq ($(filter $(SANITIZE_ARCH),$(my_32_64_bit_suffix)),)
- my_sanitize :=
+ifndef LOCAL_IS_HOST_MODULE
+ # Add a filter point for 32-bit vs 64-bit sanitization (to lighten the burden)
+ SANITIZE_TARGET_ARCH ?= $(TARGET_ARCH) $(TARGET_2ND_ARCH)
+ ifeq ($(filter $(SANITIZE_TARGET_ARCH),$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
+ my_sanitize :=
+ endif
endif
# Add a filter point based on module owner (to lighten the burden). The format is a space- or
@@ -52,6 +54,7 @@
# Don't apply sanitizers to NDK code.
ifdef LOCAL_SDK_VERSION
my_sanitize :=
+ my_global_sanitize :=
endif
# Never always wins.
@@ -59,6 +62,35 @@
my_sanitize :=
endif
+# If CFI is disabled globally, remove it from my_sanitize.
+ifeq ($(strip $(ENABLE_CFI)),false)
+ my_sanitize := $(filter-out cfi,$(my_sanitize))
+ my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
+endif
+
+# Disable CFI for arm32 (b/35157333).
+ifneq ($(filter arm,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
+ my_sanitize := $(filter-out cfi,$(my_sanitize))
+ my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
+endif
+
+# Also disable CFI if ASAN is enabled.
+ifneq ($(filter address,$(my_sanitize)),)
+ my_sanitize := $(filter-out cfi,$(my_sanitize))
+ my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
+endif
+
+# CFI needs gold linker, and mips toolchain does not have one.
+ifneq ($(filter mips mips64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
+ my_sanitize := $(filter-out cfi,$(my_sanitize))
+ my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
+endif
+
+my_nosanitize = $(strip $(LOCAL_NOSANITIZE))
+ifneq ($(my_nosanitize),)
+ my_sanitize := $(filter-out $(my_nosanitize),$(my_sanitize))
+endif
+
# TSAN is not supported on 32-bit architectures. For non-multilib cases, make
# its use an error. For multilib cases, don't use it for the 32-bit case.
ifneq ($(filter thread,$(my_sanitize)),)
@@ -71,21 +103,23 @@
endif
endif
+ifneq ($(filter safe-stack,$(my_sanitize)),)
+ ifeq ($(my_32_64_bit_suffix),32)
+ my_sanitize := $(filter-out safe-stack,$(my_sanitize))
+ endif
+endif
+
# Undefined symbols can occur if a non-sanitized library links
# sanitized static libraries. That's OK, because the executable
# always depends on the ASan runtime library, which defines these
# symbols.
-ifneq ($(strip $(SANITIZE_TARGET)),)
+ifneq ($(filter address thread,$(strip $(SANITIZE_TARGET))),)
ifndef LOCAL_IS_HOST_MODULE
ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
ifeq ($(my_sanitize),)
my_allow_undefined_symbols := true
endif
endif
- # Workaround for a bug in AddressSanitizer that breaks stack unwinding.
- # https://code.google.com/p/address-sanitizer/issues/detail?id=387
- # Revert when external/compiler-rt is updated past r236014.
- LOCAL_PACK_MODULE_RELOCATIONS := false
endif
endif
@@ -117,18 +151,32 @@
my_ldflags += -fsanitize=$(fsanitize_arg)
my_ldlibs += -lrt -ldl
else
- ifeq ($(filter address,$(my_sanitize)),)
- my_cflags += -fsanitize-trap=all
- my_cflags += -ftrap-function=abort
+ my_cflags += -fsanitize-trap=all
+ my_cflags += -ftrap-function=abort
+ ifneq ($(filter address thread,$(my_sanitize)),)
+ my_cflags += -fno-sanitize-trap=address,thread
+ my_shared_libraries += libdl
endif
- my_shared_libraries += libdl
endif
endif
-ifneq ($(filter address,$(my_sanitize)),)
- # Frame pointer based unwinder in ASan requires ARM frame setup.
- LOCAL_ARM_MODE := arm
- my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
+ifneq ($(filter cfi,$(my_sanitize)),)
+ # __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp).
+ # LLVM is not set up to do this on a function basis, so force Thumb on the
+ # entire module.
+ LOCAL_ARM_MODE := thumb
+ my_cflags += $(CFI_EXTRA_CFLAGS)
+ my_ldflags += $(CFI_EXTRA_LDFLAGS)
+ my_arflags += --plugin $(LLVM_PREBUILTS_PATH)/../lib64/LLVMgold.so
+ # Workaround for b/33678192. CFI jumptables need Thumb2 codegen. Revert when
+ # Clang is updated past r290384.
+ ifneq ($(filter arm,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
+ my_ldflags += -march=armv7-a
+ endif
+endif
+
+# If local or global modules need ASAN, add linker flags.
+ifneq ($(filter address,$(my_global_sanitize) $(my_sanitize)),)
my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS)
ifdef LOCAL_IS_HOST_MODULE
# -nodefaultlibs (provided with libc++) prevents the driver from linking
@@ -136,16 +184,38 @@
my_ldlibs += -lm -lpthread
my_ldflags += -Wl,--no-as-needed
else
- my_cflags += -mllvm -asan-globals=0
+ # Add asan libraries unless LOCAL_MODULE is the asan library.
# ASan runtime library must be the first in the link order.
- my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
- $(my_shared_libraries) \
- $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES)
- my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
+ ifeq (,$(filter $(LOCAL_MODULE),$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY)))
+ my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
+ $(my_shared_libraries)
+ endif
+ ifeq (,$(filter $(LOCAL_MODULE),$(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)))
+ my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
+ endif
- my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
- # Make sure linker_asan get installed.
- $(LOCAL_INSTALLED_MODULE) : | $(PRODUCT_OUT)$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
+ # Do not add unnecessary dependency in shared libraries.
+ ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
+ my_ldflags += -Wl,--as-needed
+ endif
+
+ ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
+ ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+ my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
+ # Make sure linker_asan get installed.
+ $(LOCAL_INSTALLED_MODULE) : | $(PRODUCT_OUT)$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
+ endif
+ endif
+ endif
+endif
+
+# If local module needs ASAN, add compiler flags.
+ifneq ($(filter address,$(my_sanitize)),)
+ # Frame pointer based unwinder in ASan requires ARM frame setup.
+ LOCAL_ARM_MODE := arm
+ my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
+ ifndef LOCAL_IS_HOST_MODULE
+ my_cflags += -mllvm -asan-globals=0
endif
endif
@@ -159,3 +229,13 @@
recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_RECOVER)),
my_cflags += -fsanitize-recover=$(recover_arg)
endif
+
+ifneq ($(my_sanitize_diag),)
+ notrap_arg := $(subst $(space),$(comma),$(my_sanitize_diag)),
+ my_cflags += -fno-sanitize-trap=$(notrap_arg)
+ # Diagnostic requires a runtime library, unless ASan or TSan are also enabled.
+ ifeq ($(filter address thread,$(my_sanitize)),)
+ # Does not have to be the first DT_NEEDED unlike ASan.
+ my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY)
+ endif
+endif
diff --git a/core/configure_local_jack.mk b/core/configure_local_jack.mk
index 2270c88..f8049a3 100644
--- a/core/configure_local_jack.mk
+++ b/core/configure_local_jack.mk
@@ -18,18 +18,23 @@
LOCAL_JACK_ENABLED := $(ANDROID_FORCE_JACK_ENABLED)
endif
+ifneq ($(ANDROID_COMPILE_WITH_JACK),true)
+LOCAL_JACK_ENABLED :=
+endif
+
LOCAL_JACK_ENABLED := $(strip $(LOCAL_JACK_ENABLED))
LOCAL_MODULE := $(strip $(LOCAL_MODULE))
-ifneq ($(LOCAL_JACK_ENABLED),full)
-ifneq ($(LOCAL_JACK_ENABLED),incremental)
+valid_jack_enabled_values := full incremental javac_frontend disabled
+
ifdef LOCAL_JACK_ENABLED
-ifneq ($(LOCAL_JACK_ENABLED),disabled)
-$(error $(LOCAL_PATH): invalid LOCAL_JACK_ENABLED "$(LOCAL_JACK_ENABLED)" for $(LOCAL_MODULE))
-endif
-endif
-LOCAL_JACK_ENABLED :=
-endif
+ ifneq ($(LOCAL_JACK_ENABLED),$(filter $(firstword $(LOCAL_JACK_ENABLED)),$(valid_jack_enabled_values)))
+ $(error $(LOCAL_PATH): invalid LOCAL_JACK_ENABLED "$(LOCAL_JACK_ENABLED)" for $(LOCAL_MODULE))
+ endif
+
+ ifeq ($(LOCAL_JACK_ENABLED),disabled)
+ LOCAL_JACK_ENABLED :=
+ endif
endif
ifdef $(LOCAL_MODULE).JACK_VERSION
diff --git a/core/copy_headers.mk b/core/copy_headers.mk
index 7d5a5d9..c26d51d 100644
--- a/core/copy_headers.mk
+++ b/core/copy_headers.mk
@@ -1,10 +1,30 @@
+ifneq (,$(strip $(LOCAL_COPY_HEADERS)))
###########################################################
## Copy headers to the install tree
###########################################################
+$(call record-module-type,COPY_HEADERS)
ifneq ($(strip $(LOCAL_IS_HOST_MODULE)),)
- my_prefix := HOST_
-else
- my_prefix := TARGET_
+ $(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): LOCAL_COPY_HEADERS may not be used with host modules >&2)
+ $(error done)
+endif
+
+# Modules linking against the SDK do not have the include path to use
+# COPY_HEADERS, so prevent them from exporting any either.
+ifdef LOCAL_SDK_VERSION
+$(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Modules using LOCAL_SDK_VERSION may not use LOCAL_COPY_HEADERS >&2)
+$(error done)
+endif
+
+include $(BUILD_SYSTEM)/local_vndk.mk
+
+# If we're using the VNDK, only vendor modules using the VNDK may use
+# LOCAL_COPY_HEADERS. Platform libraries will not have the include path
+# present.
+ifdef BOARD_VNDK_VERSION
+ifndef LOCAL_USE_VNDK
+$(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Only vendor modules using LOCAL_USE_VNDK may use LOCAL_COPY_HEADERS >&2)
+$(error done)
+endif
endif
# Create a rule to copy each header, and make the
@@ -16,8 +36,8 @@
$(eval _chFrom := $(LOCAL_PATH)/$(header)) \
$(eval _chTo := \
$(if $(LOCAL_COPY_HEADERS_TO),\
- $($(my_prefix)OUT_HEADERS)/$(LOCAL_COPY_HEADERS_TO)/$(notdir $(header)),\
- $($(my_prefix)OUT_HEADERS)/$(notdir $(header)))) \
+ $(TARGET_OUT_HEADERS)/$(LOCAL_COPY_HEADERS_TO)/$(notdir $(header)),\
+ $(TARGET_OUT_HEADERS)/$(notdir $(header)))) \
$(eval ALL_COPIED_HEADERS.$(_chTo).MAKEFILE += $(LOCAL_MODULE_MAKEFILE)) \
$(eval ALL_COPIED_HEADERS.$(_chTo).SRC += $(_chFrom)) \
$(if $(filter $(_chTo),$(ALL_COPIED_HEADERS)),, \
@@ -25,3 +45,5 @@
)
_chFrom :=
_chTo :=
+
+endif # LOCAL_COPY_HEADERS
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
index 37be1f7..fd9c442 100644
--- a/core/cxx_stl_setup.mk
+++ b/core/cxx_stl_setup.mk
@@ -70,6 +70,7 @@
endif
endif
+my_cxx_ldlibs :=
ifneq ($(filter $(my_cxx_stl),libc++ libc++_static),)
my_cflags += -D_USING_LIBCXX
@@ -89,7 +90,7 @@
my_cppflags += -nostdinc++
my_ldflags += -nodefaultlibs
my_ldlibs += -lpthread -lm
- my_ldlibs += $($($(my_prefix)OS)_$(my_link_type)_gcclibs)
+ my_cxx_ldlibs += $($($(my_prefix)OS)_$(my_link_type)_gcclibs)
else
ifeq (arm,$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
my_static_libraries += libunwind_llvm
@@ -105,18 +106,16 @@
else ifeq ($(my_cxx_stl),ndk)
# Using an NDK STL. Handled in binary.mk.
else ifeq ($(my_cxx_stl),libstdc++)
- # Using bionic's basic libstdc++. Not actually an STL. Only around until the
- # tree is in good enough shape to not need it.
ifndef LOCAL_IS_HOST_MODULE
- my_c_includes += bionic/libstdc++/include
- my_system_shared_libraries += libstdc++
+ $(error $(LOCAL_PATH): $(LOCAL_MODULE): libstdc++ is not supported for device modules)
+ else ifneq ($($(my_prefix)OS),windows)
+ $(error $(LOCAL_PATH): $(LOCAL_MODULE): libstdc++ is not supported on $($(my_prefix)OS))
endif
- # Host builds will use GNU libstdc++.
else ifeq ($(my_cxx_stl),none)
ifdef LOCAL_IS_HOST_MODULE
my_cppflags += -nostdinc++
my_ldflags += -nodefaultlibs
- my_ldlibs += $($($(my_prefix)OS)_$(my_link_type)_gcclibs)
+ my_cxx_ldlibs += $($($(my_prefix)OS)_$(my_link_type)_gcclibs)
endif
else
$(error $(LOCAL_PATH): $(LOCAL_MODULE): $(my_cxx_stl) is not a supported STL.)
diff --git a/core/definitions.mk b/core/definitions.mk
index 84ea801..15ef6f4 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -55,10 +55,6 @@
# its sub-variables.)
ALL_MODULE_NAME_TAGS:=
-# Full paths to all prebuilt files that will be copied
-# (used to make the dependency on acp)
-ALL_PREBUILT:=
-
# Full path to all files that are made by some tool
ALL_GENERATED_SOURCES:=
@@ -96,9 +92,13 @@
# Display names for various build targets
TARGET_DISPLAY := target
+AUX_DISPLAY := aux
HOST_DISPLAY := host
HOST_CROSS_DISPLAY := host cross
+# All installed initrc files
+ALL_INIT_RC_INSTALLED_PAIRS :=
+
###########################################################
## Debugging; prints a variable list to stdout
###########################################################
@@ -123,6 +123,15 @@
$(filter true, $(1))
endef
+###########################################################
+## Rule for touching GCNO files.
+###########################################################
+define gcno-touch-rule
+$(2): $(1)
+ touch -c $$@
+endef
+
+###########################################################
###########################################################
## Retrieve the directory of the current makefile
@@ -133,7 +142,6 @@
define my-dir
$(strip \
$(eval LOCAL_MODULE_MAKEFILE := $$(lastword $$(MAKEFILE_LIST))) \
- $(eval LOCAL_MODULE_MAKEFILE_DEP := $(if $(BUILDING_WITH_NINJA),,$$(LOCAL_MODULE_MAKEFILE))) \
$(if $(filter $(BUILD_SYSTEM)/% $(OUT_DIR)/%,$(LOCAL_MODULE_MAKEFILE)), \
$(error my-dir must be called before including any other makefile.) \
, \
@@ -142,28 +150,13 @@
)
endef
-###########################################################
-## Remove any makefiles that are being handled by soong
-###########################################################
-ifeq ($(USE_SOONG),true)
-define filter-soong-makefiles
-$(foreach mk,$(1),\
- $(if $(wildcard $(patsubst %/Android.mk,%/Android.bp,$(mk))),\
- $(info skipping $(mk) ...),\
- $(mk)))
-endef
-else
-define filter-soong-makefiles
-$(1)
-endef
-endif
###########################################################
## Retrieve a list of all makefiles immediately below some directory
###########################################################
define all-makefiles-under
-$(sort $(call filter-soong-makefiles,$(wildcard $(1)/*/Android.mk)))
+$(wildcard $(1)/*/Android.mk)
endef
###########################################################
@@ -174,9 +167,8 @@
# $(1): directory to search under
# Ignores $(1)/Android.mk
define first-makefiles-under
-$(call filter-soong-makefiles,\
- $(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) \
- --mindepth=2 $(1) Android.mk))
+$(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) \
+ --mindepth=2 $(addprefix --dir=,$(1)) Android.mk)
endef
###########################################################
@@ -196,8 +188,7 @@
# $(1): List of directories to look for under this directory
define all-named-subdir-makefiles
-$(sort $(call filter-soong-makefiles,\
- $(wildcard $(addsuffix /Android.mk, $(addprefix $(call my-dir)/,$(1))))))
+$(wildcard $(addsuffix /Android.mk, $(addprefix $(call my-dir)/,$(1))))
endef
###########################################################
@@ -425,8 +416,8 @@
define find-subdir-assets
$(sort $(if $(1),$(patsubst ./%,%, \
- $(shell if [ -d $(1) ] ; then cd $(1) ; find -L ./ -not -name '.*' -and -type f -and -not -type l ; fi)), \
- $(warning Empty argument supplied to find-subdir-assets) \
+ $(shell if [ -d $(1) ] ; then cd $(1) ; find -L ./ -not -name '.*' -and -type f ; fi)), \
+ $(warning Empty argument supplied to find-subdir-assets in $(LOCAL_PATH)) \
))
endef
@@ -478,6 +469,20 @@
endef
###########################################################
+## Find test data in a form required by LOCAL_TEST_DATA
+## $(1): the base dir, relative to the root of the source tree.
+## $(3): the file name pattern to be passed to find as "-name"
+## $(2): a list of subdirs of the base dir
+###########################################################
+
+define find-test-data-in-subdirs
+$(foreach f,$(sort $(patsubst ./%,%, \
+ $(shell cd $(1) ; \
+ find -L $(3) -type f -and -name $(2) -and -not -name ".*") \
+)),$(1):$(f))
+endef
+
+###########################################################
## Function we can evaluate to introduce a dynamic dependency
###########################################################
@@ -493,6 +498,28 @@
$(if $(1),$(call reverse-list,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
endef
+define def-host-aux-target
+$(eval _idf_val_:=$(if $(strip $(LOCAL_IS_HOST_MODULE)),HOST,$(if $(strip $(LOCAL_IS_AUX_MODULE)),AUX,))) \
+$(_idf_val_)
+endef
+
+###########################################################
+## Returns correct _idfPrefix from the list:
+## { HOST, HOST_CROSS, AUX, TARGET }
+###########################################################
+# the following rules checked in order:
+# ($1 is in {AUX, HOST_CROSS} => $1;
+# ($1 is empty) => TARGET;
+# ($2 is not empty) => HOST_CROSS;
+# => HOST;
+define find-idf-prefix
+$(strip \
+ $(eval _idf_pfx_:=$(strip $(filter AUX HOST_CROSS,$(1)))) \
+ $(eval _idf_pfx_:=$(if $(strip $(1)),$(if $(_idf_pfx_),$(_idf_pfx_),$(if $(strip $(2)),HOST_CROSS,HOST)),TARGET)) \
+ $(_idf_pfx_)
+)
+endef
+
###########################################################
## The intermediates directory. Where object files go for
## a given target. We could technically get away without
@@ -503,7 +530,7 @@
# $(1): target class, like "APPS"
# $(2): target name, like "NotePad"
-# $(3): if non-empty, this is a HOST target.
+# $(3): { HOST, HOST_CROSS, AUX, <empty (TARGET)>, <other non-empty (HOST)> }
# $(4): if non-empty, force the intermediates to be COMMON
# $(5): if non-empty, force the intermediates to be for the 2nd arch
# $(6): if non-empty, force the intermediates to be for the host cross os
@@ -515,7 +542,7 @@
$(eval _idfName := $(strip $(2))) \
$(if $(_idfName),, \
$(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \
- $(eval _idfPrefix := $(if $(strip $(3)),$(if $(strip $(6)),HOST_CROSS,HOST),TARGET)) \
+ $(eval _idfPrefix := $(call find-idf-prefix,$(3),$(6))) \
$(eval _idf2ndArchPrefix := $(if $(strip $(5)),$(TARGET_2ND_ARCH_VAR_PREFIX))) \
$(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
$(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \
@@ -540,7 +567,7 @@
$(error $(LOCAL_PATH): LOCAL_MODULE_CLASS not defined before call to local-intermediates-dir)) \
$(if $(strip $(LOCAL_MODULE)),, \
$(error $(LOCAL_PATH): LOCAL_MODULE not defined before call to local-intermediates-dir)) \
- $(call intermediates-dir-for,$(LOCAL_MODULE_CLASS),$(LOCAL_MODULE),$(LOCAL_IS_HOST_MODULE),$(1),$(2),$(3)) \
+ $(call intermediates-dir-for,$(LOCAL_MODULE_CLASS),$(LOCAL_MODULE),$(call def-host-aux-target),$(1),$(2),$(3)) \
)
endef
@@ -555,7 +582,7 @@
# $(1): target class, like "APPS"
# $(2): target name, like "NotePad"
-# $(3): if non-empty, this is a HOST target.
+# $(3): { HOST, HOST_CROSS, AUX, <empty (TARGET)>, <other non-empty (HOST)> }
# $(4): if non-empty, force the generated sources to be COMMON
define generated-sources-dir-for
$(strip \
@@ -565,7 +592,7 @@
$(eval _idfName := $(strip $(2))) \
$(if $(_idfName),, \
$(error $(LOCAL_PATH): Name not defined in call to generated-sources-dir-for)) \
- $(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \
+ $(eval _idfPrefix := $(call find-idf-prefix,$(3),)) \
$(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
$(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_GEN)) \
, \
@@ -585,30 +612,11 @@
$(error $(LOCAL_PATH): LOCAL_MODULE_CLASS not defined before call to local-generated-sources-dir)) \
$(if $(strip $(LOCAL_MODULE)),, \
$(error $(LOCAL_PATH): LOCAL_MODULE not defined before call to local-generated-sources-dir)) \
- $(call generated-sources-dir-for,$(LOCAL_MODULE_CLASS),$(LOCAL_MODULE),$(LOCAL_IS_HOST_MODULE),$(1)) \
+ $(call generated-sources-dir-for,$(LOCAL_MODULE_CLASS),$(LOCAL_MODULE),$(call def-host-aux-target),$(1)) \
)
endef
###########################################################
-## Convert "path/to/libXXX.so" to "-lXXX".
-## Any "path/to/libXXX.a" elements pass through unchanged.
-###########################################################
-
-define normalize-libraries
-$(foreach so,$(filter %.so,$(1)),-l$(patsubst lib%.so,%,$(notdir $(so))))\
-$(filter-out %.so,$(1))
-endef
-
-# TODO: change users to call the common version.
-define normalize-host-libraries
-$(call normalize-libraries,$(1))
-endef
-
-define normalize-target-libraries
-$(call normalize-libraries,$(1))
-endef
-
-###########################################################
## Convert a list of short module names (e.g., "framework", "Browser")
## into the list of files that are built for those modules.
## NOTE: this won't return reliable results until after all
@@ -673,7 +681,7 @@
# $(1): library name
# $(2): Non-empty if IS_HOST_MODULE
define _java-lib-full-classes.jar
-$(call _java-lib-dir,$(1),$(2))/$(if $(2),javalib,classes)$(COMMON_JAVA_PACKAGE_SUFFIX)
+$(call _java-lib-dir,$(1),$(2))/classes.jar
endef
# Get the jar files (you can pass to "javac -classpath") of static or shared
@@ -696,14 +704,6 @@
$(call java-lib-files,$(1),$(2))
endef
-# Get the jar files (you can pass to "javac -classpath") of host dalvik Java libraries.
-# You can also use them as dependency files.
-# A host dalvik Java library is different from a host Java library in that
-# the java lib file is classes.jar, not javalib.jar.
-# $(1): library name list
-define host-dex-java-lib-files
-$(foreach lib,$(1),$(call _java-lib-dir,$(lib),true)/classes.jar)
-endef
###########################################################
## Convert "core ext framework" to "out/.../classes.jack ..."
@@ -723,21 +723,6 @@
$(foreach lib,$(1),$(call _jack-lib-full-classes,$(lib),$(2)))
endef
-# $(1): library name list
-# $(2): Non-empty if IS_HOST_MODULE
-define jack-lib-deps
-$(call jack-lib-files,$(1),$(2))
-endef
-
-###########################################################
-## Run rot13 on a string
-## $(1): the string. Must be one line.
-###########################################################
-define rot13
-$(shell echo $(1) | tr 'a-zA-Z' 'n-za-mN-ZA-M')
-endef
-
-
###########################################################
## Returns true if $(1) and $(2) are equal. Returns
## the empty string if they are not equal.
@@ -761,6 +746,13 @@
endef
###########################################################
+## Convert "a b c" into "a,b,c"
+###########################################################
+define normalize-comma-list
+$(subst $(space),$(comma),$(strip $(1)))
+endef
+
+###########################################################
## Read the word out of a colon-separated list of words.
## This has the same behavior as the built-in function
## $(word n,str).
@@ -850,6 +842,39 @@
###########################################################
+## Color-coded warnings and errors
+## Use echo-(warning|error) in a build rule
+## Use pretty-(warning|error) instead of $(warning)/$(error)
+###########################################################
+ESC_BOLD := \033[1m
+ESC_WARNING := \033[35m
+ESC_ERROR := \033[31m
+ESC_RESET := \033[0m
+
+# $(1): path (and optionally line) information
+# $(2): message to print
+define echo-warning
+echo -e "$(ESC_BOLD)$(1): $(ESC_WARNING)warning:$(ESC_RESET)$(ESC_BOLD)" $(2) "$(ESC_RESET)" >&2
+endef
+
+# $(1): path (and optionally line) information
+# $(2): message to print
+define echo-error
+echo -e "$(ESC_BOLD)$(1): $(ESC_ERROR)error:$(ESC_RESET)$(ESC_BOLD)" $(2) "$(ESC_RESET)" >&2
+endef
+
+# $(1): message to print
+define pretty-warning
+$(shell $(call echo-warning,$(LOCAL_MODULE_MAKEFILE),$(LOCAL_MODULE): $(1)))
+endef
+
+# $(1): message to print
+define pretty-error
+$(shell $(call echo-error,$(LOCAL_MODULE_MAKEFILE),$(LOCAL_MODULE): $(1)))
+$(error done)
+endef
+
+###########################################################
## Package filtering
###########################################################
@@ -898,39 +923,17 @@
endif
###########################################################
-## Commands for munging the dependency files the compiler generates
-###########################################################
-# $(1): the input .d file
-# $(2): the output .P file
-define transform-d-to-p-args
-$(hide) cp $(1) $(2); \
- sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
- -e '/^$$/ d' -e 's/$$/ :/' < $(1) >> $(2); \
- rm -f $(1)
-endef
-
-define transform-d-to-p
-$(call transform-d-to-p-args,$(@:%.o=%.d),$(@:%.o=%.P))
-endef
-
-###########################################################
## Commands for including the dependency files the compiler generates
###########################################################
# $(1): the .P file
# $(2): the main build target
-ifeq ($(BUILDING_WITH_NINJA),true)
define include-depfile
$(eval $(2) : .KATI_DEPFILE := $1)
endef
-else
-define include-depfile
-$(eval -include $1)
-endef
-endif
# $(1): object files
define include-depfiles-for-objs
-$(foreach obj, $(1), $(call include-depfile, $(obj:%.o=%.P), $(obj)))
+$(foreach obj, $(1), $(call include-depfile, $(obj:%.o=%.d), $(obj)))
endef
###########################################################
@@ -1014,12 +1017,15 @@
$(hide) echo >> $2
endef
+# b/37755219
+RS_CC_ASAN_OPTIONS := ASAN_OPTIONS=detect_leaks=0:detect_container_overflow=0
+
define transform-renderscripts-to-java-and-bc
@echo "RenderScript: $(PRIVATE_MODULE) <= $(PRIVATE_RS_SOURCE_FILES)"
$(hide) rm -rf $(PRIVATE_RS_OUTPUT_DIR)
$(hide) mkdir -p $(PRIVATE_RS_OUTPUT_DIR)/res/raw
$(hide) mkdir -p $(PRIVATE_RS_OUTPUT_DIR)/src
-$(hide) $(PRIVATE_RS_CC) \
+$(hide) $(RS_CC_ASAN_OPTIONS) $(PRIVATE_RS_CC) \
-o $(PRIVATE_RS_OUTPUT_DIR)/res/raw \
-p $(PRIVATE_RS_OUTPUT_DIR)/src \
-d $(PRIVATE_RS_OUTPUT_DIR) \
@@ -1029,7 +1035,6 @@
$(foreach inc,$(PRIVATE_RS_INCLUDES),$(addprefix -I , $(inc))) \
$(PRIVATE_RS_SOURCE_FILES)
$(call _merge-renderscript-d,$(PRIVATE_DEP_FILES),$@.d)
-$(call transform-d-to-p-args,$@.d,$@.P)
$(hide) mkdir -p $(dir $@)
$(hide) touch $@
endef
@@ -1044,8 +1049,9 @@
$(dir $@)/$(notdir $(<:.bc=.o)) \
$(RS_PREBUILT_COMPILER_RT) \
-o $@ $(TARGET_GLOBAL_LDFLAGS) -Wl,--hash-style=sysv -L prebuilts/gcc/ \
- $(RS_PREBUILT_LIBPATH) -L $(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
- -lRSSupport -lm -lc
+ $(RS_PREBUILT_LIBPATH) \
+ $(call intermediates-dir-for,SHARED_LIBRARIES,libRSSupport)/libRSSupport.so \
+ -lm -lc
endef
###########################################################
@@ -1056,7 +1062,7 @@
@echo "RenderScript: $(PRIVATE_MODULE) <= $(PRIVATE_RS_SOURCE_FILES)"
$(hide) rm -rf $(PRIVATE_RS_OUTPUT_DIR)
$(hide) mkdir -p $(PRIVATE_RS_OUTPUT_DIR)/
-$(hide) $(PRIVATE_RS_CC) \
+$(hide) $(RS_CC_ASAN_OPTIONS) $(PRIVATE_RS_CC) \
-o $(PRIVATE_RS_OUTPUT_DIR)/ \
-d $(PRIVATE_RS_OUTPUT_DIR) \
-a $@ -MD \
@@ -1066,7 +1072,6 @@
$(addprefix -I , $(PRIVATE_RS_INCLUDES)) \
$(PRIVATE_RS_SOURCE_FILES)
$(call _merge-renderscript-d,$(PRIVATE_DEP_FILES),$@.d)
-$(call transform-d-to-p-args,$@.d,$@.P)
$(hide) mkdir -p $(dir $@)
$(hide) touch $@
endef
@@ -1087,10 +1092,23 @@
@mkdir -p $(dir $@)
@mkdir -p $(PRIVATE_HEADER_OUTPUT_DIR)
@echo "Generating C++ from AIDL: $(PRIVATE_MODULE) <= $<"
-$(hide) $(AIDL_CPP) -d$(basename $@).aidl.P $(PRIVATE_AIDL_FLAGS) \
+$(hide) $(AIDL_CPP) -d$(basename $@).aidl.d -ninja $(PRIVATE_AIDL_FLAGS) \
$< $(PRIVATE_HEADER_OUTPUT_DIR) $@
endef
+## Given a .aidl file path, generate the rule to compile it a .java file
+# $(1): a .aidl source file
+# $(2): a directory to place the generated .java files in
+# $(3): name of a variable to add the path to the generated source file to
+#
+# You must call this with $(eval).
+define define-aidl-java-rule
+define-aidl-java-rule-src := $(patsubst %.aidl,%.java,$(subst ../,dotdot/,$(addprefix $(2)/,$(1))))
+$$(define-aidl-java-rule-src) : $(LOCAL_PATH)/$(1) $(AIDL)
+ $$(transform-aidl-to-java)
+$(3) += $$(define-aidl-java-rule-src)
+endef
+
## Given a .aidl file path generate the rule to compile it a .cpp file.
# $(1): a .aidl source file
# $(2): a directory to place the generated .cpp files in
@@ -1136,7 +1154,7 @@
define transform-logtags-to-java
@mkdir -p $(dir $@)
@echo "logtags: $@ <= $<"
-$(hide) $(JAVATAGS) -o $@ $^
+$(hide) $(JAVATAGS) -o $@ $< $(PRIVATE_MERGED_TAG)
endef
@@ -1174,47 +1192,27 @@
$(hide) mv $(basename $@).cc $@)
endef
-
-######################################################################
-## Commands for generating DBus adaptors from .dbus-xml files.
-######################################################################
-define generate-dbus-adaptors
-@echo "Generating DBus adaptors for $(PRIVATE_MODULE)"
-@mkdir -p $(dir $@)
-$(hide) $(DBUS_GENERATOR) \
- --service-config=$(PRIVATE_DBUS_SERVICE_CONFIG) \
- --adaptor=$@ \
- $<
+###########################################################
+## Helper to set include paths form transform-*-to-o
+###########################################################
+define c-includes
+$(addprefix -I , $(PRIVATE_C_INCLUDES)) \
+$$(cat $(PRIVATE_IMPORT_INCLUDES))\
+$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),,\
+ $(addprefix -I ,\
+ $(filter-out $(PRIVATE_C_INCLUDES), \
+ $(PRIVATE_GLOBAL_C_INCLUDES))) \
+ $(addprefix -isystem ,\
+ $(filter-out $(PRIVATE_C_INCLUDES), \
+ $(PRIVATE_GLOBAL_C_SYSTEM_INCLUDES))))
endef
-######################################################################
-## Commands for generating DBus proxies from .dbus-xml files.
-######################################################################
-define generate-dbus-proxies
-@echo "Generating DBus proxies for $(PRIVATE_MODULE)"
-@mkdir -p $(dir $@)
-$(hide) $(DBUS_GENERATOR) \
- --service-config=$(PRIVATE_DBUS_SERVICE_CONFIG) \
- --proxy=$@ \
- $(filter %.dbus-xml,$^)
-endef
-
-
###########################################################
## Commands for running gcc to compile a C++ file
###########################################################
-define transform-cpp-to-o
-@echo "target $(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"
-@mkdir -p $(dir $@)
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CXX) \
- $(addprefix -I , $(PRIVATE_C_INCLUDES)) \
- $(shell cat $(PRIVATE_IMPORT_INCLUDES)) \
- $(addprefix -isystem ,\
- $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
- $(filter-out $(PRIVATE_C_INCLUDES), \
- $(PRIVATE_TARGET_PROJECT_INCLUDES) \
- $(PRIVATE_TARGET_C_INCLUDES)))) \
+define transform-cpp-to-o-compiler-args
+ $(c-includes) \
-c \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_TARGET_GLOBAL_CFLAGS) \
@@ -1226,59 +1224,86 @@
$(PRIVATE_CPPFLAGS) \
$(PRIVATE_DEBUG_CFLAGS) \
$(PRIVATE_CFLAGS_NO_OVERRIDE) \
- $(PRIVATE_CPPFLAGS_NO_OVERRIDE) \
- -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
-$(transform-d-to-p)
+ $(PRIVATE_CPPFLAGS_NO_OVERRIDE)
endef
+define clang-tidy-cpp
+$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
+ -checks=$(PRIVATE_TIDY_CHECKS) \
+ $< -- $(transform-cpp-to-o-compiler-args)
+endef
+
+ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
+define transform-cpp-to-o
+$(if $(PRIVATE_TIDY_CHECKS),
+ @echo "$($(PRIVATE_PREFIX)DISPLAY) tidy $(PRIVATE_ARM_MODE) C++: $<"
+ $(clang-tidy-cpp))
+endef
+else
+define transform-cpp-to-o
+@echo "$($(PRIVATE_PREFIX)DISPLAY) $(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"
+@mkdir -p $(dir $@)
+$(if $(PRIVATE_TIDY_CHECKS),$(clang-tidy-cpp))
+$(hide) $(RELATIVE_PWD) $(PRIVATE_CXX) \
+ $(transform-cpp-to-o-compiler-args) \
+ -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
+endef
+endif
+
###########################################################
## Commands for running gcc to compile a C file
###########################################################
# $(1): extra flags
-define transform-c-or-s-to-o-no-deps
-@mkdir -p $(dir $@)
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
- $(addprefix -I , $(PRIVATE_C_INCLUDES)) \
- $(shell cat $(PRIVATE_IMPORT_INCLUDES)) \
- $(addprefix -isystem ,\
- $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
- $(filter-out $(PRIVATE_C_INCLUDES), \
- $(PRIVATE_TARGET_PROJECT_INCLUDES) \
- $(PRIVATE_TARGET_C_INCLUDES)))) \
+define transform-c-or-s-to-o-compiler-args
+ $(c-includes) \
-c \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_TARGET_GLOBAL_CFLAGS) \
$(PRIVATE_TARGET_GLOBAL_CONLYFLAGS) \
$(PRIVATE_ARM_CFLAGS) \
) \
- $(1) \
- -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
+ $(1)
endef
-define transform-c-to-o-no-deps
-@echo "target $(PRIVATE_ARM_MODE) C: $(PRIVATE_MODULE) <= $<"
-$(call transform-c-or-s-to-o-no-deps, \
- $(PRIVATE_CFLAGS) \
- $(PRIVATE_CONLYFLAGS) \
- $(PRIVATE_DEBUG_CFLAGS) \
- $(PRIVATE_CFLAGS_NO_OVERRIDE))
+define transform-c-to-o-compiler-args
+$(call transform-c-or-s-to-o-compiler-args, \
+ $(PRIVATE_CFLAGS) \
+ $(PRIVATE_CONLYFLAGS) \
+ $(PRIVATE_DEBUG_CFLAGS) \
+ $(PRIVATE_CFLAGS_NO_OVERRIDE))
endef
-define transform-s-to-o-no-deps
-@echo "target asm: $(PRIVATE_MODULE) <= $<"
-$(call transform-c-or-s-to-o-no-deps, $(PRIVATE_ASFLAGS))
+define clang-tidy-c
+$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
+ -checks=$(PRIVATE_TIDY_CHECKS) \
+ $< -- $(transform-c-to-o-compiler-args)
endef
+ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
define transform-c-to-o
-$(transform-c-to-o-no-deps)
-$(transform-d-to-p)
+$(if $(PRIVATE_TIDY_CHECKS),
+ @echo "$($(PRIVATE_PREFIX)DISPLAY) tidy $(PRIVATE_ARM_MODE) C: $<"
+ $(clang-tidy-c))
endef
+else
+define transform-c-to-o
+@echo "$($(PRIVATE_PREFIX)DISPLAY) $(PRIVATE_ARM_MODE) C: $(PRIVATE_MODULE) <= $<"
+@mkdir -p $(dir $@)
+$(if $(PRIVATE_TIDY_CHECKS),$(clang-tidy-c))
+$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
+ $(transform-c-to-o-compiler-args) \
+ -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
+endef
+endif
define transform-s-to-o
-$(transform-s-to-o-no-deps)
-$(transform-d-to-p)
+@echo "$($(PRIVATE_PREFIX)DISPLAY) asm: $(PRIVATE_MODULE) <= $<"
+@mkdir -p $(dir $@)
+$(RELATIVE_PWD) $(PRIVATE_CC) \
+ $(call transform-c-or-s-to-o-compiler-args, $(PRIVATE_ASFLAGS)) \
+ -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
endef
# YASM compilation
@@ -1297,31 +1322,17 @@
## will error at build time.
###########################################################
-define transform-m-to-o-no-deps
-@echo "target ObjC: $(PRIVATE_MODULE) <= $<"
-$(call transform-c-or-s-to-o-no-deps, $(PRIVATE_CFLAGS) $(PRIVATE_DEBUG_CFLAGS))
-endef
-
define transform-m-to-o
-$(transform-m-to-o-no-deps)
-$(transform-d-to-p)
+@echo "$($(PRIVATE_PREFIX)DISPLAY) ObjC: $(PRIVATE_MODULE) <= $<"
+$(call transform-c-or-s-to-o, $(PRIVATE_CFLAGS) $(PRIVATE_DEBUG_CFLAGS))
endef
###########################################################
## Commands for running gcc to compile a host C++ file
###########################################################
-define transform-host-cpp-to-o
-@echo "$($(PRIVATE_PREFIX)DISPLAY) C++: $(PRIVATE_MODULE) <= $<"
-@mkdir -p $(dir $@)
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CXX) \
- $(addprefix -I , $(PRIVATE_C_INCLUDES)) \
- $(shell cat $(PRIVATE_IMPORT_INCLUDES)) \
- $(addprefix -isystem ,\
- $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
- $(filter-out $(PRIVATE_C_INCLUDES), \
- $($(PRIVATE_PREFIX)PROJECT_INCLUDES) \
- $(PRIVATE_HOST_C_INCLUDES)))) \
+define transform-host-cpp-to-o-compiler-args
+ $(c-includes) \
-c \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_HOST_GLOBAL_CFLAGS) \
@@ -1331,69 +1342,96 @@
$(PRIVATE_CPPFLAGS) \
$(PRIVATE_DEBUG_CFLAGS) \
$(PRIVATE_CFLAGS_NO_OVERRIDE) \
- $(PRIVATE_CPPFLAGS_NO_OVERRIDE) \
- -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
-$(transform-d-to-p)
+ $(PRIVATE_CPPFLAGS_NO_OVERRIDE)
endef
+define clang-tidy-host-cpp
+$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
+ -checks=$(PRIVATE_TIDY_CHECKS) \
+ $< -- $(transform-host-cpp-to-o-compiler-args)
+endef
+
+ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
+define transform-host-cpp-to-o
+$(if $(PRIVATE_TIDY_CHECKS),
+ @echo "tidy $($(PRIVATE_PREFIX)DISPLAY) C++: $<"
+ $(clang-tidy-host-cpp))
+endef
+else
+define transform-host-cpp-to-o
+@echo "$($(PRIVATE_PREFIX)DISPLAY) C++: $(PRIVATE_MODULE) <= $<"
+@mkdir -p $(dir $@)
+$(if $(PRIVATE_TIDY_CHECKS),$(clang-tidy-host-cpp))
+$(hide) $(RELATIVE_PWD) $(PRIVATE_CXX) \
+ $(transform-host-cpp-to-o-compiler-args) \
+ -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
+endef
+endif
+
###########################################################
## Commands for running gcc to compile a host C file
###########################################################
-# $(1): extra flags
-define transform-host-c-or-s-to-o-no-deps
-@mkdir -p $(dir $@)
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
- $(addprefix -I , $(PRIVATE_C_INCLUDES)) \
- $(shell cat $(PRIVATE_IMPORT_INCLUDES)) \
- $(addprefix -isystem ,\
- $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
- $(filter-out $(PRIVATE_C_INCLUDES), \
- $($(PRIVATE_PREFIX)PROJECT_INCLUDES) \
- $(PRIVATE_HOST_C_INCLUDES)))) \
+define transform-host-c-or-s-to-o-common-args
+ $(c-includes) \
-c \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_HOST_GLOBAL_CFLAGS) \
$(PRIVATE_HOST_GLOBAL_CONLYFLAGS) \
- ) \
- $(1) \
- $(PRIVATE_CFLAGS_NO_OVERRIDE) \
- -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
+ )
endef
-define transform-host-c-to-o-no-deps
-@echo "$($(PRIVATE_PREFIX)DISPLAY) C: $(PRIVATE_MODULE) <= $<"
-$(call transform-host-c-or-s-to-o-no-deps, $(PRIVATE_CFLAGS) $(PRIVATE_CONLYFLAGS) $(PRIVATE_DEBUG_CFLAGS))
+# $(1): extra flags
+define transform-host-c-or-s-to-o
+@mkdir -p $(dir $@)
+$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
+ $(transform-host-c-or-s-to-o-common-args) \
+ $(1) \
+ -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
endef
-define transform-host-s-to-o-no-deps
-@echo "$($(PRIVATE_PREFIX)DISPLAY) asm: $(PRIVATE_MODULE) <= $<"
-$(call transform-host-c-or-s-to-o-no-deps, $(PRIVATE_ASFLAGS))
+define transform-host-c-to-o-compiler-args
+ $(transform-host-c-or-s-to-o-common-args) \
+ $(PRIVATE_CFLAGS) $(PRIVATE_CONLYFLAGS) \
+ $(PRIVATE_DEBUG_CFLAGS) $(PRIVATE_CFLAGS_NO_OVERRIDE)
endef
+define clang-tidy-host-c
+$(hide) $(PATH_TO_CLANG_TIDY) $(PRIVATE_TIDY_FLAGS) \
+ -checks=$(PRIVATE_TIDY_CHECKS) \
+ $< -- $(transform-host-c-to-o-compiler-args)
+endef
+
+ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
define transform-host-c-to-o
-$(transform-host-c-to-o-no-deps)
-$(transform-d-to-p)
+$(if $(PRIVATE_TIDY_CHECKS),
+ @echo "tidy $($(PRIVATE_PREFIX)DISPLAY) C: $<"
+ $(clang-tidy-host-c))
endef
+else
+define transform-host-c-to-o
+@echo "$($(PRIVATE_PREFIX)DISPLAY) C: $(PRIVATE_MODULE) <= $<"
+@mkdir -p $(dir $@)
+$(if $(PRIVATE_TIDY_CHECKS), $(clang-tidy-host-c))
+$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
+ $(transform-host-c-to-o-compiler-args) \
+ -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
+endef
+endif
define transform-host-s-to-o
-$(transform-host-s-to-o-no-deps)
-$(transform-d-to-p)
+@echo "$($(PRIVATE_PREFIX)DISPLAY) asm: $(PRIVATE_MODULE) <= $<"
+$(call transform-host-c-or-s-to-o, $(PRIVATE_ASFLAGS))
endef
###########################################################
## Commands for running gcc to compile a host Objective-C file
###########################################################
-define transform-host-m-to-o-no-deps
-@echo "$($(PRIVATE_PREFIX)DISPLAY) ObjC: $(PRIVATE_MODULE) <= $<"
-$(call transform-host-c-or-s-to-o-no-deps, $(PRIVATE_CFLAGS) $(PRIVATE_DEBUG_CFLAGS))
-endef
-
define transform-host-m-to-o
-$(transform-host-m-to-o-no-deps)
-$(transform-d-to-p)
+@echo "$($(PRIVATE_PREFIX)DISPLAY) ObjC: $(PRIVATE_MODULE) <= $<"
+$(call transform-host-c-or-s-to-o, $(PRIVATE_CFLAGS) $(PRIVATE_DEBUG_CFLAGS) $(PRIVATE_CFLAGS_NO_OVERRIDE))
endef
###########################################################
@@ -1458,7 +1496,7 @@
define compile-dotdot-s-file-no-deps
o := $(intermediates)/$(patsubst %.s,%.o,$(subst ../,$(DOTDOT_REPLACEMENT),$(1)))
$$(o) : $(TOPDIR)$(LOCAL_PATH)/$(1) $(2)
- $$(transform-$$(PRIVATE_HOST)s-to-o-no-deps)
+ $$(transform-$$(PRIVATE_HOST)s-to-o)
$(3) += $$(o)
endef
@@ -1487,6 +1525,7 @@
endef
# $(1): the full path of the source static library.
+# $(2): the full path of the destination static library.
define _extract-and-include-single-target-whole-static-lib
$(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
rm -rf $$ldir; \
@@ -1508,32 +1547,119 @@
filelist="$$filelist $$ldir/$$ext$$f"; \
done ; \
$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \
- $(PRIVATE_ARFLAGS) $@ $$filelist
+ $(2) $$filelist
endef
# $(1): the full path of the source static library.
+# $(2): the full path of the destination static library.
define extract-and-include-whole-static-libs-first
$(if $(strip $(1)),
-$(hide) cp $(1) $@)
+$(hide) cp $(1) $(2))
endef
+# $(1): the full path of the destination static library.
define extract-and-include-target-whole-static-libs
-$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)))
+$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)),$(1))
$(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \
- $(call _extract-and-include-single-target-whole-static-lib, $(lib)))
+ $(call _extract-and-include-single-target-whole-static-lib, $(lib), $(1)))
endef
# Explicitly delete the archive first so that ar doesn't
# try to add to an existing archive.
define transform-o-to-static-lib
-@echo "target StaticLib: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
-@rm -f $@
-$(extract-and-include-target-whole-static-libs)
+@rm -f $@ $@.tmp
+$(call extract-and-include-target-whole-static-libs,$@.tmp)
$(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) \
$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \
- $(PRIVATE_ARFLAGS) $@,$(PRIVATE_ALL_OBJECTS))
+ $(PRIVATE_ARFLAGS) \
+ $@.tmp,$(PRIVATE_ALL_OBJECTS))
+$(hide) mv -f $@.tmp $@
+endef
+
+# $(1): the full path of the source static library.
+# $(2): the full path of the destination static library.
+define _extract-and-include-single-aux-whole-static-lib
+$(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
+ rm -rf $$ldir; \
+ mkdir -p $$ldir; \
+ cp $(1) $$ldir; \
+ lib_to_include=$$ldir/$(notdir $(1)); \
+ filelist=; \
+ subdir=0; \
+ for f in `$(PRIVATE_AR) t $(1)`; do \
+ if [ -e $$ldir/$$f ]; then \
+ mkdir $$ldir/$$subdir; \
+ ext=$$subdir/; \
+ subdir=$$((subdir+1)); \
+ $(PRIVATE_AR) m $$lib_to_include $$f; \
+ else \
+ ext=; \
+ fi; \
+ $(PRIVATE_AR) p $$lib_to_include $$f > $$ldir/$$ext$$f; \
+ filelist="$$filelist $$ldir/$$ext$$f"; \
+ done ; \
+ $(PRIVATE_AR) $(AUX_GLOBAL_ARFLAGS) $(2) $$filelist
+
+endef
+
+define extract-and-include-aux-whole-static-libs
+$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)),$(1))
+$(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \
+ $(call _extract-and-include-single-aux-whole-static-lib, $(lib), $(1)))
+endef
+
+# Explicitly delete the archive first so that ar doesn't
+# try to add to an existing archive.
+define transform-o-to-aux-static-lib
+@echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)"
+@mkdir -p $(dir $@)
+@rm -f $@ $@.tmp
+$(call extract-and-include-aux-whole-static-libs,$@.tmp)
+$(call split-long-arguments,$(PRIVATE_AR) \
+ $(AUX_GLOBAL_ARFLAGS) $@.tmp,$(PRIVATE_ALL_OBJECTS))
+$(hide) mv -f $@.tmp $@
+endef
+
+define transform-o-to-aux-executable-inner
+$(hide) $(PRIVATE_CXX) -pie \
+ -Bdynamic \
+ -Wl,--gc-sections \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
+ -Wl,--no-whole-archive \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
+ $(PRIVATE_LDFLAGS) \
+ -o $@
+endef
+
+define transform-o-to-aux-executable
+@echo "$(AUX_DISPLAY) Executable: $(PRIVATE_MODULE) ($@)"
+@mkdir -p $(dir $@)
+$(transform-o-to-aux-executable-inner)
+endef
+
+define transform-o-to-aux-static-executable-inner
+$(hide) $(PRIVATE_CXX) \
+ -Bstatic \
+ -Wl,--gc-sections \
+ $(PRIVATE_ALL_OBJECTS) \
+ -Wl,--whole-archive \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
+ -Wl,--no-whole-archive \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
+ $(PRIVATE_LDFLAGS) \
+ -Wl,-Map=$(@).map \
+ -o $@
+endef
+
+define transform-o-to-aux-static-executable
+@echo "$(AUX_DISPLAY) StaticExecutable: $(PRIVATE_MODULE) ($@)"
+@mkdir -p $(dir $@)
+$(transform-o-to-aux-static-executable-inner)
endef
###########################################################
@@ -1541,6 +1667,7 @@
###########################################################
# $(1): the full path of the source static library.
+# $(2): the full path of the destination static library.
define _extract-and-include-single-host-whole-static-lib
$(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
rm -rf $$ldir; \
@@ -1562,26 +1689,46 @@
filelist="$$filelist $$ldir/$$ext$$f"; \
done ; \
$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) \
- $(PRIVATE_ARFLAGS) $@ $$filelist
+ $(2) $$filelist
endef
define extract-and-include-host-whole-static-libs
-$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)))
+$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)),$(1))
$(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \
- $(call _extract-and-include-single-host-whole-static-lib, $(lib)))
+ $(call _extract-and-include-single-host-whole-static-lib, $(lib),$(1)))
endef
+ifeq ($(HOST_OS),darwin)
+# On Darwin the host ar fails if there is nothing to add to .a at all.
+# We work around by adding a dummy.o and then deleting it.
+define create-dummy.o-if-no-objs
+$(if $(PRIVATE_ALL_OBJECTS),,$(hide) touch $(dir $(1))dummy.o)
+endef
+
+define get-dummy.o-if-no-objs
+$(if $(PRIVATE_ALL_OBJECTS),,$(dir $(1))dummy.o)
+endef
+
+define delete-dummy.o-if-no-objs
+$(if $(PRIVATE_ALL_OBJECTS),,$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) d $(1) $(dir $(1))dummy.o \
+ && rm -f $(dir $(1))dummy.o)
+endef
+endif # HOST_OS is darwin
+
# Explicitly delete the archive first so that ar doesn't
# try to add to an existing archive.
define transform-host-o-to-static-lib
@echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
-@rm -f $@
-$(extract-and-include-host-whole-static-libs)
+@rm -f $@ $@.tmp
+$(call extract-and-include-host-whole-static-libs,$@.tmp)
+$(call create-dummy.o-if-no-objs,$@.tmp)
$(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) \
- $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) \
- $(PRIVATE_ARFLAGS) $@,$(PRIVATE_ALL_OBJECTS))
+ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) $@.tmp,\
+ $(PRIVATE_ALL_OBJECTS) $(call get-dummy.o-if-no-objs,$@.tmp))
+$(call delete-dummy.o-if-no-objs,$@.tmp)
+$(hide) mv -f $@.tmp $@
endef
@@ -1598,21 +1745,20 @@
-Wl,-rpath,\$$ORIGIN/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
-Wl,-rpath,\$$ORIGIN/$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
-shared -Wl,-soname,$(notdir $@) \
- $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_LD_DIRS) \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_HOST_GLOBAL_LDFLAGS) \
) \
$(PRIVATE_LDFLAGS) \
$(PRIVATE_ALL_OBJECTS) \
-Wl,--whole-archive \
- $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
-Wl,--no-whole-archive \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
$(if $(filter true,$(NATIVE_COVERAGE)),-lgcov) \
$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_HOST_LIBPROFILE_RT)) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(PRIVATE_ALL_SHARED_LIBRARIES) \
-o $@ \
$(PRIVATE_LDLIBS)
endef
@@ -1640,28 +1786,27 @@
-nostdlib -Wl,-soname,$(notdir $@) \
-Wl,--gc-sections \
$(if $(filter true,$(PRIVATE_CLANG)),-shared,-Wl$(comma)-shared) \
- $(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
$(PRIVATE_TARGET_CRTBEGIN_SO_O) \
$(PRIVATE_ALL_OBJECTS) \
-Wl,--whole-archive \
- $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
-Wl,--no-whole-archive \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
- $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_COVERAGE_LIB)) \
$(PRIVATE_TARGET_LIBATOMIC) \
$(PRIVATE_TARGET_LIBGCC) \
- $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
- -o $@ \
$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
$(PRIVATE_LDFLAGS) \
+ $(PRIVATE_ALL_SHARED_LIBRARIES) \
+ -o $@ \
$(PRIVATE_TARGET_CRTEND_SO_O) \
$(PRIVATE_LDLIBS)
endef
define transform-o-to-shared-lib
-@echo "target SharedLib: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) SharedLib: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
$(transform-o-to-shared-lib-inner)
endef
@@ -1676,14 +1821,34 @@
endif
define transform-to-stripped
-@echo "target Strip: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Strip: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
$(hide) $(PRIVATE_STRIP) --strip-all $< -o $@ \
$(if $(PRIVATE_NO_DEBUGLINK),,$(TARGET_STRIP_EXTRA))
endef
+define transform-to-stripped-keep-mini-debug-info
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Strip (mini debug info): $(PRIVATE_MODULE) ($@)"
+@mkdir -p $(dir $@)
+$(hide) rm -f $@ $@.dynsyms $@.funcsyms $@.keep_symbols $@.debug $@.mini_debuginfo.xz
+if $(PRIVATE_STRIP) --strip-all -R .comment $< -o $@; then \
+ $(PRIVATE_OBJCOPY) --only-keep-debug $< $@.debug && \
+ $(PRIVATE_NM) -D $< --format=posix --defined-only | awk '{ print $$1 }' | sort >$@.dynsyms && \
+ $(PRIVATE_NM) $< --format=posix --defined-only | awk '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' | sort >$@.funcsyms && \
+ comm -13 $@.dynsyms $@.funcsyms >$@.keep_symbols && \
+ $(PRIVATE_OBJCOPY) --rename-section .debug_frame=saved_debug_frame $@.debug $@.mini_debuginfo && \
+ $(PRIVATE_OBJCOPY) -S --remove-section .gdb_index --remove-section .comment --keep-symbols=$@.keep_symbols $@.mini_debuginfo && \
+ $(PRIVATE_OBJCOPY) --rename-section saved_debug_frame=.debug_frame $@.mini_debuginfo && \
+ rm -f $@.mini_debuginfo.xz && \
+ xz $@.mini_debuginfo && \
+ $(PRIVATE_OBJCOPY) --add-section .gnu_debugdata=$@.mini_debuginfo.xz $@; \
+else \
+ cp -f $< $@; \
+fi
+endef
+
define transform-to-stripped-keep-symbols
-@echo "target Strip (keep symbols): $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Strip (keep symbols): $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
$(hide) $(PRIVATE_OBJCOPY) \
`$(PRIVATE_READELF) -S $< | awk '/.debug_/ {print "-R " $$2}' | xargs` \
@@ -1695,7 +1860,7 @@
###########################################################
define pack-elf-relocations
-@echo "target Pack Relocations: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Pack Relocations: $(PRIVATE_MODULE) ($@)"
$(copy-file-to-target)
$(hide) $(RELOCATION_PACKER) $@
endef
@@ -1710,29 +1875,28 @@
-Wl,-dynamic-linker,$(PRIVATE_LINKER) \
-Wl,--gc-sections \
-Wl,-z,nocopyreloc \
- $(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
-Wl,-rpath-link=$(PRIVATE_TARGET_OUT_INTERMEDIATE_LIBRARIES) \
$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O) \
$(PRIVATE_ALL_OBJECTS) \
-Wl,--whole-archive \
- $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
-Wl,--no-whole-archive \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
- $(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_COVERAGE_LIB)) \
$(PRIVATE_TARGET_LIBATOMIC) \
$(PRIVATE_TARGET_LIBGCC) \
- $(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
- -o $@ \
$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
$(PRIVATE_LDFLAGS) \
+ $(PRIVATE_ALL_SHARED_LIBRARIES) \
+ -o $@ \
$(PRIVATE_TARGET_CRTEND_O) \
$(PRIVATE_LDLIBS)
endef
define transform-o-to-executable
-@echo "target Executable: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Executable: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
$(transform-o-to-executable-inner)
endef
@@ -1754,28 +1918,27 @@
$(if $(filter $(PRIVATE_LDFLAGS),-shared),,-static) \
-Wl,--gc-sections \
-o $@ \
- $(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
$(PRIVATE_TARGET_CRTBEGIN_STATIC_O) \
$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
$(PRIVATE_LDFLAGS) \
$(PRIVATE_ALL_OBJECTS) \
-Wl,--whole-archive \
- $(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
-Wl,--no-whole-archive \
- $(call normalize-target-libraries,$(filter-out %libcompiler_rt.a,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))))) \
+ $(filter-out %libcompiler_rt.a,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
-Wl,--start-group \
- $(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
- $(call normalize-target-libraries,$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
+ $(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_COVERAGE_LIB)) \
$(PRIVATE_TARGET_LIBATOMIC) \
- $(call normalize-target-libraries,$(filter %libcompiler_rt.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
+ $(filter %libcompiler_rt.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
$(PRIVATE_TARGET_LIBGCC) \
-Wl,--end-group \
$(PRIVATE_TARGET_CRTEND_O)
endef
define transform-o-to-static-executable
-@echo "target StaticExecutable: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) StaticExecutable: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
$(transform-o-to-static-executable-inner)
endef
@@ -1799,18 +1962,17 @@
$(hide) $(PRIVATE_CXX) \
$(PRIVATE_ALL_OBJECTS) \
-Wl,--whole-archive \
- $(call normalize-host-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
-Wl,--no-whole-archive \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+ $(PRIVATE_ALL_STATIC_LIBRARIES) \
$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
$(if $(filter true,$(NATIVE_COVERAGE)),-lgcov) \
$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_HOST_LIBPROFILE_RT)) \
- $(call normalize-host-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+ $(PRIVATE_ALL_SHARED_LIBRARIES) \
-Wl,-rpath-link=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_INTERMEDIATE_LIBRARIES) \
- -Wl,-rpath,\$$ORIGIN/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
- -Wl,-rpath,\$$ORIGIN/$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
- $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_LD_DIRS) \
+ $(foreach path,$(PRIVATE_RPATHS), \
+ -Wl,-rpath,\$$ORIGIN/$(path)) \
$(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
$(PRIVATE_HOST_GLOBAL_LDFLAGS) \
) \
@@ -1842,6 +2004,9 @@
APPS_DEFAULT_VERSION_NAME := $(PLATFORM_VERSION)
endif
+# b/37750224
+AAPT_ASAN_OPTIONS := ASAN_OPTIONS=detect_leaks=0
+
# TODO: Right now we generate the asset resources twice, first as part
# of generating the Java classes, then at the end when packaging the final
# assets. This should be changed to do one of two things: (1) Don't generate
@@ -1856,7 +2021,7 @@
define create-resource-java-files
@mkdir -p $(PRIVATE_SOURCE_INTERMEDIATES_DIR)
@mkdir -p $(dir $(PRIVATE_RESOURCE_PUBLICS_OUTPUT))
-$(hide) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m \
+$(hide) $(AAPT_ASAN_OPTIONS) $(AAPT) package $(PRIVATE_AAPT_FLAGS) -m \
$(eval # PRIVATE_PRODUCT_AAPT_CONFIG is intentionally missing-- see comment.) \
$(addprefix -J , $(PRIVATE_SOURCE_INTERMEDIATES_DIR)) \
$(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
@@ -2033,24 +2198,28 @@
# $(2): bootclasspath
define compile-java
$(hide) rm -f $@
-$(hide) rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR)
+$(hide) rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) $(PRIVATE_ANNO_INTERMEDIATES_DIR)
$(hide) mkdir -p $(dir $@)
-$(hide) mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR)
+$(hide) mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR) $(PRIVATE_ANNO_INTERMEDIATES_DIR)
$(call unzip-jar-files,$(PRIVATE_STATIC_JAVA_LIBRARIES),$(PRIVATE_CLASS_INTERMEDIATES_DIR))
$(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list)
$(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' -and -not -name '.*' >> $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list; \
fi
+$(if $(PRIVATE_HAS_PROTO_SOURCES), \
+ $(hide) find $(PRIVATE_PROTO_SOURCE_INTERMEDIATES_DIR) -name '*.java' -and -not -name '.*' >> $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list )
+$(if $(PRIVATE_HAS_RS_SOURCES), \
+ $(hide) find $(PRIVATE_RS_SOURCE_INTERMEDIATES_DIR) -name '*.java' -and -not -name '.*' >> $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list )
$(hide) tr ' ' '\n' < $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list \
| $(NORMALIZE_PATH) | sort -u > $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq
$(hide) if [ -s $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq ] ; then \
- $(1) -encoding UTF-8 \
+ $(SOONG_JAVAC_WRAPPER) $(1) -encoding UTF-8 \
$(if $(findstring true,$(PRIVATE_WARNINGS_ENABLE)),$(xlint_unchecked),) \
$(2) \
$(addprefix -classpath ,$(strip \
$(call normalize-path-list,$(PRIVATE_ALL_JAVA_LIBRARIES)))) \
$(if $(findstring true,$(PRIVATE_WARNINGS_ENABLE)),$(xlint_unchecked),) \
- -extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR) \
+ -extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR) -s $(PRIVATE_ANNO_INTERMEDIATES_DIR) \
$(PRIVATE_JAVACFLAGS) \
\@$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq \
|| ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 ) \
@@ -2071,7 +2240,6 @@
$(if $(PRIVATE_JAR_EXCLUDE_PACKAGES), $(hide) rm -rf \
$(foreach pkg, $(PRIVATE_JAR_EXCLUDE_PACKAGES), \
$(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))))
-$(if $(PRIVATE_RMTYPEDEFS), $(hide) $(RMTYPEDEFS) -v $(PRIVATE_CLASS_INTERMEDIATES_DIR))
$(if $(PRIVATE_JAR_MANIFEST), \
$(hide) sed -e "s/%BUILD_NUMBER%/$(BUILD_NUMBER_FROM_FILE)/" \
$(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf && \
@@ -2082,7 +2250,7 @@
endef
define transform-java-to-classes.jar
-@echo "target Java: $(PRIVATE_MODULE) ($(PRIVATE_CLASS_INTERMEDIATES_DIR))"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Java: $(PRIVATE_MODULE) ($(PRIVATE_CLASS_INTERMEDIATES_DIR))"
$(call compile-java,$(TARGET_JAVAC),$(PRIVATE_BOOTCLASSPATH))
endef
@@ -2101,9 +2269,14 @@
$(hide) mkdir -p $(PRIVATE_JACK_INTERMEDIATES_DIR)
$(if $(PRIVATE_JACK_INCREMENTAL_DIR),$(hide) mkdir -p $(PRIVATE_JACK_INCREMENTAL_DIR))
$(call dump-words-to-file,$(PRIVATE_JAVA_SOURCES),$(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list)
-$(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
- find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list; \
-fi
+$(if $(PRIVATE_SOURCE_INTERMEDIATES_DIR), \
+ $(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
+ find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list; \
+ fi)
+$(if $(PRIVATE_HAS_PROTO_SOURCES), \
+ $(hide) find $(PRIVATE_PROTO_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list )
+$(if $(PRIVATE_HAS_RS_SOURCES), \
+ $(hide) find $(PRIVATE_RS_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list )
$(hide) tr ' ' '\n' < $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list \
| $(NORMALIZE_PATH) | sort -u > $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq
$(if $(PRIVATE_JACK_PROGUARD_FLAGS), \
@@ -2116,6 +2289,10 @@
$(hide) $(call add-java-resources-to,$@.res.tmp.zip)
$(hide) unzip -qo $@.res.tmp.zip -d $@.res.tmp
$(hide) rm $@.res.tmp.zip)
+$(if $(PRIVATE_JACK_IMPORT_JAR),
+ $(hide) mkdir -p $@.tmpjill.res
+ $(hide) unzip -qo $(PRIVATE_JACK_IMPORT_JAR) -d $@.tmpjill.res
+ $(hide) find $@.tmpjill.res -iname "*.class" -delete)
$(hide) if [ -s $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq ] ; then \
export tmpEcjArg="@$(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq"; \
else \
@@ -2128,9 +2305,14 @@
-D jack.dex.optimize="false") \
$(if $(PRIVATE_RMTYPEDEFS), \
-D jack.android.remove-typedef="true") \
+ $(if $(PRIVATE_JACK_IMPORT_JAR), \
+ --import $(PRIVATE_JACK_IMPORT_JAR) --import-resource $@.tmpjill.res) \
$(addprefix --classpath ,$(strip \
- $(call normalize-path-list,$(PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES) $(PRIVATE_ALL_JACK_LIBRARIES)))) \
+ $(call normalize-path-list,$(PRIVATE_JACK_SHARED_LIBRARIES)))) \
$(addprefix --import ,$(call reverse-list,$(PRIVATE_STATIC_JACK_LIBRARIES))) \
+ $(addprefix --pluginpath ,$(strip \
+ $(call normalize-path-list,$(PRIVATE_JACK_PLUGIN_PATH)))) \
+ $(if $(PRIVATE_JACK_PLUGIN),--plugin $(call normalize-comma-list,$(PRIVATE_JACK_PLUGIN))) \
$(if $(PRIVATE_EXTRA_JAR_ARGS),--import-resource $@.res.tmp) \
-D jack.android.min-api-level=$(PRIVATE_JACK_MIN_SDK_VERSION) \
-D jack.import.resource.policy=keep-first \
@@ -2167,6 +2349,10 @@
$(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $@.java-source-list; \
fi
+$(if $(PRIVATE_HAS_PROTO_SOURCES), \
+ $(hide) find $(PRIVATE_PROTO_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $@.java-source-list )
+$(if $(PRIVATE_HAS_RS_SOURCES), \
+ $(hide) find $(PRIVATE_RS_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $@.java-source-list )
$(hide) tr ' ' '\n' < $@.java-source-list \
| sort -u > $@.java-source-list-uniq
$(hide) if [ -s $@.java-source-list-uniq ] ; then \
@@ -2174,7 +2360,7 @@
$(strip $(PRIVATE_JACK_FLAGS)) \
$(strip $(PRIVATE_JACK_DEBUG_FLAGS)) \
$(addprefix --classpath ,$(strip \
- $(call normalize-path-list,$(call reverse-list,$(PRIVATE_STATIC_JACK_LIBRARIES)) $(PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES) $(PRIVATE_ALL_JACK_LIBRARIES)))) \
+ $(call normalize-path-list,$(call reverse-list,$(PRIVATE_STATIC_JACK_LIBRARIES)) $(PRIVATE_JACK_SHARED_LIBRARIES)))) \
-D jack.import.resource.policy=keep-first \
-D jack.android.min-api-level=$(PRIVATE_JACK_MIN_SDK_VERSION) \
-D jack.import.type.policy=keep-first \
@@ -2191,6 +2377,9 @@
$(hide) find $@.tmpjill.res -iname "*.class" -delete
$(hide) $(call call-jack) \
$(PRIVATE_JACK_FLAGS) \
+ $(addprefix --pluginpath ,$(strip \
+ $(call normalize-path-list,$(PRIVATE_JACK_PLUGIN_PATH)))) \
+ $(if $(PRIVATE_JACK_PLUGIN),--plugin $(call normalize-comma-list,$(PRIVATE_JACK_PLUGIN))) \
-D jack.import.resource.policy=keep-first \
-D jack.import.type.policy=keep-first \
-D jack.android.min-api-level=$(PRIVATE_JACK_MIN_SDK_VERSION) \
@@ -2203,9 +2392,7 @@
# Moves $1.tmp to $1 if necessary. This is designed to be used with
# .KATI_RESTAT. For kati, this function doesn't update the timestamp
# of $1 when $1.tmp is identical to $1 so that ninja won't rebuild
-# targets which depend on $1. For GNU make, this function simply
-# copies $1.tmp to $1.
-ifeq ($(BUILDING_WITH_NINJA),true)
+# targets which depend on $1.
define commit-change-for-toc
$(hide) if cmp -s $1.tmp $1 ; then \
rm $1.tmp ; \
@@ -2213,12 +2400,9 @@
mv $1.tmp $1 ; \
fi
endef
-else
-define commit-change-for-toc
-@# make doesn't support restat. We always update .toc files so the dependents will always be updated too.
-$(hide) mv $1.tmp $1
-endef
-endif
+
+# b/37756495
+IJAR_ASAN_OPTIONS := ASAN_OPTIONS=detect_leaks=0
## Rule to create a table of contents from a .jar file.
## Must be called with $(eval).
@@ -2226,7 +2410,7 @@
define _transform-jar-to-toc
$1.toc: $1 | $(IJAR)
@echo Generating TOC: $$@
- $(hide) $(IJAR) $$< $$@.tmp
+ $(hide) $(IJAR_ASAN_OPTIONS) $(IJAR) $$< $$@.tmp
$$(call commit-change-for-toc,$$@)
endef
@@ -2246,7 +2430,7 @@
$1/classes.dex.toc: PRIVATE_INPUT_DEX_FILES := $1/classes*.dex
$1/classes.dex.toc: $1/classes.dex $(DEXDUMP)
@echo Generating TOC: $$@
- $(hide) $(DEXDUMP) -l xml $$(PRIVATE_INPUT_DEX_FILES) > $$@.tmp
+ $(hide) ANDROID_LOG_TAGS="*:e" $(DEXDUMP) -l xml $$(PRIVATE_INPUT_DEX_FILES) > $$@.tmp
$$(call commit-change-for-toc,$$@)
endef
@@ -2282,6 +2466,10 @@
$(hide) if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \
find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list; \
fi
+$(if $(PRIVATE_HAS_PROTO_SOURCES), \
+ $(hide) find $(PRIVATE_PROTO_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list )
+$(if $(PRIVATE_HAS_RS_SOURCES), \
+ $(hide) find $(PRIVATE_RS_SOURCE_INTERMEDIATES_DIR) -name '*.java' >> $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list )
$(hide) tr ' ' '\n' < $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list \
| $(NORMALIZE_PATH) | sort -u > $(PRIVATE_JACK_INTERMEDIATES_DIR)/java-source-list-uniq
$(if $(PRIVATE_JACK_PROGUARD_FLAGS), \
@@ -2304,8 +2492,11 @@
$(if $(NO_OPTIMIZE_DX), \
-D jack.dex.optimize="false") \
$(addprefix --classpath ,$(strip \
- $(call normalize-path-list,$(PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES) $(PRIVATE_ALL_JACK_LIBRARIES)))) \
+ $(call normalize-path-list,$(PRIVATE_JACK_SHARED_LIBRARIES)))) \
$(addprefix --import ,$(call reverse-list,$(PRIVATE_STATIC_JACK_LIBRARIES))) \
+ $(addprefix --pluginpath ,$(strip \
+ $(call normalize-path-list,$(PRIVATE_JACK_PLUGIN_PATH)))) \
+ $(if $(PRIVATE_JACK_PLUGIN),--plugin $(call normalize-comma-list,$(PRIVATE_JACK_PLUGIN))) \
$(if $(PRIVATE_EXTRA_JAR_ARGS),--import-resource $@.res.tmp) \
-D jack.import.resource.policy=keep-first \
-D jack.import.type.policy=keep-first \
@@ -2330,6 +2521,55 @@
$(addprefix -ix , $(PRIVATE_EMMA_COVERAGE_FILTER))
endef
+define desugar-classpath
+$(filter-out -classpath -bootclasspath "",$(subst :,$(space),$(1)))
+endef
+
+# Takes an sdk version that might be PLATFORM_VERSION_CODENAME (for example P),
+# returns a number greater than the highest existing sdk version if it is, or
+# the input if it is not.
+define codename-or-sdk-to-sdk
+$(if $(filter $(1),$(PLATFORM_VERSION_CODENAME)),10000,$(1))
+endef
+
+# --add-opens is required because desugar reflects via java.lang.invoke.MethodHandles.Lookup
+define desugar-classes-jar
+@echo Desugar: $@
+@mkdir -p $(dir $@)
+$(hide) rm -f $@ $@.tmp
+@rm -rf $(dir $@)/desugar_dumped_classes
+@mkdir $(dir $@)/desugar_dumped_classes
+$(hide) java \
+ $(if $(EXPERIMENTAL_USE_OPENJDK9),--add-opens java.base/java.lang.invoke=ALL-UNNAMED,) \
+ -Djdk.internal.lambda.dumpProxyClasses=$(abspath $(dir $@))/desugar_dumped_classes \
+ -jar $(DESUGAR) \
+ $(addprefix --bootclasspath_entry ,$(call desugar-bootclasspath,$(PRIVATE_BOOTCLASSPATH))) \
+ $(addprefix --classpath_entry ,$(PRIVATE_ALL_JAVA_LIBRARIES)) \
+ --min_sdk_version $(call codename-or-sdk-to-sdk,$(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
+ --allow_empty_bootclasspath \
+ $(if $(filter --core-library,$(PRIVATE_DX_FLAGS)),--core_library) \
+ -i $< -o $@.tmp
+ mv $@.tmp $@
+endef
+
+
+define transform-classes.jar-to-dex
+@echo "target Dex: $(PRIVATE_MODULE)"
+@mkdir -p $(dir $@)
+$(hide) rm -f $(dir $@)classes*.dex
+$(hide) $(DX_COMMAND) \
+ --dex --output=$(dir $@) \
+ --min-sdk-version=$(call codename-or-sdk-to-sdk,$(PRIVATE_DEFAULT_APP_TARGET_SDK)) \
+ $(if $(NO_OPTIMIZE_DX), \
+ --no-optimize) \
+ $(if $(GENERATE_DEX_DEBUG), \
+ --debug --verbose \
+ --dump-to=$(@:.dex=.lst) \
+ --dump-width=1000) \
+ $(PRIVATE_DX_FLAGS) \
+ $<
+endef
+
# Create a mostly-empty .jar file that we'll add to later.
# The MacOS jar tool doesn't like creating empty jar files,
# so we need to give it something.
@@ -2370,7 +2610,7 @@
#values; applications can override these by explicitly stating
#them in their manifest.
define add-assets-to-package
-$(hide) $(AAPT) package -u $(PRIVATE_AAPT_FLAGS) \
+$(hide) $(AAPT_ASAN_OPTIONS) $(AAPT) package -u $(PRIVATE_AAPT_FLAGS) \
$(addprefix -c , $(PRIVATE_PRODUCT_AAPT_CONFIG)) \
$(addprefix --preferred-density , $(PRIVATE_PRODUCT_AAPT_PREF_CONFIG)) \
$(addprefix -M , $(PRIVATE_ANDROID_MANIFEST)) \
@@ -2448,32 +2688,20 @@
fi
endef
-# Returns the minSdkVersion of the specified APK as a decimal number. If the
-# version is a codename, returns the current platform SDK version (always a
-# decimal number) instead. If the APK does not specify a minSdkVersion, returns
-# 0 to match how the Android platform interprets this situation at runtime.
-#
-# This currently substitutes any version which contains characters other than
-# digits with the current platform's API Level number. This is because I
-# couldn't figure out an easy way to perform the substitution only for the
-# version codes listed in PLATFORM_VERSION_ALL_CODENAMES.
-define get-package-min-sdk-version-int
-$$(($(AAPT) dump badging $(1) 2>&1 | grep '^sdkVersion' || echo "sdkVersion:'0'") \
- | cut -d"'" -f2 | \
- sed -e s/^.*[^0-9].*$$/$(PLATFORM_SDK_VERSION)/)
-endef
-
# Sign a package using the specified key/cert.
#
define sign-package
$(call sign-package-arg,$@)
endef
+# signapk uses internal APIs from sun.security.{pkcs,x509}; see http://b/37137869
# $(1): the package file we are signing.
define sign-package-arg
$(hide) mv $(1) $(1).unsigned
-$(hide) java -Djava.library.path=$(SIGNAPK_JNI_LIBRARY_PATH) -jar $(SIGNAPK_JAR) \
- --min-sdk-version $(call get-package-min-sdk-version-int,$@.unsigned) \
+$(hide) java -Djava.library.path=$(SIGNAPK_JNI_LIBRARY_PATH) \
+ $(if $(EXPERIMENTAL_USE_OPENJDK9),--add-exports java.base/sun.security.pkcs=ALL-UNNAMED,) \
+ $(if $(EXPERIMENTAL_USE_OPENJDK9),--add-exports java.base/sun.security.x509=ALL-UNNAMED,) \
+ -jar $(SIGNAPK_JAR) \
$(PRIVATE_CERTIFICATE) $(PRIVATE_PRIVATE_KEY) \
$(PRIVATE_ADDITIONAL_CERTIFICATES) $(1).unsigned $(1).signed
$(hide) mv $(1).signed $(1)
@@ -2495,11 +2723,9 @@
# Remove dynamic timestamps from packages
#
-ifndef TARGET_BUILD_APPS
define remove-timestamps-from-package
$(hide) $(ZIPTIME) $@
endef
-endif
# Uncompress shared libraries embedded in an apk.
#
@@ -2513,19 +2739,6 @@
fi
endef
-define install-dex-debug
-$(hide) if [ -f "$(PRIVATE_INTERMEDIATES_DIR)/classes.dex" ]; then \
- mkdir -p $(TOP)/dalvik/DEBUG-FILES; \
- $(ACP) $(PRIVATE_INTERMEDIATES_DIR)/classes.dex \
- $(TOP)/dalvik/DEBUG-FILES/$(PRIVATE_MODULE).dex; \
- fi
-$(hide) if [ -f "$(PRIVATE_INTERMEDIATES_DIR)/classes.lst" ]; then \
- mkdir -p $(TOP)/dalvik/DEBUG-FILES; \
- $(ACP) $(PRIVATE_INTERMEDIATES_DIR)/classes.lst \
- $(TOP)/dalvik/DEBUG-FILES/$(PRIVATE_MODULE).lst; \
- fi
-endef
-
# TODO(joeo): If we can ever upgrade to post 3.81 make and get the
# new prebuilt rules to work, we should change this to copy the
# resources to the out directory and then copy the resources.
@@ -2554,7 +2767,7 @@
# $(1): source file
# $(2): destination file
define copy-one-file
-$(2): $(1) | $(ACP)
+$(2): $(1)
@echo "Copy: $$@"
$$(copy-file-to-target)
endef
@@ -2575,7 +2788,7 @@
# $(1): source file
# $(2): destination file, must end with .xml.
define copy-xml-file-checked
-$(2): $(1) | $(ACP)
+$(2): $(1)
@echo "Copy xml: $$@"
$(hide) xmllint $$< >/dev/null # Don't print the xml file to stdout.
$$(copy-file-to-target)
@@ -2590,31 +2803,30 @@
# Copy a single file from one place to another,
# preserving permissions and overwriting any existing
# file.
-# We disable the "-t" option for acp cannot handle
-# high resolution timestamp correctly on file systems like ext4.
-# Therefore copy-file-to-target is the same as copy-file-to-new-target.
+# When we used acp, it could not handle high resolution timestamps
+# on file systems like ext4. Because of that, '-t' option was disabled
+# and copy-file-to-target was identical to copy-file-to-new-target.
+# Keep the behavior until we audit and ensure that switching this back
+# won't break anything.
define copy-file-to-target
@mkdir -p $(dir $@)
-$(hide) $(ACP) -fp $< $@
+$(hide) rm -f $@
+$(hide) cp $< $@
endef
# The same as copy-file-to-target, but use the local
# cp command instead of acp.
define copy-file-to-target-with-cp
@mkdir -p $(dir $@)
-$(hide) cp -fp $< $@
-endef
-
-# The same as copy-file-to-target, but use the zipalign tool to do so.
-define copy-file-to-target-with-zipalign
-@mkdir -p $(dir $@)
-$(hide) $(ZIPALIGN) -f 4 $< $@
+$(hide) rm -f $@
+$(hide) cp -p $< $@
endef
# The same as copy-file-to-target, but strip out "# comment"-style
# comments (for config files and such).
define copy-file-to-target-strip-comments
@mkdir -p $(dir $@)
+$(hide) rm -f $@
$(hide) sed -e 's/#.*$$//' -e 's/[ \t]*$$//' -e '/^$$/d' < $< > $@
endef
@@ -2622,31 +2834,27 @@
# the old modification time.
define copy-file-to-new-target
@mkdir -p $(dir $@)
-$(hide) $(ACP) -fp $< $@
+$(hide) rm -f $@
+$(hide) cp $< $@
endef
# The same as copy-file-to-new-target, but use the local
# cp command instead of acp.
define copy-file-to-new-target-with-cp
@mkdir -p $(dir $@)
-$(hide) cp -f $< $@
+$(hide) rm -f $@
+$(hide) cp $< $@
endef
# Copy a prebuilt file to a target location.
define transform-prebuilt-to-target
-@echo "$(if $(PRIVATE_IS_HOST_MODULE),host,target) Prebuilt: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Prebuilt: $(PRIVATE_MODULE) ($@)"
$(copy-file-to-target)
endef
-# Copy a prebuilt file to a target location, using zipalign on it.
-define transform-prebuilt-to-target-with-zipalign
-@echo "$(if $(PRIVATE_IS_HOST_MODULE),host,target) Prebuilt APK: $(PRIVATE_MODULE) ($@)"
-$(copy-file-to-target-with-zipalign)
-endef
-
# Copy a prebuilt file to a target location, stripping "# comment" comments.
define transform-prebuilt-to-target-strip-comments
-@echo "$(if $(PRIVATE_IS_HOST_MODULE),host,target) Prebuilt: $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Prebuilt: $(PRIVATE_MODULE) ($@)"
$(copy-file-to-target-strip-comments)
endef
@@ -2661,13 +2869,31 @@
$(hide) mkdir -p $(dir $(3)/$(s)); cp -Rf $(t) $(3)/$(s)$(newline))
endef
+# Define a rule to create a symlink to a file.
+# $(1): full path to source
+# $(2): source (may be relative)
+# $(3): full path to destination
+define symlink-file
+$(eval $(_symlink-file))
+endef
+
+# Order-only dependency because make/ninja will follow the link when checking
+# the timestamp, so the file must exist
+define _symlink-file
+$(3): | $(1)
+ @echo "Symlink: $$@ -> $(2)"
+ @mkdir -p $(dir $$@)
+ @rm -rf $$@
+ $(hide) ln -sf $(2) $$@
+endef
###########################################################
## Commands to call Proguard
###########################################################
define transform-jar-to-proguard
@echo Proguard: $@
-$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS) \
+$(hide) $(PROGUARD) -injars '$<$(PRIVATE_PROGUARD_INJAR_FILTERS)' \
+ -outjars $@ $(PRIVATE_PROGUARD_FLAGS) \
$(addprefix -injars , $(PRIVATE_EXTRA_INPUT_JAR))
endef
@@ -2676,7 +2902,7 @@
###########################################################
define transform-generated-source
-@echo "target Generated: $(PRIVATE_MODULE) <= $<"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Generated: $(PRIVATE_MODULE) <= $<"
@mkdir -p $(dir $@)
$(hide) $(PRIVATE_CUSTOM_TOOL)
endef
@@ -2758,7 +2984,7 @@
endef
define add-radio-file-internal
INSTALLED_RADIOIMAGE_TARGET += $$(PRODUCT_OUT)/$(2)
-$$(PRODUCT_OUT)/$(2) : $$(LOCAL_PATH)/$(1) | $$(ACP)
+$$(PRODUCT_OUT)/$(2) : $$(LOCAL_PATH)/$(1)
$$(transform-prebuilt-to-target)
endef
@@ -2773,7 +2999,7 @@
define add-radio-file-checked-internal
INSTALLED_RADIOIMAGE_TARGET += $$(PRODUCT_OUT)/$(2)
BOARD_INFO_CHECK += $(3):$(LOCAL_PATH)/$(1)
-$$(PRODUCT_OUT)/$(2) : $$(LOCAL_PATH)/$(1) | $$(ACP)
+$$(PRODUCT_OUT)/$(2) : $$(LOCAL_PATH)/$(1)
$$(transform-prebuilt-to-target)
endef
@@ -2889,6 +3115,209 @@
$(if $(filter $(TARGET_2ND_ARCH),$(1)),$(TARGET_2ND_ARCH),$(if $(1),none))))
endef
+# ###############################################################
+# Set up statistics gathering
+# ###############################################################
+STATS.MODULE_TYPE := \
+ HOST_STATIC_LIBRARY \
+ HOST_SHARED_LIBRARY \
+ STATIC_LIBRARY \
+ SHARED_LIBRARY \
+ EXECUTABLE \
+ HOST_EXECUTABLE \
+ PACKAGE \
+ PHONY_PACKAGE \
+ HOST_PREBUILT \
+ PREBUILT \
+ MULTI_PREBUILT \
+ JAVA_LIBRARY \
+ STATIC_JAVA_LIBRARY \
+ HOST_JAVA_LIBRARY \
+ DROIDDOC \
+ COPY_HEADERS \
+ NATIVE_TEST \
+ NATIVE_BENCHMARK \
+ HOST_NATIVE_TEST \
+ FUZZ_TEST \
+ HOST_FUZZ_TEST \
+ STATIC_TEST_LIBRARY \
+ HOST_STATIC_TEST_LIBRARY \
+ NOTICE_FILE \
+ HOST_DALVIK_JAVA_LIBRARY \
+ HOST_DALVIK_STATIC_JAVA_LIBRARY \
+ base_rules \
+ HEADER_LIBRARY
+
+$(foreach $(s),$(STATS.MODULE_TYPE),$(eval STATS.MODULE_TYPE.$(s) :=))
+define record-module-type
+$(strip $(if $(LOCAL_RECORDED_MODULE_TYPE),,
+ $(if $(filter-out $(SOONG_ANDROID_MK),$(LOCAL_MODULE_MAKEFILE)),
+ $(if $(filter $(1),$(STATS.MODULE_TYPE)),
+ $(eval LOCAL_RECORDED_MODULE_TYPE := true)
+ $(eval STATS.MODULE_TYPE.$(1) += 1),
+ $(error Invalid module type: $(1))))))
+endef
+
+###########################################################
+## Compatibility suite tools
+###########################################################
+
+# Return a list of output directories for a given suite and the current LOCAL_MODULE.
+# Can be passed a subdirectory to use for the common testcase directory.
+define compatibility_suite_dirs
+ $(strip \
+ $(COMPATIBILITY_TESTCASES_OUT_$(1)) \
+ $($(my_prefix)OUT_TESTCASES)/$(LOCAL_MODULE)$(2))
+endef
+
+# For each suite:
+# 1. Copy the files to the many suite output directories.
+# 2. Add all the files to each suite's dependent files list.
+# 3. Do the dependency addition to my_all_targets
+# Requires for each suite: my_compat_dist_$(suite) to be defined.
+define create-suite-dependencies
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval COMPATIBILITY.$(suite).FILES := \
+ $(COMPATIBILITY.$(suite).FILES) $(foreach f,$(my_compat_dist_$(suite)),$(call word-colon,2,$(f))))) \
+$(eval $(my_all_targets) : $(call copy-many-files, \
+ $(sort $(foreach suite,$(LOCAL_COMPATIBILITY_SUITE),$(my_compat_dist_$(suite))))))
+endef
+
+###########################################################
+## Path Cleaning
+###########################################################
+
+# Remove "dir .." combinations (but keep ".. ..")
+#
+# $(1): The expanded path, where / is converted to ' ' to work with $(word)
+define _clean-path-strip-dotdot
+$(strip \
+ $(if $(word 2,$(1)),
+ $(if $(call streq,$(word 2,$(1)),..),
+ $(if $(call streq,$(word 1,$(1)),..),
+ $(word 1,$(1)) $(call _clean-path-strip-dotdot,$(wordlist 2,$(words $(1)),$(1)))
+ ,
+ $(call _clean-path-strip-dotdot,$(wordlist 3,$(words $(1)),$(1)))
+ )
+ ,
+ $(word 1,$(1)) $(call _clean-path-strip-dotdot,$(wordlist 2,$(words $(1)),$(1)))
+ )
+ ,
+ $(1)
+ )
+)
+endef
+
+# Remove any leading .. from the path (in case of /..)
+#
+# Should only be called if the original path started with /
+# $(1): The expanded path, where / is converted to ' ' to work with $(word)
+define _clean-path-strip-root-dotdots
+$(strip $(if $(call streq,$(firstword $(1)),..),
+ $(call _clean-path-strip-root-dotdots,$(wordlist 2,$(words $(1)),$(1))),
+ $(1)))
+endef
+
+# Call _clean-path-strip-dotdot until the path stops changing
+# $(1): Non-empty if this path started with a /
+# $(2): The expanded path, where / is converted to ' ' to work with $(word)
+define _clean-path-expanded
+$(strip \
+ $(eval _ep := $(call _clean-path-strip-dotdot,$(2)))
+ $(if $(1),$(eval _ep := $(call _clean-path-strip-root-dotdots,$(_ep))))
+ $(if $(call streq,$(2),$(_ep)),
+ $(_ep),
+ $(call _clean-path-expanded,$(1),$(_ep))))
+endef
+
+# Clean the file path -- remove //, dir/.., extra .
+#
+# This should be the same semantics as golang's filepath.Clean
+#
+# $(1): The file path to clean
+define clean-path
+$(strip \
+ $(if $(call streq,$(words $(1)),1),
+ $(eval _rooted := $(filter /%,$(1)))
+ $(eval _expanded_path := $(filter-out .,$(subst /,$(space),$(1))))
+ $(eval _path := $(if $(_rooted),/)$(subst $(space),/,$(call _clean-path-expanded,$(_rooted),$(_expanded_path))))
+ $(if $(_path),
+ $(_path),
+ .
+ )
+ ,
+ $(if $(call streq,$(words $(1)),0),
+ .,
+ $(error Call clean-path with only one path (without spaces))
+ )
+ )
+)
+endef
+
+ifeq ($(TEST_MAKE_clean_path),true)
+ define my_test
+ $(if $(call streq,$(call clean-path,$(1)),$(2)),,
+ $(eval my_failed := true)
+ $(warning clean-path test '$(1)': expected '$(2)', got '$(call clean-path,$(1))'))
+ endef
+ my_failed :=
+
+ # Already clean
+ $(call my_test,abc,abc)
+ $(call my_test,abc/def,abc/def)
+ $(call my_test,a/b/c,a/b/c)
+ $(call my_test,.,.)
+ $(call my_test,..,..)
+ $(call my_test,../..,../..)
+ $(call my_test,../../abc,../../abc)
+ $(call my_test,/abc,/abc)
+ $(call my_test,/,/)
+
+ # Empty is current dir
+ $(call my_test,,.)
+
+ # Remove trailing slash
+ $(call my_test,abc/,abc)
+ $(call my_test,abc/def/,abc/def)
+ $(call my_test,a/b/c/,a/b/c)
+ $(call my_test,./,.)
+ $(call my_test,../,..)
+ $(call my_test,../../,../..)
+ $(call my_test,/abc/,/abc)
+
+ # Remove doubled slash
+ $(call my_test,abc//def//ghi,abc/def/ghi)
+ $(call my_test,//abc,/abc)
+ $(call my_test,///abc,/abc)
+ $(call my_test,//abc//,/abc)
+ $(call my_test,abc//,abc)
+
+ # Remove . elements
+ $(call my_test,abc/./def,abc/def)
+ $(call my_test,/./abc/def,/abc/def)
+ $(call my_test,abc/.,abc)
+
+ # Remove .. elements
+ $(call my_test,abc/def/ghi/../jkl,abc/def/jkl)
+ $(call my_test,abc/def/../ghi/../jkl,abc/jkl)
+ $(call my_test,abc/def/..,abc)
+ $(call my_test,abc/def/../..,.)
+ $(call my_test,/abc/def/../..,/)
+ $(call my_test,abc/def/../../..,..)
+ $(call my_test,/abc/def/../../..,/)
+ $(call my_test,abc/def/../../../ghi/jkl/../../../mno,../../mno)
+ $(call my_test,/../abc,/abc)
+
+ # Combinations
+ $(call my_test,abc/./../def,def)
+ $(call my_test,abc//./../def,def)
+ $(call my_test,abc/../../././../def,../../def)
+
+ ifdef my_failed
+ $(error failed clean-path test)
+ endif
+endif
+
###########################################################
## Other includes
###########################################################
@@ -2932,3 +3361,40 @@
# sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
# -e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
# rm -f $*.d
+
+
+###########################################################
+# Append the information to generate a RRO package for the
+# source module.
+#
+# $(1): Source module name.
+# $(2): Whether $(3) is a manifest package name or not.
+# $(3): Manifest package name if $(2) is true.
+# Otherwise, android manifest file path of the
+# source module.
+# $(4): Whether LOCAL_EXPORT_PACKAGE_RESOURCES is set or
+# not for the source module.
+# $(5): Resource overlay list.
+###########################################################
+define append_enforce_rro_sources
+ $(eval ENFORCE_RRO_SOURCES += \
+ $(strip $(1))||$(strip $(2))||$(strip $(3))||$(strip $(4))||$(call normalize-path-list, $(strip $(5))))
+endef
+
+###########################################################
+# Generate all RRO packages for source modules stored in
+# ENFORCE_RRO_SOURCES
+###########################################################
+define generate_all_enforce_rro_packages
+$(foreach source,$(ENFORCE_RRO_SOURCES), \
+ $(eval _o := $(subst ||,$(space),$(source))) \
+ $(eval enforce_rro_source_module := $(word 1,$(_o))) \
+ $(eval enforce_rro_source_is_manifest_package_name := $(word 2,$(_o))) \
+ $(eval enforce_rro_source_manifest_package_info := $(word 3,$(_o))) \
+ $(eval enforce_rro_use_res_lib := $(word 4,$(_o))) \
+ $(eval enforce_rro_source_overlays := $(subst :, ,$(word 5,$(_o)))) \
+ $(eval enforce_rro_module := $(enforce_rro_source_module)__auto_generated_rro) \
+ $(eval include $(BUILD_SYSTEM)/generate_enforce_rro.mk) \
+ $(eval ALL_MODULES.$(enforce_rro_source_module).REQUIRED += $(enforce_rro_module)) \
+)
+endef
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index 5df9dc3..f940c72 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -23,10 +23,12 @@
# being used). To bundle everything one should set this to '%'
SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%
+# Method returning whether the install path $(1) should be for system_other.
+install-on-system-other = $(filter-out $(PRODUCT_SYSTEM_SERVER_APPS),$(basename $(notdir $(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(1)))))
+
# The default values for pre-opting: always preopt PIC.
# Conditional to building on linux, as dex2oat currently does not work on darwin.
ifeq ($(HOST_OS),linux)
- WITH_DEXPREOPT_PIC ?= true
WITH_DEXPREOPT ?= true
# For an eng build only pre-opt the boot image. This gives reasonable performance and still
# allows a simple workflow: building in frameworks/base and syncing.
@@ -40,10 +42,6 @@
endif
GLOBAL_DEXPREOPT_FLAGS :=
-ifeq ($(WITH_DEXPREOPT_PIC),true)
-# Compile boot.oat as position-independent code if WITH_DEXPREOPT_PIC=true
-GLOBAL_DEXPREOPT_FLAGS += --compile-pic
-endif
# $(1): the .jar or .apk to remove classes.dex
define dexpreopt-remove-classes.dex
@@ -61,7 +59,7 @@
_dbj_jar_no_dex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1)_nodex.jar
_dbj_src_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(1),,COMMON)/javalib.jar
-$$(_dbj_jar_no_dex) : $$(_dbj_src_jar) | $(ACP)
+$$(_dbj_jar_no_dex) : $$(_dbj_src_jar)
$$(call copy-file-to-target)
ifneq ($(DEX_PREOPT_DEFAULT),nostripping)
$$(call dexpreopt-remove-classes.dex,$$@)
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index acd4a02..9db5dbf 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -25,10 +25,6 @@
COMPILED_CLASSES := $(call word-colon,1,$(firstword \
$(filter %system/etc/compiled-classes,$(PRODUCT_COPY_FILES))))
-# start of image reserved address space
-LIBART_IMG_HOST_BASE_ADDRESS := 0x60000000
-LIBART_IMG_TARGET_BASE_ADDRESS := 0x70000000
-
define get-product-default-property
$(strip $(patsubst $(1)=%,%,$(filter $(1)=%,$(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))))
endef
@@ -45,7 +41,6 @@
# building the image. We therefore limit the Xmx value. This isn't done
# via a property as we want the larger Xmx value if we're running on a
# MIPS device.
-LIBART_IMG_TARGET_BASE_ADDRESS := 0x30000000
DEX2OAT_XMX := 128m
endif
@@ -66,7 +61,7 @@
# $(2): the full install path (including file name) of the corresponding .apk.
ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
define get-odex-installed-file-path
-$(if $(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(2)),
+$(if $(call install-on-system-other, $(2)),
$(call get-odex-file-path,$(1),$(patsubst $(TARGET_OUT)/%,$(TARGET_OUT_SYSTEM_OTHER)/%,$(2))),
$(call get-odex-file-path,$(1),$(2)))
endef
@@ -90,17 +85,19 @@
# is converted into to boot.art (to match the legacy assumption that boot.art
# exists), and the rest are converted to boot-<name>.art.
# In addition, each .art file has an associated .oat file.
-LIBART_TARGET_BOOT_ART_EXTRA_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).art boot-$(jar).oat)
-LIBART_TARGET_BOOT_ART_EXTRA_FILES += boot.oat
+LIBART_TARGET_BOOT_ART_EXTRA_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).art boot-$(jar).oat boot-$(jar).vdex)
+LIBART_TARGET_BOOT_ART_EXTRA_FILES += boot.oat boot.vdex
my_2nd_arch_prefix :=
include $(BUILD_SYSTEM)/dex_preopt_libart_boot.mk
+ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
ifdef TARGET_2ND_ARCH
my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
include $(BUILD_SYSTEM)/dex_preopt_libart_boot.mk
my_2nd_arch_prefix :=
endif
+endif
########################################################################
@@ -122,9 +119,13 @@
--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
- --include-patch-information --runtime-arg -Xnorelocate --no-generate-debug-info \
+ --runtime-arg -Xnorelocate --compile-pic \
+ --no-generate-debug-info --generate-build-id \
--abort-on-hard-verifier-error \
+ --force-determinism \
--no-inline-from=core-oj.jar \
$(PRIVATE_DEX_PREOPT_FLAGS) \
+ $(PRIVATE_ART_FILE_PREOPT_FLAGS) \
+ $(PRIVATE_PROFILE_PREOPT_FLAGS) \
$(GLOBAL_DEXPREOPT_FLAGS)
endef
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 1a0dc5b..860a66a 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -52,7 +52,7 @@
$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME): PRIVATE_2ND_ARCH_VAR_PREFIX := $(my_2nd_arch_prefix)
# Use dex2oat debug version for better error reporting
-$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(DEX2OAT_DEPENDENCY)
+$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) : $(LIBART_TARGET_BOOT_DEX_FILES) $(PRELOADED_CLASSES) $(COMPILED_CLASSES) $(DEX2OAT_DEPENDENCY)
@echo "target dex2oat: $@"
@mkdir -p $(dir $@)
@mkdir -p $(dir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)LIBART_TARGET_BOOT_OAT_UNSTRIPPED))
@@ -71,6 +71,8 @@
--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
- --android-root=$(PRODUCT_OUT)/system --include-patch-information --runtime-arg -Xnorelocate --no-generate-debug-info \
+ --android-root=$(PRODUCT_OUT)/system \
+ --runtime-arg -Xnorelocate --compile-pic \
+ --no-generate-debug-info --generate-build-id \
--multi-image --no-inline-from=core-oj.jar \
$(PRODUCT_DEX_PREOPT_BOOT_FLAGS) $(GLOBAL_DEXPREOPT_FLAGS) $(COMPILED_CLASSES_FLAGS) $(ART_BOOT_IMAGE_EXTRA_ARGS)
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index b05d4da..a3fb410 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -42,15 +42,22 @@
# if installing into system, and odex are being installed into system_other, don't strip
ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
ifeq ($(LOCAL_DEX_PREOPT),true)
-ifneq ($(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(my_module_path)),)
+ifneq ($(call install-on-system-other, $(my_module_path)),)
LOCAL_DEX_PREOPT := nostripping
endif
endif
endif
built_odex :=
+built_vdex :=
+built_art :=
installed_odex :=
+installed_vdex :=
+installed_art :=
built_installed_odex :=
+built_installed_vdex :=
+built_installed_art :=
+
ifdef LOCAL_DEX_PREOPT
dexpreopt_boot_jar_module := $(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE))
ifdef dexpreopt_boot_jar_module
@@ -76,10 +83,12 @@
# #################################################
# Odex for the 2nd arch
ifdef TARGET_2ND_ARCH
+ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
ifneq (first,$(my_module_multilib))
my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
include $(BUILD_SYSTEM)/setup_one_odex.mk
endif # my_module_multilib is not first.
+endif # TARGET_TRANSLATE_2ND_ARCH not true
endif # TARGET_2ND_ARCH
# #################################################
else # must be APPS
@@ -97,9 +106,45 @@
endif # boot jar
built_odex := $(strip $(built_odex))
+built_vdex := $(strip $(built_vdex))
+built_art := $(strip $(built_art))
installed_odex := $(strip $(installed_odex))
+installed_vdex := $(strip $(installed_vdex))
+installed_art := $(strip $(installed_art))
ifdef built_odex
+
+ifndef LOCAL_DEX_PREOPT_GENERATE_PROFILE
+ifeq (true,$(WITH_DEX_PREOPT_GENERATE_PROFILE))
+ LOCAL_DEX_PREOPT_GENERATE_PROFILE := true
+endif
+endif
+
+ifeq (true,$(LOCAL_DEX_PREOPT_GENERATE_PROFILE))
+ifndef LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING
+$(call pretty-error,Must have specified class listing (LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING))
+endif
+my_built_profile := $(dir $(LOCAL_BUILT_MODULE))/profile.prof
+my_dex_location := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
+$(built_odex): $(my_built_profile)
+$(built_odex): PRIVATE_PROFILE_PREOPT_FLAGS := --profile-file=$(my_built_profile)
+$(my_built_profile): PRIVATE_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
+$(my_built_profile): PRIVATE_DEX_LOCATION := $(my_dex_location)
+$(my_built_profile): PRIVATE_SOURCE_CLASSES := $(LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING)
+$(my_built_profile): $(LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING)
+$(my_built_profile): $(PROFMAN)
+$(my_built_profile): $(LOCAL_BUILT_MODULE)
+$(my_built_profile):
+ $(hide) mkdir -p $(dir $@)
+ ANDROID_LOG_TAGS="*:e" $(PROFMAN) \
+ --create-profile-from=$(PRIVATE_SOURCE_CLASSES) \
+ --apk=$(PRIVATE_BUILT_MODULE) \
+ --dex-location=$(PRIVATE_DEX_LOCATION) \
+ --reference-profile-file=$@
+else
+$(built_odex): PRIVATE_PROFILE_PREOPT_FLAGS :=
+endif
+
ifndef LOCAL_DEX_PREOPT_FLAGS
LOCAL_DEX_PREOPT_FLAGS := $(DEXPREOPT.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG)
ifndef LOCAL_DEX_PREOPT_FLAGS
@@ -107,19 +152,36 @@
endif
endif
+ifneq (,$(filter $(PRODUCT_SYSTEM_SERVER_JARS) $(PRODUCT_SYSTEM_SERVER_APPS),$(LOCAL_MODULE)))
+ # Jars of system server, and apps loaded into system server should be
+ # compiled with the 'speed' compiler filter.
+ LOCAL_DEX_PREOPT_FLAGS += --compiler-filter=speed
+else
+ # If no compiler filter is specified, default to 'quicken' to save on storage.
+ ifeq (,$(filter --compiler-filter=%, $(LOCAL_DEX_PREOPT_FLAGS)))
+ LOCAL_DEX_PREOPT_FLAGS += --compiler-filter=quicken
+ endif
+endif
+
$(built_odex): PRIVATE_DEX_PREOPT_FLAGS := $(LOCAL_DEX_PREOPT_FLAGS)
+$(built_vdex): $(built_odex)
+$(built_art): $(built_odex)
endif
# Add the installed_odex to the list of installed files for this module.
ALL_MODULES.$(my_register_name).INSTALLED += $(installed_odex)
+ALL_MODULES.$(my_register_name).INSTALLED += $(installed_vdex)
+ALL_MODULES.$(my_register_name).INSTALLED += $(installed_art)
ALL_MODULES.$(my_register_name).BUILT_INSTALLED += $(built_installed_odex)
+ALL_MODULES.$(my_register_name).BUILT_INSTALLED += $(built_installed_vdex)
+ALL_MODULES.$(my_register_name).BUILT_INSTALLED += $(built_installed_art)
# Record dex-preopt config.
DEXPREOPT.$(LOCAL_MODULE).DEX_PREOPT := $(LOCAL_DEX_PREOPT)
DEXPREOPT.$(LOCAL_MODULE).MULTILIB := $(LOCAL_MULTILIB)
DEXPREOPT.$(LOCAL_MODULE).DEX_PREOPT_FLAGS := $(LOCAL_DEX_PREOPT_FLAGS)
DEXPREOPT.$(LOCAL_MODULE).PRIVILEGED_MODULE := $(LOCAL_PRIVILEGED_MODULE)
-DEXPREOPT.$(LOCAL_MODULE).PROPRIETARY_MODULE := $(LOCAL_PROPRIETARY_MODULE)
+DEXPREOPT.$(LOCAL_MODULE).VENDOR_MODULE := $(LOCAL_VENDOR_MODULE)
DEXPREOPT.$(LOCAL_MODULE).TARGET_ARCH := $(LOCAL_MODULE_TARGET_ARCH)
DEXPREOPT.$(LOCAL_MODULE).INSTALLED := $(installed_odex)
DEXPREOPT.$(LOCAL_MODULE).INSTALLED_STRIPPED := $(LOCAL_INSTALLED_MODULE)
@@ -127,7 +189,7 @@
$(DEXPREOPT.MODULES.$(LOCAL_MODULE_CLASS)) $(LOCAL_MODULE))
-# Make sure to install the .odex when you run "make <module_name>"
-$(my_register_name): $(installed_odex)
+# Make sure to install the .odex and .vdex when you run "make <module_name>"
+$(my_all_targets): $(installed_odex) $(installed_vdex) $(installed_art)
endif # LOCAL_DEX_PREOPT
diff --git a/core/distdir.mk b/core/distdir.mk
index 51ec46e..89c5966 100644
--- a/core/distdir.mk
+++ b/core/distdir.mk
@@ -17,16 +17,8 @@
# When specifying "dist", the user has asked that we copy the important
# files from this build into DIST_DIR.
-.PHONY: dist
-dist: ;
-
dist_goal := $(strip $(filter dist,$(MAKECMDGOALS)))
MAKECMDGOALS := $(strip $(filter-out dist,$(MAKECMDGOALS)))
-ifeq (,$(strip $(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS))))
-# The commandline was something like "make dist" or "make dist showcommands".
-# Add a dependency on a real target.
-dist: $(DEFAULT_GOAL)
-endif
ifdef dist_goal
diff --git a/core/dpi_specific_apk.mk b/core/dpi_specific_apk.mk
index 6bae25d..1b0be07 100644
--- a/core/dpi_specific_apk.mk
+++ b/core/dpi_specific_apk.mk
@@ -5,6 +5,7 @@
dpi_apk_name := $(LOCAL_MODULE)_$(my_dpi)
dpi_intermediate := $(call intermediates-dir-for,APPS,$(dpi_apk_name))
built_dpi_apk := $(dpi_intermediate)/package.apk
+additional_certificates := $(foreach c,$(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
# Set up all the target-specific variables.
$(built_dpi_apk): PRIVATE_MODULE := $(dpi_apk_name)
@@ -27,15 +28,15 @@
$(built_dpi_apk): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abis)
$(built_dpi_apk): PRIVATE_PRIVATE_KEY := $(private_key)
$(built_dpi_apk): PRIVATE_CERTIFICATE := $(certificate)
-$(built_dpi_apk): PRIVATE_ADDITIONAL_CERTIFICATES := $(foreach c,\
- $(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
+$(built_dpi_apk): $(additional_certificates)
+$(built_dpi_apk): PRIVATE_ADDITIONAL_CERTIFICATES := $(additional_certificates)
$(built_dpi_apk): PRIVATE_SOURCE_ARCHIVE :=
ifneq ($(full_classes_jar),)
$(built_dpi_apk): PRIVATE_DEX_FILE := $(built_dex)
ifndef LOCAL_JACK_ENABLED
# Use the jarjar processed arhive as the initial package file.
-$(built_dpi_apk): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
+$(built_dpi_apk): PRIVATE_SOURCE_ARCHIVE := $(full_classes_pre_proguard_jar)
else
$(built_dpi_apk): PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
endif # LOCAL_JACK_ENABLED
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index f143579..7e17a13 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -14,6 +14,7 @@
# limitations under the License.
#
+$(call record-module-type,DROIDDOC)
##
##
## Common to both droiddoc and javadoc
@@ -165,7 +166,6 @@
$(droiddoc) \
$(html_dir_files) \
$(full_java_lib_deps) \
- $(LOCAL_MODULE_MAKEFILE_DEP) \
$(LOCAL_ADDITIONAL_DEPENDENCIES)
@echo Docs droiddoc: $(PRIVATE_OUT_DIR)
$(hide) mkdir -p $(dir $@)
@@ -175,6 +175,7 @@
$(hide) ( \
javadoc \
-encoding UTF-8 \
+ -source 1.8 \
\@$(PRIVATE_SRC_LIST_FILE) \
-J-Xmx1600m \
-XDignore.symbol.file \
@@ -215,7 +216,7 @@
\@$(PRIVATE_SRC_LIST_FILE) \
-J-Xmx1024m \
-XDignore.symbol.file \
- $(if $(LEGACY_USE_JAVA7),,-Xdoclint:none) \
+ -Xdoclint:none \
$(PRIVATE_PROFILING_OPTIONS) \
$(addprefix -classpath ,$(PRIVATE_CLASSPATH)) \
$(addprefix -bootclasspath ,$(PRIVATE_BOOTCLASSPATH)) \
diff --git a/core/dumpvar.mk b/core/dumpvar.mk
index 1bd4777..acae48e 100644
--- a/core/dumpvar.mk
+++ b/core/dumpvar.mk
@@ -6,6 +6,7 @@
TARGET_PRODUCT \
TARGET_BUILD_VARIANT \
TARGET_BUILD_TYPE \
+ TARGET_PLATFORM_VERSION \
TARGET_BUILD_APPS \
TARGET_ARCH \
TARGET_ARCH_VARIANT \
@@ -22,7 +23,8 @@
HOST_CROSS_2ND_ARCH \
HOST_BUILD_TYPE \
BUILD_ID \
- OUT_DIR
+ OUT_DIR \
+ AUX_OS_VARIANT_LIST
ifeq ($(TARGET_BUILD_PDK),true)
print_build_config_vars += \
@@ -35,10 +37,15 @@
# what to add to the path given the config we have chosen.
ifeq ($(CALLED_FROM_SETUP),true)
-ifneq ($(filter /%,$(HOST_OUT_EXECUTABLES)),)
-ABP:=$(HOST_OUT_EXECUTABLES)
+ifneq ($(filter /%,$(SOONG_HOST_OUT_EXECUTABLES)),)
+ABP := $(SOONG_HOST_OUT_EXECUTABLES)
else
-ABP:=$(PWD)/$(HOST_OUT_EXECUTABLES)
+ABP := $(PWD)/$(SOONG_HOST_OUT_EXECUTABLES)
+endif
+ifneq ($(filter /%,$(HOST_OUT_EXECUTABLES)),)
+ABP := $(ABP):$(HOST_OUT_EXECUTABLES)
+else
+ABP := $(ABP):$(PWD)/$(HOST_OUT_EXECUTABLES)
endif
ANDROID_BUILD_PATHS := $(ABP)
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index 91fd271..949793b 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -23,7 +23,7 @@
# The basename of this target must be the same as the final output
# binary name, because it's used to set the "soname" in the binary.
# The includer of this file will define a rule to build this target.
-linked_module := $(intermediates)/LINKED/$(my_built_module_stem)
+linked_module := $(intermediates)/LINKED/$(notdir $(my_installed_module_stem))
ALL_ORIGINAL_DYNAMIC_BINARIES += $(linked_module)
@@ -58,7 +58,7 @@
# Do not pack relocations for executables. Because packing results in
# non-zero p_vaddr which causes kernel to load executables to lower
# address (starting at 0x8000) http://b/20665974
-ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
+ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
my_pack_module_relocations := false
endif
@@ -69,10 +69,10 @@
ifeq (true,$(my_pack_module_relocations))
# Pack relocations
-$(relocation_packer_output): $(relocation_packer_input) | $(ACP)
+$(relocation_packer_output): $(relocation_packer_input)
$(pack-elf-relocations)
else
-$(relocation_packer_output): $(relocation_packer_input) | $(ACP)
+$(relocation_packer_output): $(relocation_packer_input)
@echo "target Unpacked: $(PRIVATE_MODULE) ($@)"
$(copy-file-to-target)
endif
@@ -87,7 +87,7 @@
endif
symbolic_input := $(relocation_packer_output)
symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
-$(symbolic_output) : $(symbolic_input) | $(ACP)
+$(symbolic_output) : $(symbolic_input)
@echo "target Symbolic: $(PRIVATE_MODULE) ($@)"
$(copy-file-to-target)
@@ -116,11 +116,21 @@
$(LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
$(LOCAL_STRIP_MODULE))
ifeq ($(my_strip_module),)
+ my_strip_module := mini-debug-info
+endif
+
+ifeq ($(my_strip_module),mini-debug-info)
+# Don't use mini-debug-info on mips (both 32-bit and 64-bit). objcopy checks that all
+# SH_MIPS_DWARF sections having name prefix .debug_ or .zdebug_, so there seems no easy
+# way using objcopy to remove all debug sections except .debug_frame on mips.
+ifneq ($(filter mips mips64,$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
my_strip_module := true
endif
+endif
$(strip_output): PRIVATE_STRIP := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
$(strip_output): PRIVATE_OBJCOPY := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY)
+$(strip_output): PRIVATE_NM := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NM)
$(strip_output): PRIVATE_READELF := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_READELF)
ifeq ($(my_strip_module),no_debuglink)
$(strip_output): PRIVATE_NO_DEBUGLINK := true
@@ -128,7 +138,11 @@
$(strip_output): PRIVATE_NO_DEBUGLINK :=
endif
-ifneq ($(filter true no_debuglink,$(my_strip_module)),)
+ifeq ($(my_strip_module),mini-debug-info)
+# Strip the binary, but keep debug frames and symbol table in a compressed .gnu_debugdata section.
+$(strip_output): $(strip_input) | $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_NM)
+ $(transform-to-stripped-keep-mini-debug-info)
+else ifneq ($(filter true no_debuglink,$(my_strip_module)),)
# Strip the binary
$(strip_output): $(strip_input) | $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
$(transform-to-stripped)
@@ -148,18 +162,9 @@
else
# Don't strip the binary, just copy it. We can't skip this step
# because a copy of the binary must appear at LOCAL_BUILT_MODULE.
-#
-# If the binary we're copying is acp or a prerequisite,
-# use cp(1) instead.
-ifneq ($(LOCAL_ACP_UNAVAILABLE),true)
-$(strip_output): $(strip_input) | $(ACP)
- @echo "target Unstripped: $(PRIVATE_MODULE) ($@)"
- $(copy-file-to-target)
-else
$(strip_output): $(strip_input)
@echo "target Unstripped: $(PRIVATE_MODULE) ($@)"
- $(copy-file-to-target-with-cp)
-endif
+ $(copy-file-to-target)
endif # my_strip_module
$(cleantarget): PRIVATE_CLEAN_FILES += \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 6cfb6a1..08b2321 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -11,16 +11,89 @@
# This can be useful if you set OUT_DIR to be a different directory
# than other outputs of your build system.
+# Returns all words in $1 up to and including $2
+define find_and_earlier
+ $(strip $(if $(1),
+ $(firstword $(1))
+ $(if $(filter $(firstword $(1)),$(2)),,
+ $(call find_and_earlier,$(wordlist 2,$(words $(1)),$(1)),$(2)))))
+endef
+
+#$(warning $(call find_and_earlier,A B C,A))
+#$(warning $(call find_and_earlier,A B C,B))
+#$(warning $(call find_and_earlier,A B C,C))
+#$(warning $(call find_and_earlier,A B C,D))
+
+define version-list
+$(1)PR1 $(1)PD1 $(1)PD2 $(1)PM1 $(1)PM2
+endef
+
+ALL_VERSIONS := O P Q R S T U V W X Y Z
+ALL_VERSIONS := $(foreach v,$(ALL_VERSIONS),$(call version-list,$(v)))
+
+# Filters ALL_VERSIONS down to the range [$1, $2], and errors if $1 > $2 or $3 is
+# not in [$1, $2]
+# $(1): min platform version
+# $(2): max platform version
+# $(3): default platform version
+define allowed-platform-versions
+$(strip \
+ $(if $(filter $(ALL_VERSIONS),$(1)),,
+ $(error Invalid MIN_PLATFORM_VERSION '$(1)'))
+ $(if $(filter $(ALL_VERSIONS),$(2)),,
+ $(error Invalid MAX_PLATFORM_VERSION '$(2)'))
+ $(if $(filter $(ALL_VERSIONS),$(3)),,
+ $(error Invalid DEFAULT_PLATFORM_VERSION '$(3)'))
+
+ $(eval allowed_versions_ := $(call find_and_earlier,$(ALL_VERSIONS),$(2)))
+
+ $(if $(filter $(allowed_versions_),$(1)),,
+ $(error MIN_PLATFORM_VERSION '$(1)' must be before MAX_PLATFORM_VERSION '$(2)'))
+
+ $(eval allowed_versions_ := $(1) \
+ $(filter-out $(call find_and_earlier,$(allowed_versions_),$(1)),$(allowed_versions_)))
+
+ $(if $(filter $(allowed_versions_),$(3)),,
+ $(error DEFAULT_PLATFORM_VERSION '$(3)' must be between MIN_PLATFORM_VERSION '$(1)' and MAX_PLATFORM_VERSION '$(2)'))
+
+ $(allowed_versions_))
+endef
+
+#$(warning $(call allowed-platform-versions,OPR1,PPR1,OPR1))
+#$(warning $(call allowed-platform-versions,OPM1,PPR1,OPR1))
+
# Set up version information.
include $(BUILD_SYSTEM)/version_defaults.mk
+ENABLED_VERSIONS := $(call find_and_earlier,$(ALL_VERSIONS),$(TARGET_PLATFORM_VERSION))
+
+$(foreach v,$(ENABLED_VERSIONS), \
+ $(eval IS_AT_LEAST_$(v) := true))
+
# ---------------------------------------------------------------
# If you update the build system such that the environment setup
# or buildspec.mk need to be updated, increment this number, and
# people who haven't re-run those will have to do so before they
# can build. Make sure to also update the corresponding value in
# buildspec.mk.default and envsetup.sh.
-CORRECT_BUILD_ENV_SEQUENCE_NUMBER := 10
+CORRECT_BUILD_ENV_SEQUENCE_NUMBER := 13
+
+# ---------------------------------------------------------------
+# Whether we can expect a full build graph
+ALLOW_MISSING_DEPENDENCIES := $(filter true,$(ALLOW_MISSING_DEPENDENCIES))
+ifneq ($(TARGET_BUILD_APPS),)
+ALLOW_MISSING_DEPENDENCIES := true
+endif
+ifeq ($(TARGET_BUILD_PDK),true)
+ALLOW_MISSING_DEPENDENCIES := true
+endif
+ifneq ($(filter true,$(SOONG_ALLOW_MISSING_DEPENDENCIES)),)
+ALLOW_MISSING_DEPENDENCIES := true
+endif
+ifneq ($(ONE_SHOT_MAKEFILE),)
+ALLOW_MISSING_DEPENDENCIES := true
+endif
+.KATI_READONLY := ALLOW_MISSING_DEPENDENCIES
# ---------------------------------------------------------------
# The product defaults to generic on hardware
@@ -65,6 +138,7 @@
HOST_CROSS_OS := windows
HOST_CROSS_ARCH := x86
HOST_CROSS_2ND_ARCH := x86_64
+2ND_HOST_CROSS_IS_64_BIT := true
endif
ifeq ($(HOST_OS),)
@@ -77,7 +151,7 @@
HOST_2ND_ARCH := x86
HOST_IS_64_BIT := true
else
-ifneq (,$(findstring x86,$(UNAME)))
+ifneq (,$(findstring i686,$(UNAME))$(findstring x86,$(UNAME)))
$(error Building on a 32-bit x86 host is not supported: $(UNAME)!)
endif
endif
@@ -111,10 +185,17 @@
TARGET_COPY_OUT_SYSTEM := system
TARGET_COPY_OUT_SYSTEM_OTHER := system_other
TARGET_COPY_OUT_DATA := data
+TARGET_COPY_OUT_ASAN := $(TARGET_COPY_OUT_DATA)/asan
TARGET_COPY_OUT_OEM := oem
TARGET_COPY_OUT_ODM := odm
TARGET_COPY_OUT_ROOT := root
TARGET_COPY_OUT_RECOVERY := recovery
+
+# Returns the non-sanitized version of the path provided in $1.
+define get_non_asan_path
+$(patsubst $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/%,$(PRODUCT_OUT)/%,$1)
+endef
+
###########################################
# Define TARGET_COPY_OUT_VENDOR to a placeholder, for at this point
# we don't know if the device wants to build a separate vendor.img
@@ -187,7 +268,22 @@
$(error TARGET_COPY_OUT_VENDOR must be set to 'vendor' to use a vendor image)
endif
###########################################
+# Ensure that only TARGET_RECOVERY_UPDATER_LIBS *or* AB_OTA_UPDATER is set.
+TARGET_RECOVERY_UPDATER_LIBS ?=
+AB_OTA_UPDATER ?=
+.KATI_READONLY := TARGET_RECOVERY_UPDATER_LIBS AB_OTA_UPDATER
+ifeq ($(AB_OTA_UPDATER),true)
+ ifneq ($(strip $(TARGET_RECOVERY_UPDATER_LIBS)),)
+ $(error Do not use TARGET_RECOVERY_UPDATER_LIBS when using AB_OTA_UPDATER)
+ endif
+endif
+# Check BOARD_VNDK_VERSION
+ifdef BOARD_VNDK_VERSION
+ ifneq ($(BOARD_VNDK_VERSION),current)
+ $(error BOARD_VNDK_VERSION: Only "current" is implemented)
+ endif
+endif
# ---------------------------------------------------------------
# Set up configuration for target machine.
@@ -217,6 +313,8 @@
endif
endif
+SOONG_OUT_DIR := $(OUT_DIR)/soong
+
DEBUG_OUT_DIR := $(OUT_DIR)/debug
# Move the host or target under the debug/ directory
@@ -233,6 +331,7 @@
HOST_OUT_release := $(HOST_OUT_ROOT_release)/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
HOST_OUT_debug := $(HOST_OUT_ROOT_debug)/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
HOST_OUT := $(HOST_OUT_$(HOST_BUILD_TYPE))
+SOONG_HOST_OUT := $(SOONG_OUT_DIR)/host/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
# TODO: remove
BUILD_OUT := $(HOST_OUT)
@@ -250,25 +349,32 @@
OUT_DOCS := $(TARGET_COMMON_OUT_ROOT)/docs
BUILD_OUT_EXECUTABLES := $(BUILD_OUT)/bin
+SOONG_HOST_OUT_EXECUTABLES := $(SOONG_HOST_OUT)/bin
HOST_OUT_EXECUTABLES := $(HOST_OUT)/bin
HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT)/lib64
HOST_OUT_RENDERSCRIPT_BITCODE := $(HOST_OUT_SHARED_LIBRARIES)
HOST_OUT_JAVA_LIBRARIES := $(HOST_OUT)/framework
HOST_OUT_SDK_ADDON := $(HOST_OUT)/sdk_addon
+HOST_OUT_NATIVE_TESTS := $(HOST_OUT)/nativetest64
+HOST_OUT_COVERAGE := $(HOST_OUT)/coverage
HOST_CROSS_OUT_EXECUTABLES := $(HOST_CROSS_OUT)/bin
HOST_CROSS_OUT_SHARED_LIBRARIES := $(HOST_CROSS_OUT)/lib
+HOST_CROSS_OUT_NATIVE_TESTS := $(HOST_CROSS_OUT)/nativetest
+HOST_CROSS_OUT_COVERAGE := $(HOST_CROSS_OUT)/coverage
+HOST_OUT_TESTCASES := $(HOST_OUT)/testcases
HOST_OUT_INTERMEDIATES := $(HOST_OUT)/obj
-HOST_OUT_HEADERS := $(HOST_OUT_INTERMEDIATES)/include
HOST_OUT_INTERMEDIATE_LIBRARIES := $(HOST_OUT_INTERMEDIATES)/lib
HOST_OUT_NOTICE_FILES := $(HOST_OUT_INTERMEDIATES)/NOTICE_FILES
HOST_OUT_COMMON_INTERMEDIATES := $(HOST_COMMON_OUT_ROOT)/obj
HOST_OUT_FAKE := $(HOST_OUT)/fake_packages
+# Nano environment config
+include $(BUILD_SYSTEM)/aux_config.mk
+
HOST_CROSS_OUT_INTERMEDIATES := $(HOST_CROSS_OUT)/obj
-HOST_CROSS_OUT_HEADERS := $(HOST_CROSS_OUT_INTERMEDIATES)/include
HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES := $(HOST_CROSS_OUT_INTERMEDIATES)/lib
HOST_CROSS_OUT_NOTICE_FILES := $(HOST_CROSS_OUT_INTERMEDIATES)/NOTICE_FILES
@@ -285,14 +391,12 @@
$(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT)/lib
$(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_EXECUTABLES := $(HOST_OUT_EXECUTABLES)
$(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_JAVA_LIBRARIES := $(HOST_OUT_JAVA_LIBRARIES)
+$(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_NATIVE_TESTS := $(HOST_OUT)/nativetest
+$(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_TESTCASES := $(HOST_OUT_TESTCASES)
# The default host library path.
# It always points to the path where we build libraries in the default bitness.
-ifeq ($(HOST_PREFER_32_BIT),true)
-HOST_LIBRARY_PATH := $($(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)
-else
HOST_LIBRARY_PATH := $(HOST_OUT_SHARED_LIBRARIES)
-endif
# Out for HOST_CROSS_2ND_ARCH
HOST_CROSS_2ND_ARCH_VAR_PREFIX := 2ND_
@@ -301,18 +405,28 @@
$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATE_LIBRARIES := $($(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_INTERMEDIATES)/lib
$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_SHARED_LIBRARIES := $(HOST_CROSS_OUT)/lib64
$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_EXECUTABLES := $(HOST_CROSS_OUT_EXECUTABLES)
+$(HOST_CROSS_2ND_ARCH_VAR_PREFIX)HOST_CROSS_OUT_NATIVE_TESTS := $(HOST_CROSS_OUT)/nativetest64
-TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+ TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj_asan
+else
+ TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj
+endif
TARGET_OUT_HEADERS := $(TARGET_OUT_INTERMEDIATES)/include
TARGET_OUT_INTERMEDIATE_LIBRARIES := $(TARGET_OUT_INTERMEDIATES)/lib
-TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj
+
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+ TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj_asan
+else
+ TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj
+endif
TARGET_OUT_GEN := $(PRODUCT_OUT)/gen
TARGET_OUT_COMMON_GEN := $(TARGET_COMMON_OUT_ROOT)/gen
TARGET_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM)
ifneq ($(filter address,$(SANITIZE_TARGET)),)
-target_out_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_DATA)
+target_out_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/system
else
target_out_shared_libraries_base := $(TARGET_OUT)
endif
@@ -335,19 +449,35 @@
TARGET_OUT_ETC := $(TARGET_OUT)/etc
TARGET_OUT_NOTICE_FILES := $(TARGET_OUT_INTERMEDIATES)/NOTICE_FILES
TARGET_OUT_FAKE := $(PRODUCT_OUT)/fake_packages
+TARGET_OUT_TESTCASES := $(PRODUCT_OUT)/testcases
TARGET_OUT_SYSTEM_OTHER := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM_OTHER)
# Out for TARGET_2ND_ARCH
TARGET_2ND_ARCH_VAR_PREFIX := $(HOST_2ND_ARCH_VAR_PREFIX)
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+# With this you can reference the arm binary translation library with libfoo_arm in PRODUCT_PACKAGES.
+TARGET_2ND_ARCH_MODULE_SUFFIX := _$(TARGET_2ND_ARCH)
+else
TARGET_2ND_ARCH_MODULE_SUFFIX := $(HOST_2ND_ARCH_MODULE_SUFFIX)
-$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj_$(TARGET_2ND_ARCH)
+endif
+
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+ $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj_$(TARGET_2ND_ARCH)_asan
+else
+ $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES := $(PRODUCT_OUT)/obj_$(TARGET_2ND_ARCH)
+endif
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES)/lib
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES := $(target_out_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
+else
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES := $(target_out_shared_libraries_base)/lib
+endif
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_RENDERSCRIPT_BITCODE := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_EXECUTABLES := $(TARGET_OUT_EXECUTABLES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_APPS := $(TARGET_OUT_APPS)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_APPS_PRIVILEGED := $(TARGET_OUT_APPS_PRIVILEGED)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_TESTCASES := $(TARGET_OUT_TESTCASES)
TARGET_OUT_DATA := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_DATA)
TARGET_OUT_DATA_EXECUTABLES := $(TARGET_OUT_EXECUTABLES)
@@ -369,14 +499,19 @@
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_EXECUTABLES := $(TARGET_OUT_DATA_EXECUTABLES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_SHARED_LIBRARIES := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_APPS := $(TARGET_OUT_DATA_APPS)
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest/$(TARGET_2ND_ARCH)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_METRIC_TESTS := $(TARGET_OUT_DATA)/benchmarktest/$(TARGET_2ND_ARCH)
+else
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_METRIC_TESTS := $(TARGET_OUT_DATA)/benchmarktest
+endif
TARGET_OUT_CACHE := $(PRODUCT_OUT)/cache
TARGET_OUT_VENDOR := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)
ifneq ($(filter address,$(SANITIZE_TARGET)),)
-target_out_vendor_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_DATA)/vendor
+target_out_vendor_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ASAN)/vendor
else
target_out_vendor_shared_libraries_base := $(TARGET_OUT_VENDOR)
endif
@@ -388,13 +523,21 @@
else
TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(target_out_vendor_shared_libraries_base)/lib
endif
+TARGET_OUT_VENDOR_RENDERSCRIPT_BITCODE := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)
TARGET_OUT_VENDOR_JAVA_LIBRARIES := $(TARGET_OUT_VENDOR)/framework
TARGET_OUT_VENDOR_APPS := $(TARGET_OUT_VENDOR)/app
+TARGET_OUT_VENDOR_APPS_PRIVILEGED := $(TARGET_OUT_VENDOR)/priv-app
TARGET_OUT_VENDOR_ETC := $(TARGET_OUT_VENDOR)/etc
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_EXECUTABLES := $(TARGET_OUT_VENDOR_EXECUTABLES)
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(target_out_vendor_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
+else
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(target_out_vendor_shared_libraries_base)/lib
+endif
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_RENDERSCRIPT_BITCODE := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS := $(TARGET_OUT_VENDOR_APPS)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS_PRIVILEGED := $(TARGET_OUT_VENDOR_APPS_PRIVILEGED)
TARGET_OUT_OEM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_OEM)
TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM)/bin
@@ -409,7 +552,11 @@
TARGET_OUT_OEM_ETC := $(TARGET_OUT_OEM)/etc
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM_EXECUTABLES)
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib/$(TARGET_2ND_ARCH)
+else
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib
+endif
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_APPS := $(TARGET_OUT_OEM_APPS)
TARGET_OUT_ODM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ODM)
@@ -423,7 +570,11 @@
TARGET_OUT_ODM_ETC := $(TARGET_OUT_ODM)/etc
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM_EXECUTABLES)
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib/$(TARGET_2ND_ARCH)
+else
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib
+endif
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM_APPS)
TARGET_OUT_BREAKPAD := $(PRODUCT_OUT)/breakpad
@@ -435,6 +586,7 @@
TARGET_ROOT_OUT_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)
TARGET_ROOT_OUT_SBIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/sbin
TARGET_ROOT_OUT_BIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/bin
+TARGET_OUT_COVERAGE := $(PRODUCT_OUT)/coverage
TARGET_ROOT_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ROOT)
TARGET_ROOT_OUT_BIN := $(TARGET_ROOT_OUT)/bin
@@ -455,16 +607,22 @@
TARGET_INSTALLER_SYSTEM_OUT := $(TARGET_INSTALLER_OUT)/root/system
COMMON_MODULE_CLASSES := TARGET-NOTICE_FILES HOST-NOTICE_FILES HOST-JAVA_LIBRARIES
-PER_ARCH_MODULE_CLASSES := SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP RENDERSCRIPT_BITCODE
+PER_ARCH_MODULE_CLASSES := SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP RENDERSCRIPT_BITCODE NATIVE_TESTS HEADER_LIBRARIES
ifeq (,$(strip $(DIST_DIR)))
DIST_DIR := $(OUT_DIR)/dist
endif
-ifeq ($(PRINT_BUILD_CONFIG),)
-PRINT_BUILD_CONFIG := true
+ifndef KATI
+PRINT_BUILD_CONFIG ?= true
endif
ifeq ($(USE_CLANG_PLATFORM_BUILD),)
USE_CLANG_PLATFORM_BUILD := true
endif
+
+ifneq ($(USE_CLANG_PLATFORM_BUILD),true)
+ifneq ($(USE_CLANG_PLATFORM_BUILD),false)
+$(error USE_CLANG_PLATFORM_BUILD must be true or false)
+endif
+endif
diff --git a/core/executable.mk b/core/executable.mk
index e22ea0e..f1b2462 100644
--- a/core/executable.mk
+++ b/core/executable.mk
@@ -16,17 +16,29 @@
endif
ifneq (true,$(my_skip_this_target))
+$(call record-module-type,EXECUTABLE)
+
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+# If a native test explicity specifies to build only for the translation arch,
+# we'll still need LOCAL_MULTILIB=both and let module_arch_supported.mk choose
+# to build only for TARGET_2ND_ARCH.
+ifneq (1,$(words $(LOCAL_MODULE_TARGET_ARCH)))
+LOCAL_MULTILIB := first
+endif
+endif
my_prefix := TARGET_
include $(BUILD_SYSTEM)/multilib.mk
ifeq ($(my_module_multilib),both)
+ifneq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
ifeq ($(LOCAL_MODULE_PATH_32)$(LOCAL_MODULE_STEM_32),)
$(error $(LOCAL_PATH): LOCAL_MODULE_STEM_32 or LOCAL_MODULE_PATH_32 is required for LOCAL_MULTILIB := both for module $(LOCAL_MODULE))
endif
ifeq ($(LOCAL_MODULE_PATH_64)$(LOCAL_MODULE_STEM_64),)
$(error $(LOCAL_PATH): LOCAL_MODULE_STEM_64 or LOCAL_MODULE_PATH_64 is required for LOCAL_MULTILIB := both for module $(LOCAL_MODULE))
endif
+endif
else #!LOCAL_MULTILIB == both
LOCAL_NO_2ND_ARCH_MODULE_SUFFIX := true
endif
diff --git a/core/executable_internal.mk b/core/executable_internal.mk
index febea98..3509bd2 100644
--- a/core/executable_internal.mk
+++ b/core/executable_internal.mk
@@ -34,36 +34,30 @@
endif
# Define PRIVATE_ variables from global vars
-my_target_global_ld_dirs := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LD_DIRS)
ifeq ($(LOCAL_NO_LIBGCC),true)
my_target_libgcc :=
else
-my_target_libgcc := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCC)
+my_target_libgcc := $(call intermediates-dir-for,STATIC_LIBRARIES,libgcc,,,$(LOCAL_2ND_ARCH_VAR_PREFIX))/libgcc.a
endif
-my_target_libatomic := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBATOMIC)
+my_target_libatomic := $(call intermediates-dir-for,STATIC_LIBRARIES,libatomic,,,$(LOCAL_2ND_ARCH_VAR_PREFIX))/libatomic.a
ifeq ($(LOCAL_NO_CRT),true)
my_target_crtbegin_dynamic_o :=
my_target_crtbegin_static_o :=
my_target_crtend_o :=
+else ifdef LOCAL_USE_VNDK
+my_target_crtbegin_dynamic_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.vendor.o
+my_target_crtbegin_static_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.vendor.o
+my_target_crtend_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.vendor.o
else
-my_target_crtbegin_dynamic_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_DYNAMIC_O)
-my_target_crtbegin_static_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_STATIC_O)
-my_target_crtend_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTEND_O)
+my_target_crtbegin_dynamic_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
+my_target_crtbegin_static_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
+my_target_crtend_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
endif
-ifdef LOCAL_SDK_VERSION
-# Make sure the prebuilt NDK paths are put ahead of the TARGET_GLOBAL_LD_DIRS,
-# so we don't have race condition when the system libraries (such as libc, libstdc++) are also built in the tree.
-my_target_global_ld_dirs := \
- $(addprefix -L, $(patsubst %/,%,$(dir $(my_ndk_stl_shared_lib_fullpath))) \
- $(my_ndk_sysroot_lib)) \
- $(my_target_global_ld_dirs)
-my_target_global_ldflags := $(my_ndk_stl_shared_lib) $(my_target_global_ldflags)
+ifneq ($(LOCAL_SDK_VERSION),)
my_target_crtbegin_dynamic_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_dynamic.o)
my_target_crtbegin_static_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_static.o)
my_target_crtend_o := $(wildcard $(my_ndk_sysroot_lib)/crtend_android.o)
endif
-$(linked_module): PRIVATE_TARGET_GLOBAL_LD_DIRS := $(my_target_global_ld_dirs)
-$(linked_module): PRIVATE_TARGET_GLOBAL_LDFLAGS := $(my_target_global_ldflags)
$(linked_module): PRIVATE_TARGET_LIBGCC := $(my_target_libgcc)
$(linked_module): PRIVATE_TARGET_LIBATOMIC := $(my_target_libatomic)
$(linked_module): PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O := $(my_target_crtbegin_dynamic_o)
@@ -73,11 +67,11 @@
$(linked_module): PRIVATE_POST_LINK_CMD := $(LOCAL_POST_LINK_CMD)
ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
-$(linked_module): $(my_target_crtbegin_static_o) $(all_objects) $(all_libraries) $(my_target_crtend_o)
+$(linked_module): $(my_target_crtbegin_static_o) $(all_objects) $(all_libraries) $(my_target_crtend_o) $(my_target_libgcc) $(my_target_libatomic)
$(transform-o-to-static-executable)
$(PRIVATE_POST_LINK_CMD)
else
-$(linked_module): $(my_target_crtbegin_dynamic_o) $(all_objects) $(all_libraries) $(my_target_crtend_o)
+$(linked_module): $(my_target_crtbegin_dynamic_o) $(all_objects) $(all_libraries) $(my_target_crtend_o) $(my_target_libgcc) $(my_target_libatomic)
$(transform-o-to-executable)
$(PRIVATE_POST_LINK_CMD)
endif
diff --git a/core/executable_prefer_symlink.mk b/core/executable_prefer_symlink.mk
index 931550f..9b9814e 100644
--- a/core/executable_prefer_symlink.mk
+++ b/core/executable_prefer_symlink.mk
@@ -10,43 +10,33 @@
# et al. since those variables make no sense in that context.
ifneq ($(LOCAL_IS_HOST_MODULE),true)
my_symlink := $(addprefix $(TARGET_OUT)/bin/, $(LOCAL_MODULE))
+ my_src_binary_name :=
ifeq ($(TARGET_IS_64_BIT),true)
ifeq ($(TARGET_SUPPORTS_64_BIT_APPS)|$(TARGET_SUPPORTS_32_BIT_APPS),true|true)
# We support both 32 and 64 bit apps, so we will have to
# base our decision on whether the target prefers one or the
# other.
ifeq ($(TARGET_PREFER_32_BIT_APPS),true)
- $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
+ my_src_binary_name := $(LOCAL_MODULE_STEM_32)
else
- $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_64)
+ my_src_binary_name := $(LOCAL_MODULE_STEM_64)
endif
else ifeq ($(TARGET_SUPPORTS_64_BIT_APPS),true)
# We support only 64 bit apps.
- $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_64)
+ my_src_binary_name := $(LOCAL_MODULE_STEM_64)
else
# We support only 32 bit apps.
- $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
+ my_src_binary_name := $(LOCAL_MODULE_STEM_32)
endif
else
- $(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
+ my_src_binary_name := $(LOCAL_MODULE_STEM_32)
endif
else
my_symlink := $(addprefix $(HOST_OUT)/bin/, $(LOCAL_MODULE))
- ifneq ($(HOST_PREFER_32_BIT),true)
-$(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_64)
- else
-$(my_symlink): PRIVATE_SRC_BINARY_NAME := $(LOCAL_MODULE_STEM_32)
- endif
+ my_src_binary_name := $(LOCAL_MODULE_STEM_64)
endif
-# $(my_symlink) doesn't need to depend on $(PRIVATE_SRC_BINARY_NAME): we can generate symlink to nonexistent file.
-# If you add the dependency, make would compare the timestamp of a file against that of its symlink:
-# they are always equal, because make follows symlink.
-$(my_symlink): $(LOCAL_MODULE_MAKEFILE_DEP)
- @echo "Symlink: $@ -> $(PRIVATE_SRC_BINARY_NAME)"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf $(PRIVATE_SRC_BINARY_NAME) $@
+$(call symlink-file,$(my_module_path)/$(my_src_binary_name),$(my_src_binary_name),$(my_symlink))
# We need this so that the installed files could be picked up based on the
# local module name
diff --git a/core/fuzz_test.mk b/core/fuzz_test.mk
index fc582b3..4d41871 100644
--- a/core/fuzz_test.mk
+++ b/core/fuzz_test.mk
@@ -2,13 +2,14 @@
## A thin wrapper around BUILD_EXECUTABLE
## Common flags for fuzz tests are added.
###########################################
+$(call record-module-type,FUZZ_TEST)
ifdef LOCAL_SDK_VERSION
$(error $(LOCAL_PATH): $(LOCAL_MODULE): NDK fuzz tests are not supported.)
endif
-LOCAL_CFLAGS += -fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp
-LOCAL_STATIC_LIBRARIES += libLLVMFuzzer
+LOCAL_CFLAGS += -fsanitize-coverage=trace-pc-guard
+LOCAL_STATIC_LIBRARIES += libFuzzer
ifdef LOCAL_MODULE_PATH
$(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH when building test $(LOCAL_MODULE))
@@ -22,8 +23,8 @@
$(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH_64 when building test $(LOCAL_MODULE))
endif
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
-LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/fuzzers/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/fuzzers/$(LOCAL_MODULE)
ifndef LOCAL_MULTILIB
ifndef LOCAL_32_BIT_ONLY
diff --git a/core/generate_enforce_rro.mk b/core/generate_enforce_rro.mk
new file mode 100644
index 0000000..579089c
--- /dev/null
+++ b/core/generate_enforce_rro.mk
@@ -0,0 +1,30 @@
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := $(enforce_rro_module)
+
+intermediates := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)
+rro_android_manifest_file := $(intermediates)/AndroidManifest.xml
+
+ifeq (true,$(enforce_rro_source_is_manifest_package_name))
+$(rro_android_manifest_file): PRIVATE_PACKAGE_NAME := $(enforce_rro_source_manifest_package_info)
+$(rro_android_manifest_file): build/tools/generate-enforce-rro-android-manifest.py
+ $(hide) build/tools/generate-enforce-rro-android-manifest.py -u -p $(PRIVATE_PACKAGE_NAME) -o $@
+else
+$(rro_android_manifest_file): PRIVATE_SOURCE_MANIFEST_FILE := $(enforce_rro_source_manifest_package_info)
+$(rro_android_manifest_file): $(enforce_rro_source_manifest_package_info) build/tools/generate-enforce-rro-android-manifest.py
+ $(hide) build/tools/generate-enforce-rro-android-manifest.py -p $(PRIVATE_SOURCE_MANIFEST_FILE) -o $@
+endif
+
+LOCAL_PATH:= $(intermediates)
+
+ifeq ($(enforce_rro_use_res_lib),true)
+LOCAL_RES_LIBRARIES := $(enforce_rro_source_module)
+endif
+
+LOCAL_FULL_MANIFEST_FILE := $(rro_android_manifest_file)
+LOCAL_CERTIFICATE := platform
+
+LOCAL_AAPT_FLAGS += --auto-add-overlay
+LOCAL_RESOURCE_DIR := $(enforce_rro_source_overlays)
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/core/goma.mk b/core/goma.mk
index 6535b3e..4e8318a 100644
--- a/core/goma.mk
+++ b/core/goma.mk
@@ -14,18 +14,11 @@
# limitations under the License.
#
+# Used by the compiler wrapper, but should only be set by gomacc
+unexport GOMACC_PATH
+
# Notice: this works only with Google's Goma build infrastructure.
ifneq ($(filter-out false,$(USE_GOMA)),)
- # Check if USE_NINJA is not false because GNU make won't work well
- # with goma. Note this file is evaluated twice, once by GNU make and
- # once by kati with USE_NINJA=false. We do this check in the former
- # pass.
- ifndef KATI
- ifeq ($(USE_NINJA),false)
- $(error USE_GOMA=true is not compatible with USE_NINJA=false)
- endif
- endif
-
# Goma requires a lot of processes and file descriptors.
ifeq ($(shell echo $$(($$(ulimit -u) < 2500 || $$(ulimit -n) < 16000))),1)
$(warning Max user processes and/or open files are insufficient)
@@ -56,11 +49,9 @@
# gomacc can start goma client's daemon process automatically, but
# it is safer and faster to start up it beforehand. We run this as a
# background process so this won't slow down the build.
- # We use "ensure_start" command when the compiler_proxy is already
- # running and uses GOMA_HERMETIC=error flag. The compiler_proxy will
- # restart otherwise.
- # TODO(hamaji): Remove this condition after http://b/25676777 is fixed.
- $(shell ( if ( curl http://localhost:$$($(GOMA_CC) port)/flagz | grep GOMA_HERMETIC=error ); then cmd=ensure_start; else cmd=restart; fi; GOMA_HERMETIC=error $(goma_ctl) $${cmd} ) &> /dev/null &)
+ ifndef NOSTART_GOMA
+ $(shell ( $(goma_ctl) ensure_start ) &> /dev/null &)
+ endif
goma_ctl :=
goma_dir :=
diff --git a/core/header_library.mk b/core/header_library.mk
new file mode 100644
index 0000000..5144679
--- /dev/null
+++ b/core/header_library.mk
@@ -0,0 +1,72 @@
+$(call record-module-type,HEADER_LIBRARY)
+ifdef LOCAL_IS_HOST_MODULE
+ my_prefix := HOST_
+ LOCAL_HOST_PREFIX :=
+else
+ my_prefix := TARGET_
+endif
+include $(BUILD_SYSTEM)/multilib.mk
+
+ifndef my_module_multilib
+ # libraries default to building for both architecturess
+ my_module_multilib := both
+endif
+
+LOCAL_2ND_ARCH_VAR_PREFIX :=
+include $(BUILD_SYSTEM)/module_arch_supported.mk
+
+ifeq ($(my_module_arch_supported),true)
+ include $(BUILD_SYSTEM)/header_library_internal.mk
+endif
+
+ifdef $(my_prefix)2ND_ARCH
+ LOCAL_2ND_ARCH_VAR_PREFIX := $($(my_prefix)2ND_ARCH_VAR_PREFIX)
+ include $(BUILD_SYSTEM)/module_arch_supported.mk
+
+ ifeq ($(my_module_arch_supported),true)
+ # Build for 2ND_ARCH
+ OVERRIDE_BUILT_MODULE_PATH :=
+ LOCAL_BUILT_MODULE :=
+ LOCAL_INSTALLED_MODULE :=
+ LOCAL_INTERMEDIATE_TARGETS :=
+ include $(BUILD_SYSTEM)/header_library_internal.mk
+ endif
+ LOCAL_2ND_ARCH_VAR_PREFIX :=
+endif # 2ND_ARCH
+
+ifdef LOCAL_IS_HOST_MODULE
+ ifdef HOST_CROSS_OS
+ my_prefix := HOST_CROSS_
+ LOCAL_HOST_PREFIX := $(my_prefix)
+
+ include $(BUILD_SYSTEM)/module_arch_supported.mk
+
+ ifeq ($(my_module_arch_supported),true)
+ # Build for 2ND_ARCH
+ OVERRIDE_BUILT_MODULE_PATH :=
+ LOCAL_BUILT_MODULE :=
+ LOCAL_INSTALLED_MODULE :=
+ LOCAL_INTERMEDIATE_TARGETS :=
+ include $(BUILD_SYSTEM)/header_library_internal.mk
+ endif
+
+ ifdef HOST_CROSS_2ND_ARCH
+ LOCAL_2ND_ARCH_VAR_PREFIX := $(HOST_CROSS_2ND_ARCH_VAR_PREFIX)
+ include $(BUILD_SYSTEM)/module_arch_supported.mk
+
+ ifeq ($(my_module_arch_supported),true)
+ # Build for HOST_CROSS_2ND_ARCH
+ OVERRIDE_BUILT_MODULE_PATH :=
+ LOCAL_BUILT_MODULE :=
+ LOCAL_INSTALLED_MODULE :=
+ LOCAL_INTERMEDIATE_TARGETS :=
+ include $(BUILD_SYSTEM)/header_library_internal.mk
+ endif
+ LOCAL_2ND_ARCH_VAR_PREFIX :=
+ endif
+
+ LOCAL_HOST_PREFIX :=
+ endif
+endif
+
+my_module_arch_supported :=
diff --git a/core/header_library_internal.mk b/core/header_library_internal.mk
new file mode 100644
index 0000000..35ee1bc
--- /dev/null
+++ b/core/header_library_internal.mk
@@ -0,0 +1,21 @@
+###########################################################
+## Standard rules for building a header library.
+##
+## Additional inputs from base_rules.make:
+## None.
+###########################################################
+
+LOCAL_MODULE_CLASS := HEADER_LIBRARIES
+LOCAL_UNINSTALLABLE_MODULE := true
+ifneq ($(strip $(LOCAL_MODULE_STEM)$(LOCAL_BUILT_MODULE_STEM)),)
+$(error $(LOCAL_PATH): Cannot set module stem for a library)
+endif
+
+include $(BUILD_SYSTEM)/binary.mk
+
+ifneq ($(strip $(all_objects)),)
+$(call pretty-error,Header libraries may not have any sources)
+endif
+
+$(LOCAL_BUILT_MODULE):
+ $(hide) touch $@
diff --git a/core/help.mk b/core/help.mk
index 6e0b2c0..c034e79 100644
--- a/core/help.mk
+++ b/core/help.mk
@@ -22,6 +22,7 @@
@echo "droid Default target"
@echo "clean (aka clobber) equivalent to rm -rf out/"
@echo "snod Quickly rebuild the system image from built packages"
+ @echo "vnod Quickly rebuild the vendor image from built packages"
@echo "offline-sdk-docs Generate the HTML for the developer SDK docs"
@echo "doc-comment-check-docs Check HTML doc links & validity, without generating HTML"
@echo "libandroid_runtime All the JNI framework stuff"
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index 83047d4..7101229 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+$(call record-module-type,HOST_DALVIK_JAVA_LIBRARY)
#
# Rules for building a host dalvik java library. These libraries
@@ -23,15 +24,26 @@
ifeq ($(HOST_OS),linux)
USE_CORE_LIB_BOOTCLASSPATH := true
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
#######################################
include $(BUILD_SYSTEM)/host_java_library_common.mk
#######################################
+ifdef LOCAL_JACK_ENABLED
+ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
+ # For static library, $(LOCAL_BUILT_MODULE) is $(full_classes_jack).
+ LOCAL_BUILT_MODULE_STEM := classes.jack
+endif
+endif
ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
- LOCAL_JAVA_LIBRARIES += core-oj-hostdex core-libart-hostdex
+ LOCAL_JAVA_LIBRARIES := core-oj-hostdex core-libart-hostdex $(LOCAL_JAVA_LIBRARIES)
endif
full_classes_compiled_jar := $(intermediates.COMMON)/classes-full-debug.jar
+full_classes_desugar_jar := $(intermediates.COMMON)/desugar.classes.jar
full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar
full_classes_jar := $(intermediates.COMMON)/classes.jar
full_classes_jack := $(intermediates.COMMON)/classes.jack
@@ -40,6 +52,7 @@
LOCAL_INTERMEDIATE_TARGETS += \
$(full_classes_compiled_jar) \
+ $(full_classes_desugar_jar) \
$(full_classes_jarjar_jar) \
$(full_classes_jack) \
$(full_classes_jar) \
@@ -51,7 +64,11 @@
ifdef LOCAL_JACK_ENABLED
LOCAL_CHECKED_MODULE := $(jack_check_timestamp)
else
+ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
LOCAL_CHECKED_MODULE := $(full_classes_compiled_jar)
+else
+LOCAL_CHECKED_MODULE := $(built_dex)
+endif
endif
endif
@@ -64,14 +81,12 @@
include $(BUILD_SYSTEM)/java_common.mk
-# The layers file allows you to enforce a layering between java packages.
-# Run build/tools/java-layers.py for more details.
-layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
-
$(cleantarget): PRIVATE_CLEAN_FILES += $(intermediates.COMMON)
+ifndef LOCAL_JACK_ENABLED
+
$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
-$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JAVACFLAGS)
+$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES :=
$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES :=
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_PACKAGES :=
@@ -81,27 +96,48 @@
$(full_java_lib_deps) \
$(jar_manifest_file) \
$(proto_java_sources_file_stamp) \
- $(LOCAL_MODULE_MAKEFILE_DEP) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(annotation_processor_deps) \
+ $(NORMALIZE_PATH) \
+ $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+ | $(SOONG_JAVAC_WRAPPER)
$(transform-host-java-to-package)
+my_desugaring :=
+ifeq ($(LOCAL_JAVA_LANGUAGE_VERSION),1.8)
+my_desugaring := true
+$(full_classes_desugar_jar): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
+$(full_classes_desugar_jar): $(full_classes_compiled_jar) $(DESUGAR)
+ $(desugar-classes-jar)
+endif
+
+ifndef my_desugaring
+full_classes_desugar_jar := $(full_classes_compiled_jar)
+endif
+
# Run jarjar if necessary, otherwise just copy the file.
ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
$(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
-$(full_classes_jarjar_jar): $(full_classes_compiled_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
+$(full_classes_jarjar_jar): $(full_classes_desugar_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
@echo JarJar: $@
$(hide) java -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
else
-$(full_classes_jarjar_jar): $(full_classes_compiled_jar) | $(ACP)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
+full_classes_jarjar_jar := $(full_classes_desugar_jar)
endif
-$(full_classes_jar): $(full_classes_jarjar_jar) | $(ACP)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
+$(eval $(call copy-one-file,$(full_classes_jarjar_jar),$(full_classes_jar)))
-ifndef LOCAL_JACK_ENABLED
+ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
+# No dex; all we want are the .class files with resources.
+$(LOCAL_BUILT_MODULE) : $(java_resource_sources)
+$(LOCAL_BUILT_MODULE) : $(full_classes_jar)
+ @echo "host Static Jar: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-target)
+
+else # !LOCAL_IS_STATIC_JAVA_LIBRARY
+$(built_dex): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
+$(built_dex): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
+$(built_dex): $(full_classes_jar) $(DX)
+ $(transform-classes.jar-to-dex)
$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
$(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
@@ -111,33 +147,43 @@
$(call initialize-package-file,$(PRIVATE_SOURCE_ARCHIVE),$@)
$(add-dex-to-package)
+endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
+
+ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SDK_VERSION := $(LOCAL_SDK_VERSION)
+else
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SDK_VERSION := $(PLATFORM_SDK_VERSION)
+endif
+
else # LOCAL_JACK_ENABLED
$(LOCAL_INTERMEDIATE_TARGETS): \
- PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
+ PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
ifeq ($(LOCAL_JACK_ENABLED),incremental)
$(LOCAL_INTERMEDIATE_TARGETS): \
- PRIVATE_JACK_INCREMENTAL_DIR := $(intermediates.COMMON)/jack-incremental
+ PRIVATE_JACK_INCREMENTAL_DIR := $(intermediates.COMMON)/jack-incremental
else
$(LOCAL_INTERMEDIATE_TARGETS): \
- PRIVATE_JACK_INCREMENTAL_DIR :=
+ PRIVATE_JACK_INCREMENTAL_DIR :=
endif
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_FLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JACK_FLAGS)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_VERSION := $(LOCAL_JACK_VERSION)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_MIN_SDK_VERSION := $(PLATFORM_JACK_MIN_SDK_VERSION)
jack_all_deps := $(java_sources) $(java_resource_sources) $(full_jack_deps) \
- $(jar_manifest_file) $(proto_java_sources_file_stamp) $(LOCAL_MODULE_MAKEFILE_DEP) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES) $(JACK)
+ $(jar_manifest_file) $(proto_java_sources_file_stamp) \
+ $(LOCAL_ADDITIONAL_DEPENDENCIES) $(NORMALIZE_PATH) $(JACK_DEFAULT_ARGS) $(JACK)
+
+ifneq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
$(built_dex): PRIVATE_CLASSES_JACK := $(full_classes_jack)
-$(built_dex): $(jack_all_deps) | setup-jack-server
+$(built_dex): PRIVATE_JACK_PLUGIN_PATH := $(LOCAL_JACK_PLUGIN_PATH)
+$(built_dex): PRIVATE_JACK_PLUGIN := $(LOCAL_JACK_PLUGIN)
+$(built_dex): $(jack_all_deps) $(LOCAL_JACK_PLUGIN_PATH) | setup-jack-server
@echo Building with Jack: $@
$(jack-java-to-dex)
-$(jack_check_timestamp): $(jack_all_deps) | setup-jack-server
- @echo Checking build with Jack: $@
- $(jack-check-java)
-
# $(full_classes_jack) is just by-product of $(built_dex).
# The dummy command was added because, without it, make misses the fact the $(built_dex) also
# change $(full_classes_jack).
@@ -151,6 +197,18 @@
$(add-dex-to-package)
$(add-carried-jack-resources)
+else # LOCAL_IS_STATIC_JAVA_LIBRARY
+$(full_classes_jack): PRIVATE_JACK_PLUGIN_PATH := $(LOCAL_JACK_PLUGIN_PATH)
+$(full_classes_jack): PRIVATE_JACK_PLUGIN := $(LOCAL_JACK_PLUGIN)
+$(full_classes_jack): $(jack_all_deps) $(LOCAL_JACK_PLUGIN_PATH) | setup-jack-server
+ @echo Building with Jack: $@
+ $(java-to-jack)
+
+endif # LOCAL_IS_STATIC_JAVA_LIBRARY
+
+$(jack_check_timestamp): $(jack_all_deps) | setup-jack-server
+ @echo Checking build with Jack: $@
+ $(jack-check-java)
endif # LOCAL_JACK_ENABLED
USE_CORE_LIB_BOOTCLASSPATH :=
diff --git a/core/host_dalvik_static_java_library.mk b/core/host_dalvik_static_java_library.mk
index c296be3..78faf73 100644
--- a/core/host_dalvik_static_java_library.mk
+++ b/core/host_dalvik_static_java_library.mk
@@ -13,48 +13,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+$(call record-module-type,HOST_DALVIK_STATIC_JAVA_LIBRARY)
#
# Rules for building a host dalvik static java library.
# These libraries will be compiled against libcore and not the host
# JRE.
#
-ifeq ($(HOST_OS),linux)
-
LOCAL_UNINSTALLABLE_MODULE := true
LOCAL_IS_STATIC_JAVA_LIBRARY := true
-USE_CORE_LIB_BOOTCLASSPATH := true
-LOCAL_JAVA_LIBRARIES += core-oj-hostdex core-libart-hostdex
-intermediates.COMMON := $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE),true,COMMON,)
-full_classes_jack := $(intermediates.COMMON)/classes.jack
-LOCAL_INTERMEDIATE_TARGETS += \
- $(full_classes_jack)
+include $(BUILD_SYSTEM)/host_dalvik_java_library.mk
-include $(BUILD_SYSTEM)/host_java_library.mk
-# proguard is not supported
-# *.proto files are not supported
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_FLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JACK_FLAGS)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_VERSION := $(LOCAL_JACK_VERSION)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_MIN_SDK_VERSION := $(PLATFORM_JACK_MIN_SDK_VERSION)
-
-$(full_classes_jack): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
-$(full_classes_jack): \
- PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
-ifeq ($(LOCAL_JACK_ENABLED),incremental)
-$(full_classes_jack): \
- PRIVATE_JACK_INCREMENTAL_DIR := $(intermediates.COMMON)/jack-incremental
-else
-$(full_classes_jack): \
- PRIVATE_JACK_INCREMENTAL_DIR :=
-endif
-$(full_classes_jack): $(java_sources) $(java_resource_sources) $(full_jack_deps) \
- $(jar_manifest_file) $(layers_file) $(LOCAL_MODULE_MAKEFILE_DEP) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES) $(LOCAL_JARJAR_RULES) \
- $(JACK) | setup-jack-server
- @echo Building with Jack: $@
- $(java-to-jack)
-
-USE_CORE_LIB_BOOTCLASSPATH :=
LOCAL_IS_STATIC_JAVA_LIBRARY :=
-endif
diff --git a/core/host_executable.mk b/core/host_executable.mk
index 6f19bd1..1480c2c 100644
--- a/core/host_executable.mk
+++ b/core/host_executable.mk
@@ -1,3 +1,4 @@
+$(call record-module-type,HOST_EXECUTABLE)
LOCAL_IS_HOST_MODULE := true
my_prefix := HOST_
LOCAL_HOST_PREFIX :=
@@ -5,26 +6,24 @@
ifndef LOCAL_MODULE_HOST_ARCH
ifndef my_module_multilib
-ifeq ($(HOST_PREFER_32_BIT),true)
-my_module_multilib := 32
-else
# By default we only build host module for the first arch.
my_module_multilib := first
endif
endif
-endif
ifeq ($(LOCAL_NO_FPIE),)
LOCAL_LDFLAGS += $(HOST_FPIE_FLAGS)
endif
ifeq ($(my_module_multilib),both)
+ifneq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
ifeq ($(LOCAL_MODULE_PATH_32)$(LOCAL_MODULE_STEM_32),)
$(error $(LOCAL_PATH): LOCAL_MODULE_STEM_32 or LOCAL_MODULE_PATH_32 is required for LOCAL_MULTILIB := both for module $(LOCAL_MODULE))
endif
ifeq ($(LOCAL_MODULE_PATH_64)$(LOCAL_MODULE_STEM_64),)
$(error $(LOCAL_PATH): LOCAL_MODULE_STEM_64 or LOCAL_MODULE_PATH_64 is required for LOCAL_MULTILIB := both for module $(LOCAL_MODULE))
endif
+endif
else #!LOCAL_MULTILIB == both
LOCAL_NO_2ND_ARCH_MODULE_SUFFIX := true
endif
diff --git a/core/host_executable_internal.mk b/core/host_executable_internal.mk
index b682ffd..19200fd 100644
--- a/core/host_executable_internal.mk
+++ b/core/host_executable_internal.mk
@@ -29,6 +29,14 @@
my_host_libprofile_rt := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LIBPROFILE_RT)
$(LOCAL_BUILT_MODULE): PRIVATE_HOST_LIBPROFILE_RT := $(my_host_libprofile_rt)
+my_libdir := $(notdir $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_SHARED_LIBRARIES))
+ifeq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
+$(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../../$(my_libdir)
+else
+$(LOCAL_BUILT_MODULE): PRIVATE_RPATHS := ../$(my_libdir) $(my_libdir)
+endif
+my_libdir :=
+
$(LOCAL_BUILT_MODULE): $(all_objects) $(all_libraries)
$(transform-host-o-to-executable)
diff --git a/core/host_fuzz_test.mk b/core/host_fuzz_test.mk
index cc7baad..1c9eed2 100644
--- a/core/host_fuzz_test.mk
+++ b/core/host_fuzz_test.mk
@@ -2,6 +2,7 @@
## A thin wrapper around BUILD_HOST_EXECUTABLE
## Common flags for host fuzz tests are added.
################################################
+$(call record-module-type,HOST_FUZZ_TEST)
LOCAL_CFLAGS += -fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp
LOCAL_STATIC_LIBRARIES += libLLVMFuzzer
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index 97079fd..d30c90d 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -14,6 +14,8 @@
# limitations under the License.
#
+$(call record-module-type,HOST_JAVA_LIBRARY)
+
#
# Standard rules for building a host java library.
#
@@ -35,6 +37,7 @@
# emma is hardcoded to use the leaf name of its input for the output file --
# only the output directory can be changed
full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(notdir $(full_classes_jarjar_jar))
+full_classes_jar := $(intermediates.COMMON)/classes.jar
LOCAL_INTERMEDIATE_TARGETS += \
$(full_classes_compiled_jar) \
@@ -55,8 +58,13 @@
# Run build/tools/java-layers.py for more details.
layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
+# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
+ifeq ($(RUN_ERROR_PRONE),true)
+LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
+endif
+
$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
-$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JAVACFLAGS)
+$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES :=
$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES :=
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_PACKAGES :=
@@ -66,9 +74,16 @@
$(full_java_lib_deps) \
$(jar_manifest_file) \
$(proto_java_sources_file_stamp) \
- $(LOCAL_MODULE_MAKEFILE_DEP) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(annotation_processor_deps) \
+ $(NORMALIZE_PATH) \
+ $(ZIPTIME) \
+ $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+ | $(SOONG_JAVAC_WRAPPER)
$(transform-host-java-to-package)
+ $(remove-timestamps-from-package)
+
+javac-check : $(full_classes_compiled_jar)
+javac-check-$(LOCAL_MODULE) : $(full_classes_compiled_jar)
# Run jarjar if necessary, otherwise just copy the file.
ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
@@ -77,9 +92,7 @@
@echo JarJar: $@
$(hide) java -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
else
-$(full_classes_jarjar_jar): $(full_classes_compiled_jar) | $(ACP)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
+full_classes_jarjar_jar := $(full_classes_compiled_jar)
endif
ifeq (true,$(LOCAL_EMMA_INSTRUMENT))
@@ -96,14 +109,9 @@
# $(full_classes_emma_jar)
$(full_classes_emma_jar) : $(full_classes_jarjar_jar) | $(EMMA_JAR)
$(transform-classes.jar-to-emma)
-
-$(built_javalib_jar) : $(full_classes_emma_jar)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
-
else # LOCAL_EMMA_INSTRUMENT
-$(built_javalib_jar): $(full_classes_jarjar_jar) | $(ACP)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
+full_classes_emma_jar := $(full_classes_jarjar_jar)
endif # LOCAL_EMMA_INSTRUMENT
+$(eval $(call copy-one-file,$(full_classes_emma_jar),$(LOCAL_BUILT_MODULE)))
+$(eval $(call copy-one-file,$(full_classes_emma_jar),$(full_classes_jar)))
diff --git a/core/host_java_library_common.mk b/core/host_java_library_common.mk
index 35a6e28..8df4b37 100644
--- a/core/host_java_library_common.mk
+++ b/core/host_java_library_common.mk
@@ -26,19 +26,6 @@
intermediates := $(call local-intermediates-dir)
intermediates.COMMON := $(call local-intermediates-dir,COMMON)
-built_javalib_jar := $(intermediates)/javalib.jar
-
-#################################
-include $(BUILD_SYSTEM)/configure_local_jack.mk
-#################################
-
-ifdef LOCAL_JACK_ENABLED
-ifdef LOCAL_IS_STATIC_JAVA_LIBRARY
-LOCAL_BUILT_MODULE_STEM := classes.jack
-LOCAL_INTERMEDIATE_TARGETS += $(built_javalib_jar)
-endif
-endif
-
# base_rules.mk looks at this
all_res_assets :=
@@ -61,4 +48,3 @@
LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
-
diff --git a/core/host_native_test.mk b/core/host_native_test.mk
index 7cba1ae..aa05bb3 100644
--- a/core/host_native_test.mk
+++ b/core/host_native_test.mk
@@ -2,25 +2,22 @@
## A thin wrapper around BUILD_HOST_EXECUTABLE
## Common flags for host native tests are added.
################################################
+$(call record-module-type,HOST_NATIVE_TEST)
+
+ifdef LOCAL_MODULE_CLASS
+ifneq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
+$(error $(LOCAL_PATH): LOCAL_MODULE_CLASS must be NATIVE_TESTS with BUILD_HOST_NATIVE_TEST)
+endif
+endif
+
+LOCAL_MODULE_CLASS := NATIVE_TESTS
include $(BUILD_SYSTEM)/host_test_internal.mk
-needs_symlink :=
ifndef LOCAL_MULTILIB
- ifndef LOCAL_32_BIT_ONLY
- LOCAL_MULTILIB := both
-
- ifeq (,$(LOCAL_MODULE_STEM_32)$(LOCAL_MODULE_STEM_64))
- LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
- LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
- needs_symlink := true
- endif
- endif
+ifndef LOCAL_32_BIT_ONLY
+LOCAL_MULTILIB := both
+endif
endif
include $(BUILD_HOST_EXECUTABLE)
-
-ifdef needs_symlink
-include $(BUILD_SYSTEM)/executable_prefer_symlink.mk
-needs_symlink :=
-endif
diff --git a/core/host_prebuilt.mk b/core/host_prebuilt.mk
index 7baab69..79f3ffa 100644
--- a/core/host_prebuilt.mk
+++ b/core/host_prebuilt.mk
@@ -14,5 +14,6 @@
# limitations under the License.
#
+$(call record-module-type,HOST_PREBUILT)
LOCAL_IS_HOST_MODULE := true
include $(BUILD_MULTI_PREBUILT)
diff --git a/core/host_shared_library.mk b/core/host_shared_library.mk
index 2e0c9f1c..5da7913 100644
--- a/core/host_shared_library.mk
+++ b/core/host_shared_library.mk
@@ -1,3 +1,4 @@
+$(call record-module-type,HOST_SHARED_LIBRARY)
LOCAL_IS_HOST_MODULE := true
my_prefix := HOST_
LOCAL_HOST_PREFIX :=
@@ -5,14 +6,10 @@
ifndef LOCAL_MODULE_HOST_ARCH
ifndef my_module_multilib
-ifeq ($(HOST_PREFER_32_BIT),true)
-my_module_multilib := 32
-else
# libraries default to building for both architecturess
my_module_multilib := both
endif
endif
-endif
LOCAL_2ND_ARCH_VAR_PREFIX :=
include $(BUILD_SYSTEM)/module_arch_supported.mk
diff --git a/core/host_shared_library_internal.mk b/core/host_shared_library_internal.mk
index 272e76f..bfbde21 100644
--- a/core/host_shared_library_internal.mk
+++ b/core/host_shared_library_internal.mk
@@ -44,7 +44,6 @@
$(LOCAL_BUILT_MODULE): \
$(all_objects) \
$(all_libraries) \
- $(LOCAL_MODULE_MAKEFILE_DEP) \
$(LOCAL_ADDITIONAL_DEPENDENCIES)
$(transform-host-o-to-shared-lib)
diff --git a/core/host_shared_test_lib.mk b/core/host_shared_test_lib.mk
index 1eb9b26..ed7e23a 100644
--- a/core/host_shared_test_lib.mk
+++ b/core/host_shared_test_lib.mk
@@ -1,8 +1 @@
-##################################################
-## A thin wrapper around BUILD_HOST_SHARED_LIBRARY
-## Common flags for host native tests are added.
-##################################################
-
-include $(BUILD_SYSTEM)/host_test_internal.mk
-
-include $(BUILD_HOST_SHARED_LIBRARY)
+$(error BUILD_HOST_SHARED_TEST_LIBRARY is obsolete)
diff --git a/core/host_static_library.mk b/core/host_static_library.mk
index 068c702..aa0421e 100644
--- a/core/host_static_library.mk
+++ b/core/host_static_library.mk
@@ -1,3 +1,4 @@
+$(call record-module-type,HOST_STATIC_LIBRARY)
LOCAL_IS_HOST_MODULE := true
my_prefix := HOST_
LOCAL_HOST_PREFIX :=
@@ -5,14 +6,10 @@
ifndef LOCAL_MODULE_HOST_ARCH
ifndef my_module_multilib
-ifeq ($(HOST_PREFER_32_BIT),true)
-my_module_multilib := 32
-else
# libraries default to building for both architecturess
my_module_multilib := both
endif
endif
-endif
LOCAL_2ND_ARCH_VAR_PREFIX :=
include $(BUILD_SYSTEM)/module_arch_supported.mk
diff --git a/core/host_static_test_lib.mk b/core/host_static_test_lib.mk
index 5423dc6..a24cd62 100644
--- a/core/host_static_test_lib.mk
+++ b/core/host_static_test_lib.mk
@@ -2,6 +2,7 @@
## A thin wrapper around BUILD_HOST_STATIC_LIBRARY
## Common flags for host native tests are added.
##################################################
+$(call record-module-type,HOST_STATIC_TEST_LIBRARY)
include $(BUILD_SYSTEM)/host_test_internal.mk
diff --git a/core/host_test_internal.mk b/core/host_test_internal.mk
index 7f6aff0..ffb22c7 100644
--- a/core/host_test_internal.mk
+++ b/core/host_test_internal.mk
@@ -2,13 +2,30 @@
## Shared definitions for all host test compilations.
#####################################################
-LOCAL_CFLAGS_windows += -DGTEST_OS_WINDOWS
-LOCAL_CFLAGS_linux += -DGTEST_OS_LINUX
-LOCAL_LDLIBS_linux += -lpthread
-LOCAL_CFLAGS_darwin += -DGTEST_OS_LINUX
-LOCAL_LDLIBS_darwin += -lpthread
+ifeq ($(LOCAL_GTEST),true)
+ LOCAL_CFLAGS_windows += -DGTEST_OS_WINDOWS
+ LOCAL_CFLAGS_linux += -DGTEST_OS_LINUX
+ LOCAL_LDLIBS_linux += -lpthread
+ LOCAL_CFLAGS_darwin += -DGTEST_OS_MAC
+ LOCAL_LDLIBS_darwin += -lpthread
-LOCAL_CFLAGS += -DGTEST_HAS_STD_STRING -O0 -g
-LOCAL_C_INCLUDES += external/gtest/include
+ LOCAL_CFLAGS += -DGTEST_HAS_STD_STRING -O0 -g
-LOCAL_STATIC_LIBRARIES += libgtest_main_host libgtest_host
+ LOCAL_STATIC_LIBRARIES += libgtest_main_host libgtest_host
+endif
+
+ifdef LOCAL_MODULE_PATH
+$(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH when building test $(LOCAL_MODULE))
+endif
+
+ifdef LOCAL_MODULE_PATH_32
+$(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH_32 when building test $(LOCAL_MODULE))
+endif
+
+ifdef LOCAL_MODULE_PATH_64
+$(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH_64 when building test $(LOCAL_MODULE))
+endif
+
+ifndef LOCAL_MODULE_RELATIVE_PATH
+LOCAL_MODULE_RELATIVE_PATH := $(LOCAL_MODULE)
+endif
diff --git a/core/install_jni_libs.mk b/core/install_jni_libs.mk
index 625a8a2..35f4f55 100644
--- a/core/install_jni_libs.mk
+++ b/core/install_jni_libs.mk
@@ -18,9 +18,19 @@
ifneq ($(filter tests samples, $(LOCAL_MODULE_TAGS)),)
my_embed_jni := true
endif
-ifeq ($(filter $(TARGET_OUT)/% $(TARGET_OUT_VENDOR)/% $(TARGET_OUT_OEM)/%, $(my_module_path)),)
-# If this app isn't to be installed to system partitions.
-my_embed_jni := true
+ifneq ($(BOARD_VNDK_VERSION),)
+ ifeq ($(filter $(TARGET_OUT)/%, $(my_module_path)),)
+ # If this app isn't to be installed to the system partition, and the device
+ # is fully treble-ized then jni libs are embedded, Otherwise, access to the
+ # directory where the lib is installed to (usually /vendor/lib) needs to be
+ # allowed for system processes, which is a Treble violation.
+ my_embed_jni := true
+ endif
+else
+ ifeq ($(filter $(TARGET_OUT)/% $(TARGET_OUT_VENDOR)/% $(TARGET_OUT_OEM)/%, $(my_module_path)),)
+ # If this app isn't to be installed to system, vendor, or oem partitions.
+ my_embed_jni := true
+ endif
endif
jni_shared_libraries :=
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index 27b9697..0e92153 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -32,10 +32,10 @@
endif
ifeq (stlport_shared,$(LOCAL_NDK_STL_VARIANT))
my_jni_shared_libraries += \
- $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources/cxx-stl/stlport/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libstlport_shared.so
+ $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources/cxx-stl/stlport/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libstlport_shared.so
else ifeq (c++_shared,$(LOCAL_NDK_STL_VARIANT))
my_jni_shared_libraries += \
- $(HISTORICAL_NDK_VERSIONS_ROOT)/current/sources/cxx-stl/llvm-libc++/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libc++_shared.so
+ $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources/cxx-stl/llvm-libc++/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libc++_shared.so
endif
# Set the abi directory used by the local JNI shared libraries.
@@ -54,11 +54,14 @@
# The jni libaries will be installed to the system.img.
my_jni_filenames := $(notdir $(my_jni_shared_libraries))
# Make sure the JNI libraries get installed
-my_shared_library_path := $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES)
+my_shared_library_path := $(call get_non_asan_path,\
+ $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES))
# Do not use order-only dependency, because we want to rebuild the image if an jni is updated.
$(LOCAL_INSTALLED_MODULE) : $(addprefix $(my_shared_library_path)/, $(my_jni_filenames))
# Create symlink in the app specific lib path
+# Skip creating this symlink when running the second part of a target sanitization build.
+ifndef SANITIZE_TARGET
ifdef LOCAL_POST_INSTALL_CMD
# Add a shell command separator
LOCAL_POST_INSTALL_CMD += ;
@@ -70,6 +73,11 @@
mkdir -p $(my_app_lib_path) \
$(foreach lib, $(my_jni_filenames), ;ln -sf $(my_symlink_target_dir)/$(lib) $(my_app_lib_path)/$(lib))
$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
+else
+ifdef LOCAL_POST_INSTALL_CMD
+$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
+endif
+endif
# Clear jni_shared_libraries to not embed it into the apk.
my_jni_shared_libraries :=
@@ -98,3 +106,21 @@
endif # my_embed_jni
endif # inner my_prebuilt_jni_libs
endif # outer my_prebuilt_jni_libs
+
+# Verify that all included libraries are built against the NDK
+ifneq ($(strip $(LOCAL_JNI_SHARED_LIBRARIES)),)
+ifneq ($(LOCAL_SDK_VERSION),)
+my_link_type := app:sdk
+my_warn_types := native:platform
+my_allowed_types := native:ndk
+else
+my_link_type := app:platform
+my_warn_types :=
+my_allowed_types := native:ndk native:platform
+endif
+
+my_link_deps := $(addprefix SHARED_LIBRARIES:,$(LOCAL_JNI_SHARED_LIBRARIES))
+
+my_common :=
+include $(BUILD_SYSTEM)/link_type.mk
+endif
diff --git a/core/jack-default.args b/core/jack-default.args
index 8d70a82..433bc53 100644
--- a/core/jack-default.args
+++ b/core/jack-default.args
@@ -2,4 +2,8 @@
-D sched.runner.thread.kind=fixed
-D sched.runner.thread.fixed.count=4
--sanity-checks off
--D jack.reporter.level.file=error=--,warning=-
\ No newline at end of file
+-D jack.reporter.level.file=error=--,warning=-
+--verbose error
+-D jack.jayce.cache=false
+-D jack.lambda.grouping-scope=package
+-D jack.lambda.simplify-stateless=true
diff --git a/core/java.mk b/core/java.mk
index 2602daf..4cb8114 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -109,20 +109,16 @@
LOCAL_PROGUARD_ENABLED :=
endif
-ifdef LOCAL_PROGUARD_ENABLED
-proguard_jar_leaf := proguard.classes.jar
-else
-proguard_jar_leaf := noproguard.classes.jar
-endif
-
full_classes_compiled_jar := $(intermediates.COMMON)/$(full_classes_compiled_jar_leaf)
+full_classes_processed_jar := $(intermediates.COMMON)/classes-processed.jar
+full_classes_desugar_jar := $(intermediates.COMMON)/classes-desugar.jar
jarjar_leaf := classes-jarjar.jar
full_classes_jarjar_jar := $(intermediates.COMMON)/$(jarjar_leaf)
emma_intermediates_dir := $(intermediates.COMMON)/emma_out
# emma is hardcoded to use the leaf name of its input for the output file --
# only the output directory can be changed
full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(jarjar_leaf)
-full_classes_proguard_jar := $(intermediates.COMMON)/$(proguard_jar_leaf)
+full_classes_proguard_jar := $(intermediates.COMMON)/classes-proguard.jar
built_dex_intermediate := $(intermediates.COMMON)/$(built_dex_intermediate_leaf)/classes.dex
full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
@@ -142,6 +138,7 @@
LOCAL_INTERMEDIATE_TARGETS += \
$(full_classes_compiled_jar) \
+ $(full_classes_desugar_jar) \
$(full_classes_jarjar_jar) \
$(full_classes_emma_jar) \
$(full_classes_jar) \
@@ -169,7 +166,7 @@
ifneq ($(renderscript_sources),)
renderscript_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(renderscript_sources))
RenderScript_file_stamp := $(LOCAL_INTERMEDIATE_SOURCE_DIR)/RenderScript.stamp
-renderscript_intermediate.COMMON := $(LOCAL_INTERMEDIATE_SOURCE_DIR)/renderscript
+renderscript_intermediate.COMMON := $(intermediates.COMMON)/renderscript
# Defaulting to an empty string uses the latest available platform SDK.
renderscript_target_api :=
@@ -213,7 +210,7 @@
else
LOCAL_RENDERSCRIPT_INCLUDES := \
$(TOPDIR)external/clang/lib/Headers \
- $(TOPDIR)frameworks/rs/scriptc \
+ $(TOPDIR)frameworks/rs/script_api/include \
$(LOCAL_RENDERSCRIPT_INCLUDES)
endif
@@ -306,10 +303,9 @@
## AIDL: Compile .aidl files to .java
###########################################################
aidl_sources := $(filter %.aidl,$(LOCAL_SRC_FILES))
+aidl_java_sources :=
ifneq ($(strip $(aidl_sources)),)
-aidl_java_sources := $(patsubst %.aidl,%.java,$(addprefix $(intermediates.COMMON)/src/, $(aidl_sources)))
-aidl_sources := $(addprefix $(LOCAL_PATH)/, $(aidl_sources))
aidl_preprocess_import :=
ifdef LOCAL_SDK_VERSION
@@ -323,20 +319,17 @@
# build against the platform.
LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
endif # LOCAL_SDK_VERSION
-$(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b $(addprefix -p,$(aidl_preprocess_import)) -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES))
-$(aidl_java_sources): $(intermediates.COMMON)/src/%.java: \
- $(LOCAL_PATH)/%.aidl \
- $(LOCAL_MODULE_MAKEFILE_DEP) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES) \
- $(AIDL) \
- $(aidl_preprocess_import)
- $(transform-aidl-to-java)
+$(foreach s,$(aidl_sources),\
+ $(eval $(call define-aidl-java-rule,$(s),$(intermediates.COMMON),aidl_java_sources)))
$(foreach java,$(aidl_java_sources), \
$(call include-depfile,$(java:%.java=%.P),$(java)))
-else
-aidl_java_sources :=
+$(aidl_java_sources) : $(LOCAL_ADDITIONAL_DEPENDENCIES) $(aidl_preprocess_import)
+
+$(aidl_java_sources): PRIVATE_AIDL_FLAGS := -b $(addprefix -p,$(aidl_preprocess_import)) -I$(LOCAL_PATH) -I$(LOCAL_PATH)/src $(addprefix -I,$(LOCAL_AIDL_INCLUDES))
+$(aidl_java_sources): PRIVATE_MODULE := $(LOCAL_MODULE)
+
endif
##########################################
@@ -348,7 +341,11 @@
ifndef LOCAL_CHECKED_MODULE
ifdef full_classes_jar
ifdef LOCAL_JACK_ENABLED
+ifeq ($(LOCAL_JACK_ENABLED),javac_frontend)
+LOCAL_CHECKED_MODULE := $(full_classes_compiled_jar)
+else
LOCAL_CHECKED_MODULE := $(jack_check_timestamp)
+endif
else
LOCAL_CHECKED_MODULE := $(full_classes_compiled_jar)
endif
@@ -367,7 +364,8 @@
logtags_java_sources := $(patsubst %.logtags,%.java,$(addprefix $(intermediates.COMMON)/src/, $(logtags_sources)))
logtags_sources := $(addprefix $(LOCAL_PATH)/, $(logtags_sources))
-$(logtags_java_sources): $(intermediates.COMMON)/src/%.java: $(LOCAL_PATH)/%.logtags $(TARGET_OUT_COMMON_INTERMEDIATES)/all-event-log-tags.txt
+$(logtags_java_sources): PRIVATE_MERGED_TAG := $(TARGET_OUT_COMMON_INTERMEDIATES)/all-event-log-tags.txt
+$(logtags_java_sources): $(intermediates.COMMON)/src/%.java: $(LOCAL_PATH)/%.logtags $(TARGET_OUT_COMMON_INTERMEDIATES)/all-event-log-tags.txt $(JAVATAGS) build/tools/event_log_tags.py
$(transform-logtags-to-java)
else
@@ -381,6 +379,9 @@
include $(BUILD_SYSTEM)/java_common.mk
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HAS_RS_SOURCES := $(if $(renderscript_sources),true)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RS_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/renderscript
+
#######################################
# defines built_odex along with rule to install odex
include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
@@ -405,15 +406,7 @@
# Droiddoc isn't currently able to generate stubs for modules, so we're just
# allowing it to use the classes.jar as the "stubs" that would be use to link
# against, for the cases where someone needs the jar to link against.
-# - Use the classes.jar instead of the handful of other intermediates that
-# we have, because it's the most processed, but still hasn't had dex run on
-# it, so it's closest to what's on the device.
-# - This extra copy, with the dependency on LOCAL_BUILT_MODULE allows the
-# PRIVATE_ vars to be preserved.
-$(full_classes_stubs_jar): PRIVATE_SOURCE_FILE := $(full_classes_jar)
-$(full_classes_stubs_jar) : $(full_classes_jar) | $(ACP)
- @echo Copying $(PRIVATE_SOURCE_FILE)
- $(hide) $(ACP) -fp $(PRIVATE_SOURCE_FILE) $@
+$(eval $(call copy-one-file,$(full_classes_jar),$(full_classes_stubs_jar)))
ALL_MODULES.$(LOCAL_MODULE).STUBS := $(full_classes_stubs_jar)
# The layers file allows you to enforce a layering between java packages.
@@ -422,15 +415,17 @@
$(full_classes_compiled_jar): PRIVATE_JAVA_LAYERS_FILE := $(layers_file)
$(full_classes_compiled_jar): PRIVATE_WARNINGS_ENABLE := $(LOCAL_WARNINGS_ENABLE)
-ifdef LOCAL_RMTYPEDEFS
-$(full_classes_compiled_jar): | $(RMTYPEDEFS)
-endif
-
# Compile the java files to a .jar file.
# This intentionally depends on java_sources, not all_java_sources.
# Deps for generated source files must be handled separately,
# via deps on the target that generates the sources.
-$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JAVACFLAGS)
+
+# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
+ifeq ($(RUN_ERROR_PRONE),true)
+LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
+endif
+
+$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES := $(LOCAL_JAR_EXCLUDE_FILES)
$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES := $(LOCAL_JAR_PACKAGES)
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_PACKAGES := $(LOCAL_JAR_EXCLUDE_PACKAGES)
@@ -443,24 +438,62 @@
$(layers_file) \
$(RenderScript_file_stamp) \
$(proto_java_sources_file_stamp) \
- $(LOCAL_MODULE_MAKEFILE_DEP) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(annotation_processor_deps) \
+ $(NORMALIZE_PATH) \
+ $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+ | $(SOONG_JAVAC_WRAPPER)
$(transform-java-to-classes.jar)
-# Run jarjar if necessary, otherwise just copy the file.
+javac-check : $(full_classes_compiled_jar)
+javac-check-$(LOCAL_MODULE) : $(full_classes_compiled_jar)
+
+ifdef LOCAL_JAR_PROCESSOR
+# LOCAL_JAR_PROCESSOR_ARGS must be evaluated here to set up the rule-local
+# PRIVATE_JAR_PROCESSOR_ARGS variable, but $< and $@ are not available yet.
+# Set ${in} and ${out} so they can be referenced by LOCAL_JAR_PROCESSOR_ARGS
+# using deferred evaluation (LOCAL_JAR_PROCESSOR_ARGS = instead of :=).
+in := $(full_classes_compiled_jar)
+out := $(full_classes_processed_jar).tmp
+$(full_classes_processed_jar): PRIVATE_JAR_PROCESSOR_ARGS := $(LOCAL_JAR_PROCESSOR_ARGS)
+$(full_classes_processed_jar): PRIVATE_JAR_PROCESSOR := $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_JAR_PROCESSOR).jar
+$(full_classes_processed_jar): PRIVATE_TMP_OUT := $(out)
+in :=
+out :=
+
+$(full_classes_processed_jar): $(full_classes_compiled_jar) $(LOCAL_JAR_PROCESSOR)
+ @echo Processing $@ with $(PRIVATE_JAR_PROCESSOR)
+ $(hide) rm -f $@ $(PRIVATE_TMP_OUT)
+ $(hide) java -jar $(PRIVATE_JAR_PROCESSOR) $(PRIVATE_JAR_PROCESSOR_ARGS)
+ $(hide) mv $(PRIVATE_TMP_OUT) $@
+
+else
+full_classes_processed_jar := $(full_classes_compiled_jar)
+endif
+
+my_desugaring :=
+ifndef LOCAL_JACK_ENABLED
+ifndef LOCAL_IS_STATIC_JAVA_LIBRARY
+my_desugaring := true
+$(full_classes_desugar_jar): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
+$(full_classes_desugar_jar): $(full_classes_processed_jar) $(DESUGAR)
+ $(desugar-classes-jar)
+endif
+endif
+
+ifndef my_desugaring
+full_classes_desugar_jar := $(full_classes_processed_jar)
+endif
+
+# Run jarjar if necessary
ifneq ($(strip $(LOCAL_JARJAR_RULES)),)
$(full_classes_jarjar_jar): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
-$(full_classes_jarjar_jar): $(full_classes_compiled_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
+$(full_classes_jarjar_jar): $(full_classes_desugar_jar) $(LOCAL_JARJAR_RULES) | $(JARJAR)
@echo JarJar: $@
$(hide) java -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
else
-$(full_classes_jarjar_jar): $(full_classes_compiled_jar) | $(ACP)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
+full_classes_jarjar_jar := $(full_classes_desugar_jar)
endif
-full_classes_jar_source := $(full_classes_jarjar_jar)
-ifndef LOCAL_JACK_ENABLED
ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
$(full_classes_emma_jar): PRIVATE_EMMA_COVERAGE_FILE := $(intermediates.COMMON)/coverage.emma.ignore
$(full_classes_emma_jar): PRIVATE_EMMA_INTERMEDIATES_DIR := $(emma_intermediates_dir)
@@ -477,18 +510,18 @@
# $(full_classes_emma_jar)
$(full_classes_emma_jar): $(full_classes_jarjar_jar) | $(EMMA_JAR)
$(transform-classes.jar-to-emma)
-full_classes_jar_source := $(full_classes_emma_jar)
+
+else
+full_classes_emma_jar := $(full_classes_jarjar_jar)
endif
-endif
+
+# TODO: this should depend on full_classes_emma_jar once coverage works again
+full_classes_pre_proguard_jar := $(full_classes_jarjar_jar)
# Keep a copy of the jar just before proguard processing.
-$(full_classes_jar): $(full_classes_jar_source) | $(ACP)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
+$(eval $(call copy-one-file,$(full_classes_pre_proguard_jar),$(intermediates.COMMON)/classes-pre-proguard.jar))
-$(call define-jar-to-toc-rule, $(full_classes_jar))
-
-# Run proguard if necessary, otherwise just copy the file.
+# Run proguard if necessary
ifdef LOCAL_PROGUARD_ENABLED
ifneq ($(filter-out full custom nosystem obfuscation optimization shrinktests,$(LOCAL_PROGUARD_ENABLED)),)
$(warning while processing: $(LOCAL_MODULE))
@@ -518,29 +551,37 @@
endif
# jack already has the libraries in its classpath and doesn't support jars
-legacy_proguard_flags := $(addprefix -libraryjars ,$(my_support_library_sdk_raise) $(full_shared_java_libs))
+legacy_proguard_flags := $(addprefix -libraryjars ,$(my_support_library_sdk_raise) \
+ $(filter-out $(my_support_library_sdk_raise),$(full_shared_java_libs)))
legacy_proguard_flags += -printmapping $(proguard_dictionary)
jack_proguard_flags := -printmapping $(jack_dictionary)
common_proguard_flags := -forceprocessing
+common_proguard_flag_files :=
ifeq ($(filter nosystem,$(LOCAL_PROGUARD_ENABLED)),)
-common_proguard_flags += -include $(BUILD_SYSTEM)/proguard.flags
+common_proguard_flag_files += $(BUILD_SYSTEM)/proguard.flags
ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
ifdef LOCAL_JACK_ENABLED
-common_proguard_flags += -include $(BUILD_SYSTEM)/proguard.jacoco.flags
+common_proguard_flag_files += $(BUILD_SYSTEM)/proguard.jacoco.flags
else
common_proguard_flags += -include $(BUILD_SYSTEM)/proguard.emma.flags
endif # LOCAL_JACK_ENABLED
endif
# If this is a test package, add proguard keep flags for tests.
ifneq ($(LOCAL_INSTRUMENTATION_FOR)$(filter tests,$(LOCAL_MODULE_TAGS)),)
-common_proguard_flags += -include $(BUILD_SYSTEM)/proguard_tests.flags
+common_proguard_flag_files += $(BUILD_SYSTEM)/proguard_tests.flags
ifeq ($(filter shrinktests,$(LOCAL_PROGUARD_ENABLED)),)
common_proguard_flags += -dontshrink # don't shrink tests by default
endif # shrinktests
endif # test package
+ifneq ($(common_proguard_flag_files),)
+common_proguard_flags += $(addprefix -include , $(common_proguard_flag_files))
+# This is included from $(BUILD_SYSTEM)/proguard.flags
+common_proguard_flag_files += $(BUILD_SYSTEM)/proguard_basic_keeps.flags
+endif
+
ifeq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)
# By default no obfuscation
common_proguard_flags += -dontobfuscate
@@ -590,22 +631,38 @@
else
extra_input_jar :=
endif
+
+# If not using jack and building against the current SDK version then filter
+# out the junit, android.test and c.a.i.u.Predicate classes that are to be
+# removed from the Android API as part of b/30188076 but which are still
+# present in the Android API. This is to allow changes to be made to the
+# build to statically include those classes into the application without
+# simultaneously removing those classes from the API.
+proguard_injar_filters :=
+ifndef LOCAL_JACK_ENABLED
+ifdef LOCAL_SDK_VERSION
+ifeq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+proguard_injar_filters := (!junit/framework/**,!junit/runner/**,!android/test/**,!com/android/internal/util/*)
+endif
+endif
+endif
+
+$(full_classes_proguard_jar): PRIVATE_PROGUARD_INJAR_FILTERS := $(proguard_injar_filters)
$(full_classes_proguard_jar): PRIVATE_EXTRA_INPUT_JAR := $(extra_input_jar)
$(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(legacy_proguard_flags) $(common_proguard_flags) $(LOCAL_PROGUARD_FLAGS)
-$(full_classes_proguard_jar) : $(full_classes_jar) $(extra_input_jar) $(my_support_library_sdk_raise) $(proguard_flag_files) | $(ACP) $(PROGUARD)
+$(full_classes_proguard_jar) : $(full_classes_pre_proguard_jar) $(extra_input_jar) $(my_support_library_sdk_raise) $(common_proguard_flag_files) $(proguard_flag_files) | $(PROGUARD)
$(call transform-jar-to-proguard)
else # LOCAL_PROGUARD_ENABLED not defined
-$(full_classes_proguard_jar) : $(full_classes_jar)
- @echo Copying: $@
- $(hide) $(ACP) -fp $< $@
-
+full_classes_proguard_jar := $(full_classes_pre_proguard_jar)
endif # LOCAL_PROGUARD_ENABLED defined
+$(eval $(call copy-one-file,$(full_classes_proguard_jar),$(full_classes_jar)))
+
+$(call define-jar-to-toc-rule, $(full_classes_jar))
+
+ifneq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
ifndef LOCAL_JACK_ENABLED
-# Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug
-# will work even when intermediates != intermediates.COMMON.
-$(built_dex_intermediate): PRIVATE_INTERMEDIATES_DIR := $(intermediates.COMMON)
$(built_dex_intermediate): PRIVATE_DX_FLAGS := $(LOCAL_DX_FLAGS)
# If you instrument class files that have local variable debug information in
# them emma does not correctly maintain the local variable table.
@@ -616,22 +673,25 @@
ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
$(built_dex_intermediate): PRIVATE_DX_FLAGS += --no-locals
endif
+$(built_dex_intermediate): $(full_classes_jar) $(DX)
+ $(transform-classes.jar-to-dex)
endif # LOCAL_JACK_ENABLED is disabled
-$(built_dex): $(built_dex_intermediate) | $(ACP)
+$(built_dex): $(built_dex_intermediate)
@echo Copying: $@
$(hide) mkdir -p $(dir $@)
$(hide) rm -f $(dir $@)/classes*.dex
- $(hide) $(ACP) -fp $(dir $<)/classes*.dex $(dir $@)
-ifneq ($(GENERATE_DEX_DEBUG),)
- $(install-dex-debug)
-endif
+ $(hide) cp -fp $(dir $<)/classes*.dex $(dir $@)
+
+java-dex: $(built_dex)
+
+endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
findbugs_xml := $(intermediates.COMMON)/findbugs.xml
$(findbugs_xml): PRIVATE_AUXCLASSPATH := $(addprefix -auxclasspath ,$(strip \
$(call normalize-path-list,$(filter %.jar,$(full_java_libs)))))
$(findbugs_xml): PRIVATE_FINDBUGS_FLAGS := $(LOCAL_FINDBUGS_FLAGS)
-$(findbugs_xml) : $(full_classes_jar) $(filter %.xml, $(LOCAL_FINDBUGS_FLAGS))
+$(findbugs_xml) : $(full_classes_pre_proguard_jar) $(filter %.xml, $(LOCAL_FINDBUGS_FLAGS))
@echo Findbugs: $@
$(hide) $(FINDBUGS) -textui -effort:min -xml:withMessages \
$(PRIVATE_AUXCLASSPATH) $(PRIVATE_FINDBUGS_FLAGS) \
@@ -653,6 +713,14 @@
endif # full_classes_jar is defined
+ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SDK_VERSION := $(LOCAL_SDK_VERSION)
+else
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SDK_VERSION := $(PLATFORM_SDK_VERSION)
+endif
+
ifdef LOCAL_JACK_ENABLED
$(LOCAL_INTERMEDIATE_TARGETS): \
PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-rsc
@@ -690,20 +758,24 @@
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_PROGUARD_FLAGS :=
endif # LOCAL_PROGUARD_ENABLED defined
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_FLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JACK_FLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_FLAGS := $(GLOBAL_JAVAC_DEBUG_FLAGS) $(LOCAL_JACK_FLAGS) $(annotation_processor_flags)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_VERSION := $(LOCAL_JACK_VERSION)
jack_all_deps := $(java_sources) $(java_resource_sources) $(full_jack_deps) \
- $(jar_manifest_file) $(layers_file) $(RenderScript_file_stamp) $(proguard_flag_files) \
- $(proto_java_sources_file_stamp) $(LOCAL_ADDITIONAL_DEPENDENCIES) $(LOCAL_JARJAR_RULES) \
- $(LOCAL_MODULE_MAKEFILE_DEP) $(JACK)
+ $(jar_manifest_file) $(layers_file) $(RenderScript_file_stamp) \
+ $(common_proguard_flag_files) $(proguard_flag_files) \
+ $(proto_java_sources_file_stamp) $(annotation_processor_deps) \
+ $(LOCAL_ADDITIONAL_DEPENDENCIES) $(LOCAL_JARJAR_RULES) \
+ $(NORMALIZE_PATH) $(JACK_DEFAULT_ARGS) $(JACK)
$(jack_check_timestamp): $(jack_all_deps) | setup-jack-server
@echo Checking build with Jack: $@
$(jack-check-java)
ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
-$(full_classes_jack): $(jack_all_deps) | setup-jack-server
+$(full_classes_jack): PRIVATE_JACK_PLUGIN_PATH := $(LOCAL_JACK_PLUGIN_PATH)
+$(full_classes_jack): PRIVATE_JACK_PLUGIN := $(LOCAL_JACK_PLUGIN)
+$(full_classes_jack): $(jack_all_deps) $(LOCAL_JACK_PLUGIN_PATH) | setup-jack-server
@echo Building with Jack: $@
$(java-to-jack)
@@ -716,6 +788,8 @@
$(built_dex_intermediate): PRIVATE_CLASSES_JACK := $(full_classes_jack)
ifeq ($(LOCAL_EMMA_INSTRUMENT),true)
+LOCAL_JACK_PLUGIN_PATH += $(HOST_OUT_JAVA_LIBRARIES)/jack-coverage-plugin.jar
+LOCAL_JACK_PLUGIN += com.android.jack.coverage.CodeCoverage
$(built_dex_intermediate): PRIVATE_JACK_COVERAGE_OPTIONS := \
-D jack.coverage=true \
-D jack.coverage.metadata.file=$(intermediates.COMMON)/coverage.em \
@@ -726,7 +800,29 @@
$(built_dex_intermediate): PRIVATE_JACK_COVERAGE_OPTIONS :=
endif
-$(built_dex_intermediate): $(jack_all_deps) | setup-jack-server
+# Compiling with javac to jar, then converting jar to dex with jack
+ifeq ($(LOCAL_JACK_ENABLED),javac_frontend)
+
+# PRIVATE_EXTRA_JAR_ARGS and source files were already handled during javac
+$(built_dex_intermediate): PRIVATE_EXTRA_JAR_ARGS :=
+$(built_dex_intermediate): PRIVATE_JAVA_SOURCES :=
+$(built_dex_intermediate): PRIVATE_SOURCE_INTERMEDIATES_DIR :=
+$(built_dex_intermediate): PRIVATE_HAS_PROTO_SOURCES :=
+$(built_dex_intermediate): PRIVATE_HAS_RS_SOURCES :=
+
+# Incremental compilation is not supported when mixing javac and jack
+$(built_dex_intermediate): PRIVATE_JACK_INCREMENTAL_DIR :=
+
+# Pass output of javac to jack
+$(built_dex_intermediate): PRIVATE_JACK_IMPORT_JAR := $(full_classes_compiled_jar)
+$(built_dex_intermediate): $(full_classes_compiled_jar)
+else # LOCAL_JACK_ENABLED != javac_frontend
+$(built_dex_intermediate): PRIVATE_JACK_IMPORT_JAR :=
+endif # LOCAL_JACK_ENABLED != javac_frontend
+
+$(built_dex_intermediate): PRIVATE_JACK_PLUGIN_PATH := $(LOCAL_JACK_PLUGIN_PATH)
+$(built_dex_intermediate): PRIVATE_JACK_PLUGIN := $(LOCAL_JACK_PLUGIN)
+$(built_dex_intermediate): $(jack_all_deps) $(LOCAL_JACK_PLUGIN_PATH) | setup-jack-server
@echo Building with Jack: $@
$(jack-java-to-dex)
@@ -740,9 +836,11 @@
endif #LOCAL_IS_STATIC_JAVA_LIBRARY
+$(noshrob_classes_jack): PRIVATE_JACK_PLUGIN_PATH := $(LOCAL_JACK_PLUGIN_PATH)
+$(noshrob_classes_jack): PRIVATE_JACK_PLUGIN := $(LOCAL_JACK_PLUGIN)
$(noshrob_classes_jack): PRIVATE_JACK_INTERMEDIATES_DIR := $(intermediates.COMMON)/jack-noshrob-rsc
$(noshrob_classes_jack): PRIVATE_JACK_PROGUARD_FLAGS :=
-$(noshrob_classes_jack): $(jack_all_deps) | setup-jack-server
+$(noshrob_classes_jack): $(jack_all_deps) $(LOCAL_JACK_PLUGIN_PATH) | setup-jack-server
@echo Building with Jack: $@
$(java-to-jack)
endif # full_classes_jar is defined
diff --git a/core/java_common.mk b/core/java_common.mk
index 9b7d10f..3c9b18f 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -34,9 +34,7 @@
ifneq ($(proto_sources),)
proto_sources_fullpath := $(addprefix $(LOCAL_PATH)/, $(proto_sources))
-# By putting the generated java files into $(LOCAL_INTERMEDIATE_SOURCE_DIR), they will be
-# automatically found by the java compiling function transform-java-to-classes.jar.
-proto_java_intemediate_dir := $(LOCAL_INTERMEDIATE_SOURCE_DIR)/proto
+proto_java_intemediate_dir := $(intermediates.COMMON)/proto
proto_java_sources_file_stamp := $(proto_java_intemediate_dir)/Proto.stamp
proto_java_sources_dir := $(proto_java_intemediate_dir)/src
@@ -128,6 +126,15 @@
extra_jar_args :=
endif # java_resource_file_groups
+#####################################
+## Warn if there is unrecognized file in LOCAL_SRC_FILES.
+my_unknown_src_files := $(filter-out \
+ %.java %.aidl %.proto %.logtags %.fs %.rs, \
+ $(LOCAL_SRC_FILES) $(LOCAL_INTERMEDIATE_SOURCES) $(LOCAL_GENERATED_SOURCES))
+ifneq ($(my_unknown_src_files),)
+$(warning $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Unused source files: $(my_unknown_src_files))
+endif
+
######################################
## PRIVATE java vars
# LOCAL_SOURCE_FILES_ALL_GENERATED is set only if the module does not have static source files,
@@ -136,10 +143,24 @@
need_compile_java := $(strip $(all_java_sources)$(all_res_assets)$(java_resource_sources))$(LOCAL_STATIC_JAVA_LIBRARIES)$(filter true,$(LOCAL_SOURCE_FILES_ALL_GENERATED))
ifdef need_compile_java
+annotation_processor_flags :=
+annotation_processor_deps :=
+
+ifdef LOCAL_ANNOTATION_PROCESSORS
+ annotation_processor_jars := $(call java-lib-deps,$(LOCAL_ANNOTATION_PROCESSORS),true)
+ annotation_processor_flags += -processorpath $(call normalize-path-list,$(annotation_processor_jars))
+ annotation_processor_deps += $(annotation_processor_jars)
+
+ # b/25860419: annotation processors must be explicitly specified for grok
+ annotation_processor_flags += $(foreach class,$(LOCAL_ANNOTATION_PROCESSOR_CLASSES),-processor $(class))
+
+ annotation_processor_jars :=
+endif
+
full_static_java_libs := \
$(foreach lib,$(LOCAL_STATIC_JAVA_LIBRARIES), \
$(call intermediates-dir-for, \
- JAVA_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE),COMMON)/javalib.jar)
+ JAVA_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE),COMMON)/classes.jar)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_STATIC_JAVA_LIBRARIES := $(full_static_java_libs)
@@ -147,7 +168,11 @@
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates.COMMON)/classes
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ANNO_INTERMEDIATES_DIR := $(intermediates.COMMON)/anno
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/src
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HAS_PROTO_SOURCES := $(if $(proto_sources),true)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_PROTO_SOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/proto
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_HAS_RS_SOURCES :=
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JAVA_SOURCES := $(all_java_sources)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RMTYPEDEFS := $(LOCAL_RMTYPEDEFS)
@@ -201,11 +226,11 @@
ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
my_bootclasspath := ""
else
-my_bootclasspath := $(call normalize-path-list,$(call host-dex-java-lib-files,core-oj-hostdex core-libart-hostdex))
+my_bootclasspath := $(call normalize-path-list,$(call java-lib-files,core-oj-hostdex core-libart-hostdex,true))
endif
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH := -bootclasspath $(my_bootclasspath)
-full_shared_java_libs := $(call host-dex-java-lib-files,$(LOCAL_JAVA_LIBRARIES))
+full_shared_java_libs := $(call java-lib-files,$(LOCAL_JAVA_LIBRARIES),true)
full_java_lib_deps := $(full_shared_java_libs)
else # !USE_CORE_LIB_BOOTCLASSPATH
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH :=
@@ -227,7 +252,7 @@
link_apk_libraries := \
$(foreach lib,$(apk_libraries), \
$(call intermediates-dir-for, \
- APPS,$(lib),,COMMON)/classes.jar)
+ APPS,$(lib),,COMMON)/classes-pre-proguard.jar)
# link against the jar with full original names (before proguard processing).
full_shared_java_libs += $(link_apk_libraries)
@@ -248,7 +273,7 @@
link_instr_intermediates_dir.COMMON := $(call intermediates-dir-for, \
APPS,$(LOCAL_INSTRUMENTATION_FOR),,COMMON)
# link against the jar with full original names (before proguard processing).
- link_instr_classes_jar := $(link_instr_intermediates_dir.COMMON)/classes.jar
+ link_instr_classes_jar := $(link_instr_intermediates_dir.COMMON)/classes-pre-proguard.jar
full_java_libs += $(link_instr_classes_jar)
full_java_lib_deps += $(link_instr_classes_jar)
endif # LOCAL_INSTRUMENTATION_FOR
@@ -317,54 +342,16 @@
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_STATIC_JACK_LIBRARIES := $(full_static_jack_libs)
-ifndef LOCAL_IS_HOST_MODULE
-ifeq ($(LOCAL_SDK_VERSION),)
-ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
-my_bootclasspath :=
-else
-my_bootclasspath := $(call jack-lib-files,core-oj core-libart)
-endif
-else # LOCAL_SDK_VERSION
-ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),current)
-# LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS.
-my_bootclasspath := $(call jack-lib-files,android_stubs_current)
-else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),system_current)
-my_bootclasspath := $(call jack-lib-files,android_system_stubs_current)
-else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),test_current)
-my_bootclasspath := $(call jack-lib-files,android_test_stubs_current)
-else
-my_bootclasspath :=$(call jack-lib-files,sdk_v$(LOCAL_SDK_VERSION))
-endif # current, system_current, or test_current
-endif # LOCAL_SDK_VERSION
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES := $(my_bootclasspath)
-
full_shared_jack_libs := $(call jack-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-full_jack_deps := $(call jack-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
+full_jack_deps := $(full_shared_jack_libs)
+
+ifndef LOCAL_IS_HOST_MODULE
# Turn off .toc optimization for apps build as we cannot build dexdump.
ifeq (,$(TARGET_BUILD_APPS))
full_jack_deps := $(patsubst %.jack, %.dex.toc, $(full_jack_deps))
endif
-
-else # LOCAL_IS_HOST_MODULE
-
-ifeq ($(USE_CORE_LIB_BOOTCLASSPATH),true)
-ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
-my_bootclasspath :=
-else
-my_bootclasspath := $(call jack-lib-files,core-oj-hostdex core-libart-hostdex,$(LOCAL_IS_HOST_MODULE))
-endif
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES := $(my_bootclasspath)
-# Compiling against the final jack library. If we want to add support for obfuscated library
-# we'll need to change that to compile against the not obfuscated jack library.
-full_shared_jack_libs := $(call jack-lib-files,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-full_jack_deps := $(call jack-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-else
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_BOOTCLASSPATH_JAVA_LIBRARIES :=
-full_shared_jack_libs := $(call jack-lib-deps,$(LOCAL_JAVA_LIBRARIES),$(LOCAL_IS_HOST_MODULE))
-full_jack_deps := $(full_shared_jack_libs)
-endif # USE_CORE_LIB_BOOTCLASSPATH
endif # !LOCAL_IS_HOST_MODULE
-full_jack_libs := $(full_shared_jack_libs) $(full_static_jack_libs) $(LOCAL_JACK_CLASSPATH)
+full_shared_jack_libs += $(LOCAL_JACK_CLASSPATH)
full_jack_deps += $(full_static_jack_libs) $(LOCAL_JACK_CLASSPATH)
ifndef LOCAL_IS_HOST_MODULE
@@ -378,7 +365,6 @@
# link against the jar with full original names (before proguard processing).
full_shared_jack_libs += $(link_apk_jack_libraries)
- full_jack_libs += $(link_apk_jack_libraries)
full_jack_deps += $(link_apk_jack_libraries)
endif
@@ -388,14 +374,41 @@
ifdef LOCAL_INSTRUMENTATION_FOR
# link against the jar with full original names (before proguard processing).
link_instr_classes_jack := $(link_instr_intermediates_dir.COMMON)/classes.noshrob.jack
- full_jack_libs += $(link_instr_classes_jack)
+ full_shared_jack_libs += $(link_instr_classes_jack)
full_jack_deps += $(link_instr_classes_jack)
endif # LOCAL_INSTRUMENTATION_FOR
endif # !LOCAL_IS_HOST_MODULE
# Propagate local configuration options to this target.
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ALL_JACK_LIBRARIES:= $(full_jack_libs)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JACK_SHARED_LIBRARIES:= $(full_shared_jack_libs)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_JARJAR_RULES := $(LOCAL_JARJAR_RULES)
endif # need_compile_java
endif # LOCAL_JACK_ENABLED
+
+
+###########################################################
+# Verify that all libraries are safe to use
+###########################################################
+ifndef LOCAL_IS_HOST_MODULE
+ifeq ($(LOCAL_SDK_VERSION),system_current)
+my_link_type := java:system
+my_warn_types := java:platform
+my_allowed_types := java:sdk java:system
+else ifneq ($(LOCAL_SDK_VERSION),)
+my_link_type := java:sdk
+my_warn_types := java:system java:platform
+my_allowed_types := java:sdk
+else
+my_link_type := java:platform
+my_warn_types :=
+my_allowed_types := java:sdk java:system java:platform
+endif
+
+my_link_deps := $(addprefix JAVA_LIBRARIES:,$(LOCAL_STATIC_JAVA_LIBRARIES))
+my_link_deps += $(addprefix APPS:,$(apk_libraries))
+
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+my_common := COMMON
+include $(BUILD_SYSTEM)/link_type.mk
+endif # !LOCAL_IS_HOST_MODULE
diff --git a/core/java_library.mk b/core/java_library.mk
index 81a4a6a..9db587d 100644
--- a/core/java_library.mk
+++ b/core/java_library.mk
@@ -2,6 +2,7 @@
## Standard rules for building a java library.
##
###########################################################
+$(call record-module-type,JAVA_LIBRARY)
ifdef LOCAL_IS_HOST_MODULE
$(error $(LOCAL_PATH): Host java libraries must use BUILD_HOST_JAVA_LIBRARY)
@@ -34,9 +35,14 @@
endif
endif
+# For non-static java libraries, other modules should depend on
+# out/target/common/obj/JAVA_LIBRARIES/.../javalib.jar (for jack)
+# or out/target/common/obj/JAVA_LIBRARIES/.../classes.jar (for javac).
+# For static java libraries, other modules should depend on
+# out/target/common/obj/JAVA_LIBRARIES/.../classes.jar
+# There are some dependencies outside the build system that assume static
+# java libraries produce javalib.jar, so we will copy classes.jar there too.
intermediates.COMMON := $(call local-intermediates-dir,COMMON)
-
-# This file will be the one that other modules should depend on.
common_javalib.jar := $(intermediates.COMMON)/javalib.jar
LOCAL_INTERMEDIATE_TARGETS += $(common_javalib.jar)
@@ -64,27 +70,20 @@
#################################
ifeq ($(LOCAL_IS_STATIC_JAVA_LIBRARY),true)
-# No dex; all we want are the .class files with resources.
-$(common_javalib.jar) : $(java_resource_sources)
-ifdef LOCAL_PROGUARD_ENABLED
-$(common_javalib.jar) : $(full_classes_proguard_jar)
-else
-$(common_javalib.jar) : $(full_classes_jar)
-endif
- @echo "target Static Jar: $(PRIVATE_MODULE) ($@)"
- $(copy-file-to-target)
+# There are some dependencies outside the build system that assume classes.jar
+# is available as javalib.jar so copy it there too.
+$(eval $(call copy-one-file,$(full_classes_jar),$(common_javalib.jar)))
ifdef LOCAL_JACK_ENABLED
-$(LOCAL_BUILT_MODULE) : $(full_classes_jack)
+$(eval $(call copy-one-file,$(full_classes_jack),$(LOCAL_BUILT_MODULE)))
else
-$(LOCAL_BUILT_MODULE) : $(common_javalib.jar)
+$(eval $(call copy-one-file,$(full_classes_jar),$(LOCAL_BUILT_MODULE)))
endif
- $(copy-file-to-target)
else # !LOCAL_IS_STATIC_JAVA_LIBRARY
$(common_javalib.jar): PRIVATE_DEX_FILE := $(built_dex)
-$(common_javalib.jar): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
+$(common_javalib.jar): PRIVATE_SOURCE_ARCHIVE := $(full_classes_pre_proguard_jar)
$(common_javalib.jar): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
$(common_javalib.jar) : $(built_dex) $(java_resource_sources) | $(ZIPTIME)
@echo "target Jar: $(PRIVATE_MODULE) ($@)"
@@ -103,8 +102,7 @@
ifneq ($(dexpreopt_boot_jar_module),) # boot jar
# boot jar's rules are defined in dex_preopt.mk
dexpreopted_boot_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module)_nodex.jar
-$(LOCAL_BUILT_MODULE) : $(dexpreopted_boot_jar) | $(ACP)
- $(call copy-file-to-target)
+$(eval $(call copy-one-file,$(dexpreopted_boot_jar),$(LOCAL_BUILT_MODULE)))
# For libart boot jars, we don't have .odex files.
else # ! boot jar
@@ -114,8 +112,7 @@
@echo "Dexpreopt Jar: $(PRIVATE_MODULE) ($@)"
$(call dexpreopt-one-file,$<,$@)
-$(LOCAL_BUILT_MODULE) : $(common_javalib.jar) | $(ACP)
- $(call copy-file-to-target)
+$(eval $(call copy-one-file,$(common_javalib.jar),$(LOCAL_BUILT_MODULE)))
ifneq (nostripping,$(LOCAL_DEX_PREOPT))
$(call dexpreopt-remove-classes.dex,$@)
endif
@@ -123,8 +120,7 @@
endif # ! boot jar
else # LOCAL_DEX_PREOPT
-$(LOCAL_BUILT_MODULE) : $(common_javalib.jar) | $(ACP)
- $(call copy-file-to-target)
+$(eval $(call copy-one-file,$(common_javalib.jar),$(LOCAL_BUILT_MODULE)))
endif # LOCAL_DEX_PREOPT
endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
diff --git a/core/legacy_prebuilts.mk b/core/legacy_prebuilts.mk
deleted file mode 100644
index f4633d0..0000000
--- a/core/legacy_prebuilts.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright (C) 2010 The Android Open Source Project
-#
-# 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.
-#
-
-# This is the list of modules grandfathered to use ALL_PREBUILT
-
-# DO NOT ADD ANY NEW MODULE TO THIS FILE
-#
-# ALL_PREBUILT modules are hard to control and audit and we don't want
-# to add any new such module in the system
-
-GRANDFATHERED_ALL_PREBUILT := \
- bmgr \
- ime \
- input \
- monkey \
- pm \
- RFFspeed_501.bmd \
- RFFstd_501.bmd \
- svc
diff --git a/core/link_type.mk b/core/link_type.mk
new file mode 100644
index 0000000..ff525cb
--- /dev/null
+++ b/core/link_type.mk
@@ -0,0 +1,27 @@
+# Inputs:
+# LOCAL_MODULE_CLASS, LOCAL_MODULE, LOCAL_MODULE_MAKEFILE, LOCAL_BUILT_MODULE
+# from base_rules.mk: my_kind, my_host_cross
+# my_common: empty or COMMON, like the argument to intermediates-dir-for
+# my_2nd_arch_prefix: usually LOCAL_2ND_ARCH_VAR_PREFIX, separate for JNI installation
+#
+# my_link_type: the tags to apply to this module
+# my_warn_types: the tags to warn about in our dependencies
+# my_allowed_types: the tags to allow in our dependencies
+# my_link_deps: the dependencies, in the form of <MODULE_CLASS>:<name>
+#
+
+my_link_prefix := LINK_TYPE:$(call find-idf-prefix,$(my_kind),$(my_host_cross)):$(if $(my_common),$(my_common):_,_:$(if $(my_2nd_arch_prefix),$(my_2nd_arch_prefix),_))
+link_type := $(my_link_prefix):$(LOCAL_MODULE_CLASS):$(LOCAL_MODULE)
+ALL_LINK_TYPES := $(ALL_LINK_TYPES) $(link_type)
+$(link_type).TYPE := $(my_link_type)
+$(link_type).MAKEFILE := $(LOCAL_MODULE_MAKEFILE)
+$(link_type).WARN := $(my_warn_types)
+$(link_type).ALLOWED := $(my_allowed_types)
+$(link_type).DEPS := $(addprefix $(my_link_prefix):,$(my_link_deps))
+$(link_type).BUILT := $(LOCAL_BUILT_MODULE)
+
+link_type :=
+my_allowed_types :=
+my_link_prefix :=
+my_link_type :=
+my_warn_types :=
diff --git a/core/local_vndk.mk b/core/local_vndk.mk
new file mode 100644
index 0000000..5ac5f26
--- /dev/null
+++ b/core/local_vndk.mk
@@ -0,0 +1,40 @@
+
+#Set LOCAL_USE_VNDK for modules going into vendor partition, except for host modules
+#If LOCAL_SDK_VERSION is set, thats a more restrictive set, so they dont need LOCAL_USE_VNDK
+ifndef LOCAL_IS_HOST_MODULE
+ifndef LOCAL_SDK_VERSION
+ ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_OEM_MODULE)))
+ LOCAL_USE_VNDK:=true
+ else
+ ifneq (,$(filter $(TARGET_OUT_VENDOR)%,$(LOCAL_MODULE_PATH) $(LOCAL_MODULE_PATH_32) $(LOCAL_MODULE_PATH_64)))
+ LOCAL_USE_VNDK:=true
+ endif
+ endif
+endif
+endif
+
+# Verify LOCAL_USE_VNDK usage, and set LOCAL_SDK_VERSION if necessary
+
+ifdef LOCAL_IS_HOST_MODULE
+ ifdef LOCAL_USE_VNDK
+ $(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Do not use LOCAL_USE_VNDK with host modules >&2)
+ $(error done)
+ endif
+endif
+ifdef LOCAL_USE_VNDK
+ ifneq ($(LOCAL_USE_VNDK),true)
+ $(shell echo '$(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): LOCAL_USE_VNDK must be "true" or empty, not "$(LOCAL_USE_VNDK)"' >&2)
+ $(error done)
+ endif
+
+ ifdef LOCAL_SDK_VERSION
+ $(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): LOCAL_USE_VNDK must not be used with LOCAL_SDK_VERSION >&2)
+ $(error done)
+ endif
+
+ # If we're not using the VNDK, drop all restrictions
+ ifndef BOARD_VNDK_VERSION
+ LOCAL_USE_VNDK:=
+ endif
+endif
+
diff --git a/core/main.mk b/core/main.mk
index a612f83..bc4ed04 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -9,44 +9,23 @@
SHELL := /bin/bash
endif
-# this turns off the suffix rules built into make
-.SUFFIXES:
+ifndef KATI
-# this turns off the RCS / SCCS implicit rules of GNU Make
-% : RCS/%,v
-% : RCS/%
-% : %,v
-% : s.%
-% : SCCS/s.%
-
-# If a rule fails, delete $@.
-.DELETE_ON_ERROR:
-
-# Figure out where we are.
-#TOP := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
-#TOP := $(patsubst %/,%,$(TOP))
-
-# TOPDIR is the normal variable you should use, because
-# if we are executing relative to the current directory
-# it can be "", whereas TOP must be "." which causes
-# pattern matching problems when make strips off the
-# trailing "./" from paths in various places.
-#ifeq ($(TOP),.)
-#TOPDIR :=
-#else
-#TOPDIR := $(TOP)/
-#endif
-
-# Check for broken versions of make.
-ifneq (1,$(strip $(shell expr $(MAKE_VERSION) \>= 3.81)))
-$(warning ********************************************************************************)
-$(warning * You are using version $(MAKE_VERSION) of make.)
-$(warning * Android can only be built by versions 3.81 and higher.)
-$(warning * see https://source.android.com/source/download.html)
-$(warning ********************************************************************************)
-$(error stopping)
+host_prebuilts := linux-x86
+ifeq ($(shell uname),Darwin)
+host_prebuilts := darwin-x86
endif
+.PHONY: run_soong_ui
+run_soong_ui:
+ +@prebuilts/build-tools/$(host_prebuilts)/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode $(MAKECMDGOALS)
+
+.PHONY: $(MAKECMDGOALS)
+$(sort $(MAKECMDGOALS)) : run_soong_ui
+ @#empty
+
+else # KATI
+
# Absolute path of the present working direcotry.
# This overrides the shell variable $PWD, which does not necessarily points to
# the top of the source tree, for example when "make -C" is used in m/mm/mmm.
@@ -57,9 +36,6 @@
BUILD_SYSTEM := $(TOPDIR)build/core
-# Ensure JAVA_NOT_REQUIRED is not set externally.
-JAVA_NOT_REQUIRED := false
-
# This is the default target. It must be the first declared target.
.PHONY: droid
DEFAULT_GOAL := droid
@@ -68,54 +44,17 @@
.PHONY: droid_targets
droid_targets:
-# Used to force goals to build. Only use for conditionally defined goals.
-.PHONY: FORCE
-FORCE:
-
-# These goals don't need to collect and include Android.mks/CleanSpec.mks
-# in the source tree.
-dont_bother_goals := clean clobber dataclean installclean \
- help out \
- snod systemimage-nodeps \
- stnod systemtarball-nodeps \
- userdataimage-nodeps userdatatarball-nodeps \
- cacheimage-nodeps \
- vendorimage-nodeps \
- systemotherimage-nodeps \
- ramdisk-nodeps \
- bootimage-nodeps \
- recoveryimage-nodeps \
- product-graph dump-products
+# Set up various standard variables based on configuration
+# and host information.
+include $(BUILD_SYSTEM)/config.mk
ifneq ($(filter $(dont_bother_goals), $(MAKECMDGOALS)),)
dont_bother := true
endif
-ORIGINAL_MAKECMDGOALS := $(MAKECMDGOALS)
+include $(SOONG_MAKEVARS_MK)
-# Targets that provide quick help on the build system.
-include $(BUILD_SYSTEM)/help.mk
-
-# Set up various standard variables based on configuration
-# and host information.
-include $(BUILD_SYSTEM)/config.mk
-
-relaunch_with_ninja :=
-ifneq ($(USE_NINJA),false)
-ifndef BUILDING_WITH_NINJA
-relaunch_with_ninja := true
-endif
-endif
-
-ifeq ($(relaunch_with_ninja),true)
-# Mark this is a ninja build.
-$(shell mkdir -p $(OUT_DIR) && touch $(OUT_DIR)/ninja_build)
-include build/core/ninja.mk
-else # !relaunch_with_ninja
-ifndef BUILDING_WITH_NINJA
-# Remove ninja build mark if it exists.
-$(shell rm -f $(OUT_DIR)/ninja_build)
-endif
+include $(BUILD_SYSTEM)/clang/config.mk
# Write the build number to a file so it can be read back in
# without changing the command line every time. Avoids rebuilds
@@ -135,6 +74,10 @@
-include cts/build/config.mk
# VTS-specific config.
-include test/vts/tools/vts-tradefed/build/config.mk
+# device-tests-specific-config.
+-include tools/tradefederation/build/suites/device-tests/config.mk
+# general-tests-specific-config.
+-include tools/tradefederation/build/suites/general-tests/config.mk
# This allows us to force a clean build - included after the config.mk
# environment setup is done, but before we generate any dependencies. This
@@ -145,153 +88,41 @@
# Include the google-specific config
-include vendor/google/build/config.mk
-VERSION_CHECK_SEQUENCE_NUMBER := 6
--include $(OUT_DIR)/versions_checked.mk
-ifneq ($(VERSION_CHECK_SEQUENCE_NUMBER),$(VERSIONS_CHECKED))
-
-$(info Checking build tools versions...)
-
-# check for a case sensitive file system
-ifneq (a,$(shell mkdir -p $(OUT_DIR) ; \
- echo a > $(OUT_DIR)/casecheck.txt; \
- echo B > $(OUT_DIR)/CaseCheck.txt; \
- cat $(OUT_DIR)/casecheck.txt))
-$(warning ************************************************************)
-$(warning You are building on a case-insensitive filesystem.)
-$(warning Please move your source tree to a case-sensitive filesystem.)
-$(warning ************************************************************)
-$(error Case-insensitive filesystems not supported)
-endif
-
-# Make sure that there are no spaces in the absolute path; the
-# build system can't deal with them.
-ifneq ($(words $(shell pwd)),1)
-$(warning ************************************************************)
-$(warning You are building in a directory whose absolute path contains)
-$(warning a space character:)
-$(warning $(space))
-$(warning "$(shell pwd)")
-$(warning $(space))
-$(warning Please move your source tree to a path that does not contain)
-$(warning any spaces.)
-$(warning ************************************************************)
-$(error Directory names containing spaces not supported)
-endif
-
-ifeq ($(JAVA_NOT_REQUIRED), false)
-java_version_str := $(shell unset _JAVA_OPTIONS && java -version 2>&1)
-javac_version_str := $(shell unset _JAVA_OPTIONS && javac -version 2>&1)
-
-# Check for the correct version of java, should be 1.8 by
-# default and only 1.7 if LEGACY_USE_JAVA7 is set.
-ifeq ($(LEGACY_USE_JAVA7),) # if LEGACY_USE_JAVA7 == ''
-required_version := "1.8.x"
-required_javac_version := "1.8"
-java_version := $(shell echo '$(java_version_str)' | grep '[ "]1\.8[\. "$$]')
-javac_version := $(shell echo '$(javac_version_str)' | grep '[ "]1\.8[\. "$$]')
-else
-required_version := "1.7.x"
-required_javac_version := "1.7"
-java_version := $(shell echo '$(java_version_str)' | grep '^java .*[ "]1\.7[\. "$$]')
-javac_version := $(shell echo '$(javac_version_str)' | grep '[ "]1\.7[\. "$$]')
-endif # if LEGACY_USE_JAVA7 == ''
-
-ifeq ($(strip $(java_version)),)
-$(info ************************************************************)
-$(info You are attempting to build with the incorrect version)
-$(info of java.)
-$(info $(space))
-$(info Your version is: $(java_version_str).)
-$(info The required version is: $(required_version))
-$(info $(space))
-$(info Please follow the machine setup instructions at)
-$(info $(space)$(space)$(space)$(space)https://source.android.com/source/initializing.html)
-$(info ************************************************************)
-$(error stop)
-endif
-
-# Check for the current JDK.
-#
-# For Java 1.7/1.8, we require OpenJDK on linux and Oracle JDK on Mac OS.
-requires_openjdk := false
-ifeq ($(BUILD_OS),linux)
-requires_openjdk := true
-endif
-
-
-# Check for the current jdk
-ifeq ($(requires_openjdk), true)
-# The user asked for openjdk, so check that the host
-# java version is really openjdk and not some other JDK.
-ifeq ($(shell echo '$(java_version_str)' | grep -i openjdk),)
-$(info ************************************************************)
-$(info You asked for an OpenJDK based build but your version is)
-$(info $(java_version_str).)
-$(info ************************************************************)
-$(error stop)
-endif # java version is not OpenJdk
-else # if requires_openjdk
-ifneq ($(shell echo '$(java_version_str)' | grep -i openjdk),)
-$(info ************************************************************)
-$(info You are attempting to build with an unsupported JDK.)
-$(info $(space))
-$(info You use OpenJDK but only Sun/Oracle JDK is supported.)
-$(info Please follow the machine setup instructions at)
-$(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
-$(info ************************************************************)
-$(error stop)
-endif # java version is not Sun Oracle JDK
-endif # if requires_openjdk
-
-KNOWN_INCOMPATIBLE_JAVAC_VERSIONS := google
-incompat_javac := $(foreach v,$(KNOWN_INCOMPATIBLE_JAVAC_VERSIONS),$(findstring $(v),$(javac_version_str)))
-ifneq ($(incompat_javac),)
-javac_version :=
-endif
-
-# Check for the correct version of javac
-ifeq ($(strip $(javac_version)),)
-$(info ************************************************************)
-$(info You are attempting to build with the incorrect version)
-$(info of javac.)
-$(info $(space))
-$(info Your version is: $(javac_version_str).)
-ifneq ($(incompat_javac),)
-$(info This '$(incompat_javac)' version is not supported for Android platform builds.)
-$(info Use a publicly available JDK and make sure you have run envsetup.sh / lunch.)
-else
-$(info The required version is: $(required_javac_version))
-endif
-$(info $(space))
-$(info Please follow the machine setup instructions at)
-$(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html)
-$(info ************************************************************)
-$(error stop)
-endif
-
-endif # if JAVA_NOT_REQUIRED
-
-ifndef BUILD_EMULATOR
- # Emulator binaries are now provided under prebuilts/android-emulator/
- BUILD_EMULATOR := false
-endif
-
-$(shell echo 'VERSIONS_CHECKED := $(VERSION_CHECK_SEQUENCE_NUMBER)' \
- > $(OUT_DIR)/versions_checked.mk)
-$(shell echo 'BUILD_EMULATOR ?= $(BUILD_EMULATOR)' \
- >> $(OUT_DIR)/versions_checked.mk)
-endif
-
# These are the modifier targets that don't do anything themselves, but
# change the behavior of the build.
# (must be defined before including definitions.make)
-INTERNAL_MODIFIER_TARGETS := showcommands all
+INTERNAL_MODIFIER_TARGETS := all
# EMMA_INSTRUMENT_STATIC merges the static emma library to each emma-enabled module.
ifeq (true,$(EMMA_INSTRUMENT_STATIC))
EMMA_INSTRUMENT := true
endif
+#
+# -----------------------------------------------------------------
+# Validate ADDITIONAL_DEFAULT_PROPERTIES.
+ifneq ($(ADDITIONAL_DEFAULT_PROPERTIES),)
+$(error ADDITIONAL_DEFAULT_PROPERTIES must not be set before here: $(ADDITIONAL_DEFAULT_PROPERTIES))
+endif
+
+#
+# -----------------------------------------------------------------
+# Validate ADDITIONAL_BUILD_PROPERTIES.
+ifneq ($(ADDITIONAL_BUILD_PROPERTIES),)
+$(error ADDITIONAL_BUILD_PROPERTIES must not be set before here: $(ADDITIONAL_BUILD_PROPERTIES))
+endif
+
+#
+# -----------------------------------------------------------------
+# Add the product-defined properties to the build properties.
+ifdef PRODUCT_SHIPPING_API_LEVEL
+ADDITIONAL_BUILD_PROPERTIES += \
+ ro.product.first_api_level=$(PRODUCT_SHIPPING_API_LEVEL)
+endif
+ADDITIONAL_BUILD_PROPERTIES := \
+ $(ADDITIONAL_BUILD_PROPERTIES) \
+ $(PRODUCT_PROPERTY_OVERRIDES)
+
# Bring in standard build system definitions.
include $(BUILD_SYSTEM)/definitions.mk
@@ -457,6 +288,9 @@
$(error The 'sdk' target may not be specified with any other targets)
endif
+# AUX dependencies are already added by now; remove triggers from the MAKECMDGOALS
+MAKECMDGOALS := $(strip $(filter-out AUX-%,$(MAKECMDGOALS)))
+
# TODO: this should be eng I think. Since the sdk is built from the eng
# variant.
tags_to_install := debug eng
@@ -469,8 +303,8 @@
ADDITIONAL_BUILD_PROPERTIES += net.bt.name=Android
-# enable vm tracing in files for now to help track
-# the cause of ANRs in the content process
+# Sets the location that the runtime dumps stack traces to when signalled
+# with SIGQUIT. Stack trace dumping is turned on for all android builds.
ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.stack-trace-file=/data/anr/traces.txt
# ------------------------------------------------------------
@@ -492,7 +326,7 @@
endif
-# If they only used the modifier goals (showcommands, etc), we'll actually
+# If they only used the modifier goals (all, etc), we'll actually
# build the default target.
ifeq ($(filter-out $(INTERNAL_MODIFIER_TARGETS),$(MAKECMDGOALS)),)
.PHONY: $(INTERNAL_MODIFIER_TARGETS)
@@ -502,21 +336,25 @@
#
# Typical build; include any Android.mk files we can find.
#
-subdirs := $(TOP)
FULL_BUILD := true
-# Before we go and include all of the module makefiles, stash away
-# the PRODUCT_* values so that later we can verify they are not modified.
-stash_product_vars:=true
-ifeq ($(stash_product_vars),true)
- $(call stash-product-vars, __STASHED)
+# Before we go and include all of the module makefiles, mark the PRODUCT_*
+# and ADDITIONAL*PROPERTIES values readonly so that they won't be modified.
+$(call readonly-product-vars)
+ADDITIONAL_DEFAULT_PROPERTIES := $(strip $(ADDITIONAL_DEFAULT_PROPERTIES))
+.KATI_READONLY := ADDITIONAL_DEFAULT_PROPERTIES
+ADDITIONAL_BUILD_PROPERTIES := $(strip $(ADDITIONAL_BUILD_PROPERTIES))
+.KATI_READONLY := ADDITIONAL_BUILD_PROPERTIES
+
+ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),)
+ENFORCE_RRO_SOURCES :=
endif
ifneq ($(ONE_SHOT_MAKEFILE),)
# We've probably been invoked by the "mm" shell function
# with a subdirectory's makefile.
-include $(ONE_SHOT_MAKEFILE)
+include $(SOONG_ANDROID_MK) $(wildcard $(ONE_SHOT_MAKEFILE))
# Change CUSTOM_MODULES to include only modules that were
# defined by this makefile; this will install all of those
# modules as a side-effect. Do this after including ONE_SHOT_MAKEFILE
@@ -530,11 +368,28 @@
NOTICE-TARGET-%: ;
# A helper goal printing out install paths
-.PHONY: GET-INSTALL-PATH
-GET-INSTALL-PATH:
- @echo "Install paths for modules in $(ONE_SHOT_MAKEFILE):"
- @$(foreach m, $(ALL_MODULES), $(if $(ALL_MODULES.$(m).INSTALLED), \
- echo 'INSTALL-PATH: $(m) $(ALL_MODULES.$(m).INSTALLED)';))
+define register_module_install_path
+.PHONY: GET-MODULE-INSTALL-PATH-$(1)
+GET-MODULE-INSTALL-PATH-$(1):
+ echo 'INSTALL-PATH: $(1) $(ALL_MODULES.$(1).INSTALLED)'
+endef
+
+SORTED_ALL_MODULES := $(sort $(ALL_MODULES))
+UNIQUE_ALL_MODULES :=
+$(foreach m,$(SORTED_ALL_MODULES),\
+ $(if $(call streq,$(m),$(lastword $(UNIQUE_ALL_MODULES))),,\
+ $(eval UNIQUE_ALL_MODULES += $(m))))
+SORTED_ALL_MODULES :=
+
+$(foreach mod,$(UNIQUE_ALL_MODULES),$(if $(ALL_MODULES.$(mod).INSTALLED),\
+ $(eval $(call register_module_install_path,$(mod)))\
+ $(foreach path,$(ALL_MODULES.$(mod).PATH),\
+ $(eval my_path_prefix := GET-INSTALL-PATH-IN)\
+ $(foreach component,$(subst /,$(space),$(path)),\
+ $(eval my_path_prefix := $$(my_path_prefix)-$$(component))\
+ $(eval .PHONY: $$(my_path_prefix))\
+ $(eval $$(my_path_prefix): GET-MODULE-INSTALL-PATH-$(mod))))))
+UNIQUE_ALL_MODULES :=
else # ONE_SHOT_MAKEFILE
@@ -543,53 +398,34 @@
# Include all of the makefiles in the system
#
-# Can't use first-makefiles-under here because
-# --mindepth=2 makes the prunes not work.
-subdir_makefiles := \
- $(shell build/tools/findleaves.py $(FIND_LEAVES_EXCLUDES) $(subdirs) Android.mk)
+subdir_makefiles := $(SOONG_ANDROID_MK) $(call first-makefiles-under,$(TOP))
+subdir_makefiles_total := $(words $(subdir_makefiles))
+.KATI_READONLY := subdir_makefiles_total
-ifeq ($(USE_SOONG),true)
-subdir_makefiles := $(SOONG_ANDROID_MK) $(call filter-soong-makefiles,$(subdir_makefiles))
-endif
-
-$(foreach mk, $(subdir_makefiles),$(info including $(mk) ...)$(eval include $(mk)))
+$(foreach mk,$(subdir_makefiles),$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] including $(mk) ...)$(eval include $(mk)))
ifdef PDK_FUSION_PLATFORM_ZIP
# Bring in the PDK platform.zip modules.
include $(BUILD_SYSTEM)/pdk_fusion_modules.mk
endif # PDK_FUSION_PLATFORM_ZIP
+droid_targets : blueprint_tools
+
endif # dont_bother
endif # ONE_SHOT_MAKEFILE
-# Now with all Android.mks loaded we can do post cleaning steps.
-include $(BUILD_SYSTEM)/post_clean.mk
-
-ifeq ($(stash_product_vars),true)
- $(call assert-product-vars, __STASHED)
-endif
-
-include $(BUILD_SYSTEM)/legacy_prebuilts.mk
-ifneq ($(filter-out $(GRANDFATHERED_ALL_PREBUILT),$(strip $(notdir $(ALL_PREBUILT)))),)
- $(warning *** Some files have been added to ALL_PREBUILT.)
- $(warning *)
- $(warning * ALL_PREBUILT is a deprecated mechanism that)
- $(warning * should not be used for new files.)
- $(warning * As an alternative, use PRODUCT_COPY_FILES in)
- $(warning * the appropriate product definition.)
- $(warning * build/target/product/core.mk is the product)
- $(warning * definition used in all products.)
- $(warning *)
- $(foreach bad_prebuilt,$(filter-out $(GRANDFATHERED_ALL_PREBUILT),$(strip $(notdir $(ALL_PREBUILT)))),$(warning * unexpected $(bad_prebuilt) in ALL_PREBUILT))
- $(warning *)
- $(error ALL_PREBUILT contains unexpected files)
-endif
-
# -------------------------------------------------------------------
# All module makefiles have been included at this point.
# -------------------------------------------------------------------
+# -------------------------------------------------------------------
+# Enforce to generate all RRO packages for modules having resource
+# overlays.
+# -------------------------------------------------------------------
+ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),)
+$(call generate_all_enforce_rro_packages)
+endif
# -------------------------------------------------------------------
# Fix up CUSTOM_MODULES to refer to installed files rather than
@@ -613,19 +449,33 @@
#
# Resolve the required module name to 32-bit or 64-bit variant.
# Get a list of corresponding 32-bit module names, if one exists.
+ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
define get-32-bit-modules
-$(strip $(foreach m,$(1),\
+$(sort $(foreach m,$(1),\
$(if $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).CLASS),\
- $(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX))))
+ $(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX))\
+ $(if $(ALL_MODULES.$(m)$(HOST_2ND_ARCH_MODULE_SUFFIX).CLASS),\
+ $(m)$(HOST_2ND_ARCH_MODULE_SUFFIX))\
+ ))
endef
# Get a list of corresponding 32-bit module names, if one exists;
# otherwise return the original module name
define get-32-bit-modules-if-we-can
-$(strip $(foreach m,$(1),\
- $(if $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).CLASS),\
- $(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX),
- $(m))))
+$(sort $(foreach m,$(1),\
+ $(if $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).CLASS)$(ALL_MODULES.$(m)$(HOST_2ND_ARCH_MODULE_SUFFIX).CLASS),\
+ $(if $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).CLASS),$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX)) \
+ $(if $(ALL_MODULES.$(m)$(HOST_2ND_ARCH_MODULE_SUFFIX).CLASS),$(m)$(HOST_2ND_ARCH_MODULE_SUFFIX)),\
+ $(m))))
endef
+else # TARGET_TRANSLATE_2ND_ARCH
+# For binary translation config, by default only install the first arch.
+define get-32-bit-modules
+endef
+
+define get-32-bit-modules-if-we-can
+$(strip $(1))
+endef
+endif # TARGET_TRANSLATE_2ND_ARCH
# If a module is for a cross host os, the required modules must be for
# that OS too.
@@ -640,7 +490,7 @@
$(eval r := $(addprefix host_cross_,$(r))))\
$(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),\
$(eval r_r := $(call get-32-bit-modules-if-we-can,$(r))),\
- $(if $(filter EXECUTABLES SHARED_LIBRARIES,$(ALL_MODULES.$(m).CLASS)),\
+ $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS)),\
$(eval r_r := $(r)),\
$(eval r_r := $(r) $(call get-32-bit-modules,$(r)))\
)\
@@ -654,16 +504,24 @@
$(1): | $(2)
endef
+# Use a normal dependency instead of an order-only dependency when installing
+# host dynamic binaries so that the timestamp of the final binary always
+# changes, even if the toc optimization has skipped relinking the binary
+# and its dependant shared libraries.
+define add-required-host-so-deps
+$(1): $(2)
+endef
+
$(foreach m,$(ALL_MODULES), \
$(eval r := $(ALL_MODULES.$(m).REQUIRED)) \
$(if $(r), \
$(eval r := $(call module-installed-files,$(r))) \
$(eval t_m := $(filter $(TARGET_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
- $(eval h_m := $(filter $(HOST_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
- $(eval hc_m := $(filter $(HOST_CROSS_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
+ $(eval h_m := $(filter $(HOST_OUT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
+ $(eval hc_m := $(filter $(HOST_CROSS_OUT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
$(eval t_r := $(filter $(TARGET_OUT_ROOT)/%, $(r))) \
- $(eval h_r := $(filter $(HOST_OUT_ROOT)/%, $(r))) \
- $(eval hc_r := $(filter $(HOST_CROSS_OUT_ROOT)/%, $(r))) \
+ $(eval h_r := $(filter $(HOST_OUT)/%, $(r))) \
+ $(eval hc_r := $(filter $(HOST_CROSS_OUT)/%, $(r))) \
$(eval t_m := $(filter-out $(t_r), $(t_m))) \
$(eval h_m := $(filter-out $(h_r), $(h_m))) \
$(eval hc_m := $(filter-out $(hc_r), $(hc_m))) \
@@ -691,11 +549,14 @@
$(eval p := $(subst :,$(space),$(m)))\
$(eval mod := $(firstword $(p)))\
$(eval deps := $(subst $(comma),$(space),$(lastword $(p))))\
+ $(eval root := $(1)OUT$(if $(call streq,$(1),TARGET_),_ROOT))\
$(if $(2),$(eval deps := $(addsuffix $($(1)2ND_ARCH_MODULE_SUFFIX),$(deps))))\
$(if $(3),$(eval deps := $(addprefix host_cross_,$(deps))))\
- $(eval r := $(filter $($(1)OUT)/%,$(call module-installed-files,\
+ $(eval r := $(filter $($(root))/%,$(call module-installed-files,\
$(deps))))\
- $(eval $(call add-required-deps,$(word 2,$(p)),$(r)))\
+ $(if $(filter $(1),HOST_),\
+ $(eval $(call add-required-host-so-deps,$(word 2,$(p)),$(r))),\
+ $(eval $(call add-required-deps,$(word 2,$(p)),$(r))))\
$(eval ALL_MODULES.$(mod).REQUIRED += $(deps)))
endef
@@ -717,6 +578,168 @@
deps :=
add-required-deps :=
+################################################################################
+# Link type checking
+#
+# ALL_LINK_TYPES contains a list of all link type prefixes (generally one per
+# module, but APKs can "link" to both java and native code). The link type
+# prefix consists of all the information needed by intermediates-dir-for:
+#
+# LINK_TYPE:TARGET:_:2ND:STATIC_LIBRARIES:libfoo
+#
+# 1: LINK_TYPE literal
+# 2: prefix
+# - TARGET
+# - HOST
+# - HOST_CROSS
+# - AUX
+# 3: Whether to use the common intermediates directory or not
+# - _
+# - COMMON
+# 4: Whether it's the second arch or not
+# - _
+# - 2ND_
+# 5: Module Class
+# - STATIC_LIBRARIES
+# - SHARED_LIBRARIES
+# - ...
+# 6: Module Name
+#
+# Then fields under that are separated by a period and the field name:
+# - TYPE: the link types for this module
+# - MAKEFILE: Where this module was defined
+# - BUILT: The built module location
+# - DEPS: the link type prefixes for the module's dependencies
+# - ALLOWED: the link types to allow in this module's dependencies
+# - WARN: the link types to warn about in this module's dependencies
+#
+# All of the dependency link types not listed in ALLOWED or WARN will become
+# errors.
+################################################################################
+
+link_type_error :=
+
+define link-type-prefix
+$(word 2,$(subst :,$(space),$(1)))
+endef
+define link-type-common
+$(patsubst _,,$(word 3,$(subst :,$(space),$(1))))
+endef
+define link-type-2ndarchprefix
+$(patsubst _,,$(word 4,$(subst :,$(space),$(1))))
+endef
+define link-type-class
+$(word 5,$(subst :,$(space),$(1)))
+endef
+define link-type-name
+$(word 6,$(subst :,$(space),$(1)))
+endef
+define link-type-os
+$(strip $(eval _p := $(link-type-prefix))\
+ $(if $(filter HOST HOST_CROSS,$(_p)),\
+ $($(_p)_OS),\
+ $(if $(filter AUX,$(_p)),AUX,android)))
+endef
+define link-type-arch
+$($(link-type-prefix)_$(link-type-2ndarchprefix)ARCH)
+endef
+define link-type-name-variant
+$(link-type-name) ($(link-type-class) $(link-type-os)-$(link-type-arch))
+endef
+
+# $(1): the prefix of the module doing the linking
+# $(2): the prefix of the linked module
+define link-type-warning
+$(shell $(call echo-warning,$($(1).MAKEFILE),"$(call link-type-name,$(1)) ($($(1).TYPE)) should not link against $(call link-type-name,$(2)) ($(3))"))
+endef
+
+# $(1): the prefix of the module doing the linking
+# $(2): the prefix of the linked module
+define link-type-error
+$(shell $(call echo-error,$($(1).MAKEFILE),"$(call link-type-name,$(1)) ($($(1).TYPE)) can not link against $(call link-type-name,$(2)) ($(3))"))\
+$(eval link_type_error := true)
+endef
+
+link-type-missing :=
+ifneq ($(ALLOW_MISSING_DEPENDENCIES),true)
+ # Print an error message if the linked-to module is missing
+ # $(1): the prefix of the module doing the linking
+ # $(2): the prefix of the missing module
+ define link-type-missing
+ $(shell $(call echo-error,$($(1).MAKEFILE),"$(call link-type-name-variant,$(1)) missing $(call link-type-name-variant,$(2))"))\
+ $(eval available_variants := $(filter %:$(call link-type-name,$(2)),$(ALL_LINK_TYPES)))\
+ $(if $(available_variants),\
+ $(info Available variants:)\
+ $(foreach v,$(available_variants),$(info $(space)$(space)$(call link-type-name-variant,$(v)))))\
+ $(info You can set ALLOW_MISSING_DEPENDENCIES=true in your environment if this is intentional, but that may defer real problems until later in the build.)\
+ $(eval link_type_error := true)
+ endef
+else
+ define link-type-missing
+ $(eval $$(1).MISSING := true)
+ endef
+endif
+
+# Verify that $(1) can link against $(2)
+# Both $(1) and $(2) are the link type prefix defined above
+define verify-link-type
+$(foreach t,$($(2).TYPE),\
+ $(if $(filter-out $($(1).ALLOWED),$(t)),\
+ $(if $(filter $(t),$($(1).WARN)),\
+ $(call link-type-warning,$(1),$(2),$(t)),\
+ $(call link-type-error,$(1),$(2),$(t)))))
+endef
+
+# TODO: Verify all branches/configs have reasonable warnings/errors, and remove
+# these overrides
+link-type-missing = $(eval $$(1).MISSING := true)
+verify-link-type = $(eval $$(1).MISSING := true)
+
+$(foreach lt,$(ALL_LINK_TYPES),\
+ $(foreach d,$($(lt).DEPS),\
+ $(if $($(d).TYPE),\
+ $(call verify-link-type,$(lt),$(d)),\
+ $(call link-type-missing,$(lt),$(d)))))
+
+ifdef link_type_error
+ $(error exiting from previous errors)
+endif
+
+# The intermediate filename for link type rules
+#
+# APPS are special -- they have up to three different rules:
+# 1. The COMMON rule for Java libraries
+# 2. The jni_link_type rule for embedded native code
+# 3. The 2ND_jni_link_type for the second architecture native code
+define link-type-file
+$(call intermediates-dir-for,$(link-type-class),$(link-type-name),$(filter AUX HOST HOST_CROSS,$(link-type-prefix)),$(link-type-common),$(link-type-2ndarchprefix),$(filter HOST_CROSS,$(link-type-prefix)))/$(if $(filter APPS,$(link-type-class)),$(if $(link-type-common),,$(link-type-2ndarchprefix)jni_))link_type
+endef
+
+# Write out the file-based link_type rules for the ALLOW_MISSING_DEPENDENCIES
+# case. We always need to write the file for mm to work, but only need to
+# check it if we weren't able to check it when reading the Android.mk files.
+define link-type-file-rule
+my_link_type_deps := $(foreach l,$($(1).DEPS),$(call link-type-file,$(l)))
+my_link_type_file := $(call link-type-file,$(1))
+$($(1).BUILT): | $$(my_link_type_file)
+$$(my_link_type_file): PRIVATE_DEPS := $$(my_link_type_deps)
+ifeq ($($(1).MISSING),true)
+$$(my_link_type_file): $(CHECK_LINK_TYPE)
+endif
+$$(my_link_type_file): $$(my_link_type_deps)
+ @echo Check module type: $$@
+ $$(hide) mkdir -p $$(dir $$@) && rm -f $$@
+ifeq ($($(1).MISSING),true)
+ $$(hide) $(CHECK_LINK_TYPE) --makefile $($(1).MAKEFILE) --module $(link-type-name) \
+ --type "$($(1).TYPE)" $(addprefix --allowed ,$($(1).ALLOWED)) \
+ $(addprefix --warn ,$($(1).WARN)) $$(PRIVATE_DEPS)
+endif
+ $$(hide) echo "$($(1).TYPE)" >$$@
+endef
+
+$(foreach lt,$(ALL_LINK_TYPES),\
+ $(eval $(call link-type-file-rule,$(lt))))
+
# -------------------------------------------------------------------
# Figure out our module sets.
#
@@ -802,7 +825,7 @@
ifdef overridden_packages
# old_modules_to_install := $(modules_to_install)
modules_to_install := \
- $(filter-out $(foreach p,$(overridden_packages),$(p) %/$(p).apk %/$(p).odex), \
+ $(filter-out $(foreach p,$(overridden_packages),$(p) %/$(p).apk %/$(p).odex %/$(p).vdex), \
$(modules_to_install))
endif
#$(error filtered out
@@ -876,9 +899,6 @@
# This is used to to get the ordering right, you can also use these,
# but they're considered undocumented, so don't complain if their
# behavior changes.
-.PHONY: prebuilt
-prebuilt: $(ALL_PREBUILT)
-
# An internal target that depends on all copied headers
# (see copy_headers.make). Other targets that need the
# headers to be copied first can depend on this target.
@@ -889,17 +909,14 @@
# All the droid stuff, in directories
.PHONY: files
-files: prebuilt \
- $(modules_to_install) \
- $(INSTALLED_ANDROID_INFO_TXT_TARGET)
+files: $(modules_to_install) \
+ $(INSTALLED_ANDROID_INFO_TXT_TARGET)
# -------------------------------------------------------------------
.PHONY: checkbuild
checkbuild: $(modules_to_check) droid_targets
-ifeq ($(USE_SOONG),true)
-checkbuild: checkbuild-soong
-endif
+
ifeq (true,$(ANDROID_BUILD_EVERYTHING_BY_DEFAULT))
droid: checkbuild
endif
@@ -926,6 +943,9 @@
.PHONY: cacheimage
cacheimage: $(INSTALLED_CACHEIMAGE_TARGET)
+.PHONY: bptimage
+bptimage: $(INSTALLED_BPTIMAGE_TARGET)
+
.PHONY: vendorimage
vendorimage: $(INSTALLED_VENDORIMAGE_TARGET)
@@ -935,20 +955,11 @@
.PHONY: bootimage
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
-# phony target that include any targets in $(ALL_MODULES)
-.PHONY: all_modules
-ifndef BUILD_MODULES_IN_PATHS
-all_modules: $(ALL_MODULES)
-else
-# BUILD_MODULES_IN_PATHS is a list of paths relative to the top of the tree
-build_modules_in_paths := $(patsubst ./%,%,$(BUILD_MODULES_IN_PATHS))
-module_path_patterns := $(foreach p, $(build_modules_in_paths),\
- $(if $(filter %/,$(p)),$(p)%,$(p)/%))
-my_all_modules := $(sort $(foreach m, $(ALL_MODULES),$(if $(filter\
- $(module_path_patterns), $(addsuffix /,$(ALL_MODULES.$(m).PATH))),$(m))))
-all_modules: $(my_all_modules)
-endif
+.PHONY: vbmetaimage
+vbmetaimage: $(INSTALLED_VBMETAIMAGE_TARGET)
+.PHONY: auxiliary
+auxiliary: $(INSTALLED_AUX_TARGETS)
# Build files and then package it into the rom formats
.PHONY: droidcore
@@ -956,8 +967,10 @@
systemimage \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
+ $(INSTALLED_VBMETAIMAGE_TARGET) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_CACHEIMAGE_TARGET) \
+ $(INSTALLED_BPTIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
$(INSTALLED_FILES_FILE) \
@@ -1001,15 +1014,18 @@
$(SYMBOLS_ZIP) : $(apps_only_installed_files)
$(call dist-for-goals,apps_only, $(SYMBOLS_ZIP))
+ $(COVERAGE_ZIP) : $(apps_only_installed_files)
+ $(call dist-for-goals,apps_only, $(COVERAGE_ZIP))
+
.PHONY: apps_only
apps_only: $(unbundled_build_modules)
droid_targets: apps_only
# Combine the NOTICE files for a apps_only build
-$(eval $(call combine-notice-files, \
+$(eval $(call combine-notice-files, html, \
$(target_notice_file_txt), \
- $(target_notice_file_html), \
+ $(target_notice_file_html_or_xml), \
"Notices for files for apps:", \
$(TARGET_OUT_NOTICE_FILES), \
$(apps_only_installed_files)))
@@ -1021,6 +1037,7 @@
$(INTERNAL_OTA_PACKAGE_TARGET) \
$(BUILT_OTATOOLS_PACKAGE) \
$(SYMBOLS_ZIP) \
+ $(COVERAGE_ZIP) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_FILE_VENDOR) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
@@ -1064,13 +1081,14 @@
$(call dist-for-goals,sdk win_sdk, \
$(ALL_SDK_TARGETS) \
$(SYMBOLS_ZIP) \
+ $(COVERAGE_ZIP) \
$(INSTALLED_BUILD_PROP_TARGET) \
)
# umbrella targets to assit engineers in verifying builds
.PHONY: java native target host java-host java-target native-host native-target \
java-host-tests java-target-tests native-host-tests native-target-tests \
- java-tests native-tests host-tests target-tests tests
+ java-tests native-tests host-tests target-tests tests java-dex
# some synonyms
.PHONY: host-java target-java host-native target-native \
target-java-tests target-native-tests
@@ -1082,14 +1100,8 @@
target-native-tests : native-target-tests
tests : host-tests target-tests
-# To catch more build breakage, check build tests modules in eng and userdebug builds.
-ifneq ($(ANDROID_NO_TEST_CHECK),true)
-ifneq ($(TARGET_BUILD_PDK),true)
-ifneq ($(filter eng userdebug,$(TARGET_BUILD_VARIANT)),)
-droidcore : target-tests host-tests
-endif
-endif
-endif
+# Phony target to run all java compilations that use javac instead of jack.
+.PHONY: javac-check
ifneq (,$(filter samplecode, $(MAKECMDGOALS)))
.PHONY: samplecode
@@ -1100,7 +1112,7 @@
$(foreach module,$(sample_MODULES),$(eval $(call \
copy-one-file,$(module),$(sample_APKS_DEST_PATH)/$(notdir $(module)))))
sample_ADDITIONAL_INSTALLED := \
- $(filter-out $(modules_to_install) $(modules_to_check) $(ALL_PREBUILT),$(sample_MODULES))
+ $(filter-out $(modules_to_install) $(modules_to_check),$(sample_MODULES))
samplecode: $(sample_APKS_COLLECTION)
@echo "Collect sample code apks: $^"
# remove apks that are not intended to be installed.
@@ -1110,16 +1122,6 @@
.PHONY: findbugs
findbugs: $(INTERNAL_FINDBUGS_HTML_TARGET) $(INTERNAL_FINDBUGS_XML_TARGET)
-.PHONY: clean
-clean:
- @rm -rf $(OUT_DIR)/*
- @echo "Entire build directory removed."
-
-.PHONY: clobber
-clobber: clean
-
-# The rules for dataclean and installclean are defined in cleanbuild.mk.
-
#xxx scrape this from ALL_MODULE_NAME_TAGS
.PHONY: modules
modules:
@@ -1127,11 +1129,15 @@
@echo "$(call module-names-for-tag-list,$(ALL_MODULE_TAGS))" | \
tr -s ' ' '\n' | sort -u | $(COLUMN)
-.PHONY: showcommands
-showcommands:
- @echo >/dev/null
-
.PHONY: nothing
nothing:
@echo Successfully read the makefiles.
-endif # !relaunch_with_ninja
+
+.PHONY: tidy_only
+tidy_only:
+ @echo Successfully make tidy_only.
+
+ndk: $(SOONG_OUT_DIR)/ndk.timestamp
+.PHONY: ndk
+
+endif # KATI
diff --git a/core/math.mk b/core/math.mk
new file mode 100644
index 0000000..047d046
--- /dev/null
+++ b/core/math.mk
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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.
+#
+
+###########################################################
+# Basic math functions for positive integers <= 100
+#
+# (SDK versions for example)
+###########################################################
+__MATH_NUMBERS := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
+ 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
+ 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
+ 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
+ 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
+
+# Returns true if $(1) is a positive integer <= 100, otherwise returns nothing.
+define math_is_number
+$(strip \
+ $(if $(1),,$(error Argument missing)) \
+ $(if $(word 2,$(1)),$(error Multiple words in a single argument: $(1))) \
+ $(if $(filter $(1),$(__MATH_NUMBERS)),true))
+endef
+
+#$(warning true == $(call math_is_number,2))
+#$(warning == $(call math_is_number,foo))
+#$(call math_is_number,1 2)
+#$(call math_is_number,no 2)
+
+define _math_check_valid
+$(if $(call math_is_number,$(1)),,$(error Only positive integers <= 100 are supported (not $(1))))
+endef
+
+#$(call _math_check_valid,0)
+#$(call _math_check_valid,1)
+#$(call _math_check_valid,100)
+#$(call _math_check_valid,101)
+#$(call _math_check_valid,)
+#$(call _math_check_valid,1 2)
+
+# Returns the greater of $1 or $2.
+# If $1 or $2 is not a positive integer <= 100, then an error is generated.
+define math_max
+$(strip $(call _math_check_valid,$(1)) $(call _math_check_valid,$(2)) \
+ $(lastword $(filter $(1) $(2),$(__MATH_NUMBERS))))
+endef
+
+#$(call math_max)
+#$(call math_max,1)
+#$(call math_max,1 2,3)
+#$(warning 1 == $(call math_max,1,1))
+#$(warning 42 == $(call math_max,5,42))
+#$(warning 42 == $(call math_max,42,5))
+
+define math_gt_or_eq
+$(if $(filter $(1),$(call math_max,$(1),$(2))),true)
+endef
+
+#$(warning $(call math_gt_or_eq, 2, 1))
+#$(warning $(call math_gt_or_eq, 1, 1))
+#$(warning $(if $(call math_gt_or_eq, 1, 2),false,true))
+
+# $1 is the variable name to increment
+define inc_and_print
+$(strip $(eval $(1) := $($(1)) .)$(words $($(1))))
+endef
diff --git a/core/multi_prebuilt.mk b/core/multi_prebuilt.mk
index ed2fed6..77c57ab 100644
--- a/core/multi_prebuilt.mk
+++ b/core/multi_prebuilt.mk
@@ -14,6 +14,7 @@
# limitations under the License.
#
+$(call record-module-type,MULTI_PREBUILT)
ifneq ($(LOCAL_MODULE)$(LOCAL_MODULE_CLASS),)
$(error $(LOCAL_PATH): LOCAL_MODULE or LOCAL_MODULE_CLASS not needed by \
BUILD_MULTI_PREBUILT, use BUILD_PREBUILT instead!)
diff --git a/core/native_benchmark.mk b/core/native_benchmark.mk
index ac37701..e73bcad 100644
--- a/core/native_benchmark.mk
+++ b/core/native_benchmark.mk
@@ -2,6 +2,7 @@
## A thin wrapper around BUILD_EXECUTABLE
## Common flags for native benchmarks are added.
###########################################
+$(call record-module-type,NATIVE_BENCHMARK)
LOCAL_STATIC_LIBRARIES += libgoogle-benchmark
diff --git a/core/native_test.mk b/core/native_test.mk
index 93b7e1a..8b49fbd 100644
--- a/core/native_test.mk
+++ b/core/native_test.mk
@@ -2,6 +2,15 @@
## A thin wrapper around BUILD_EXECUTABLE
## Common flags for native tests are added.
###########################################
+$(call record-module-type,NATIVE_TEST)
+
+ifdef LOCAL_MODULE_CLASS
+ifneq ($(LOCAL_MODULE_CLASS),NATIVE_TESTS)
+$(error $(LOCAL_PATH): LOCAL_MODULE_CLASS must be NATIVE_TESTS with BUILD_HOST_NATIVE_TEST)
+endif
+endif
+
+LOCAL_MODULE_CLASS := NATIVE_TESTS
include $(BUILD_SYSTEM)/target_test_internal.mk
diff --git a/core/ninja.mk b/core/ninja.mk
deleted file mode 100644
index 9d0ff9a..0000000
--- a/core/ninja.mk
+++ /dev/null
@@ -1,192 +0,0 @@
-NINJA ?= prebuilts/ninja/$(HOST_PREBUILT_TAG)/ninja
-
-ifeq ($(USE_SOONG),true)
-USE_SOONG_FOR_KATI := true
-endif
-
-ifeq ($(USE_SOONG_FOR_KATI),true)
-include $(BUILD_SYSTEM)/soong.mk
-else
-KATI ?= $(HOST_OUT_EXECUTABLES)/ckati
-MAKEPARALLEL ?= $(HOST_OUT_EXECUTABLES)/makeparallel
-endif
-
-KATI_OUTPUT_PATTERNS := $(OUT_DIR)/build%.ninja $(OUT_DIR)/ninja%.sh
-
-# Modifier goals we don't need to pass to Ninja.
-NINJA_EXCLUDE_GOALS := showcommands all dist
-.PHONY : $(NINJA_EXCLUDE_GOALS)
-
-# A list of goals which affect parsing of makefiles and we need to pass to Kati.
-PARSE_TIME_MAKE_GOALS := \
- $(PARSE_TIME_MAKE_GOALS) \
- $(dont_bother_goals) \
- all \
- APP-% \
- DUMP_% \
- ECLIPSE-% \
- PRODUCT-% \
- boottarball-nodeps \
- btnod \
- build-art% \
- build_kernel-nodeps \
- clean-oat% \
- continuous_instrumentation_tests \
- continuous_native_tests \
- cts \
- custom_images \
- deps-license \
- dicttool_aosp \
- dist \
- dump-products \
- dumpvar-% \
- eng \
- fusion \
- oem_image \
- old-cts \
- online-system-api-sdk-docs \
- pdk \
- platform \
- platform-java \
- product-graph \
- samplecode \
- sdk \
- sdk_addon \
- sdk_repo \
- snod \
- stnod \
- systemimage-nodeps \
- systemtarball-nodeps \
- target-files-package \
- test-art% \
- user \
- userdataimage \
- userdebug \
- valgrind-test-art% \
- vts \
- win_sdk \
- winsdk-tools
-
--include vendor/google/build/ninja_config.mk
-
-# Any Android goals that need to be built.
-ANDROID_GOALS := $(filter-out $(KATI_OUTPUT_PATTERNS) $(KATI) $(MAKEPARALLEL),\
- $(sort $(ORIGINAL_MAKECMDGOALS) $(MAKECMDGOALS)))
-# Goals we need to pass to Ninja.
-NINJA_GOALS := $(filter-out $(NINJA_EXCLUDE_GOALS), $(ANDROID_GOALS))
-# Goals we need to pass to Kati.
-KATI_GOALS := $(filter $(PARSE_TIME_MAKE_GOALS), $(ANDROID_GOALS))
-
-define replace_space_and_slash
-$(subst /,_,$(subst $(space),_,$(sort $1)))
-endef
-
-KATI_NINJA_SUFFIX := -$(TARGET_PRODUCT)
-ifneq ($(KATI_GOALS),)
-KATI_NINJA_SUFFIX := $(KATI_NINJA_SUFFIX)-$(call replace_space_and_slash,$(KATI_GOALS))
-endif
-ifneq ($(ONE_SHOT_MAKEFILE),)
-KATI_NINJA_SUFFIX := $(KATI_NINJA_SUFFIX)-mmm-$(call replace_space_and_slash,$(ONE_SHOT_MAKEFILE))
-endif
-ifneq ($(BUILD_MODULES_IN_PATHS),)
-KATI_NINJA_SUFFIX := $(KATI_NINJA_SUFFIX)-mmma-$(call replace_space_and_slash,$(BUILD_MODULES_IN_PATHS))
-endif
-
-my_checksum_suffix :=
-my_ninja_suffix_too_long := $(filter 1, $(shell v='$(KATI_NINJA_SUFFIX)' && echo $$(($${$(pound)v} > 64))))
-ifneq ($(my_ninja_suffix_too_long),)
-# Replace the suffix with a checksum if it gets too long.
-my_checksum_suffix := $(KATI_NINJA_SUFFIX)
-KATI_NINJA_SUFFIX := -$(word 1, $(shell echo $(my_checksum_suffix) | $(MD5SUM)))
-endif
-
-KATI_BUILD_NINJA := $(OUT_DIR)/build$(KATI_NINJA_SUFFIX).ninja
-KATI_ENV_SH := $(OUT_DIR)/env$(KATI_NINJA_SUFFIX).sh
-
-# Write out a file mapping checksum to the real suffix.
-ifneq ($(my_checksum_suffix),)
-my_ninja_suffix_file := $(basename $(KATI_BUILD_NINJA)).suf
-$(shell mkdir -p $(dir $(my_ninja_suffix_file)) && \
- echo $(my_checksum_suffix) > $(my_ninja_suffix_file))
-endif
-
-ifeq (,$(NINJA_STATUS))
-NINJA_STATUS := [%p %s/%t]$(space)
-endif
-
-ifneq (,$(filter showcommands,$(ORIGINAL_MAKECMDGOALS)))
-NINJA_ARGS += "-v"
-endif
-
-ifdef USE_GOMA
-KATI_MAKEPARALLEL := $(MAKEPARALLEL)
-# Ninja runs remote jobs (i.e., commands which contain gomacc) with
-# this parallelism. Note the parallelism of all other jobs is still
-# limited by the -j flag passed to GNU make.
-NINJA_REMOTE_NUM_JOBS ?= 500
-NINJA_ARGS += -j$(NINJA_REMOTE_NUM_JOBS)
-else
-NINJA_MAKEPARALLEL := $(MAKEPARALLEL) --ninja
-endif
-
-ifeq ($(USE_SOONG),true)
-COMBINED_BUILD_NINJA := $(OUT_DIR)/combined$(KATI_NINJA_SUFFIX).ninja
-
-$(COMBINED_BUILD_NINJA): $(KATI_BUILD_NINJA) $(SOONG_ANDROID_MK)
- $(hide) echo "builddir = $(OUT_DIR)" > $(COMBINED_BUILD_NINJA)
- $(hide) echo "subninja $(SOONG_BUILD_NINJA)" >> $(COMBINED_BUILD_NINJA)
- $(hide) echo "subninja $(KATI_BUILD_NINJA)" >> $(COMBINED_BUILD_NINJA)
-else
-COMBINED_BUILD_NINJA := $(KATI_BUILD_NINJA)
-endif
-
-$(sort $(DEFAULT_GOAL) $(ANDROID_GOALS)) : ninja_wrapper
- @#empty
-
-.PHONY: ninja_wrapper
-ninja_wrapper: $(COMBINED_BUILD_NINJA) $(MAKEPARALLEL)
- @echo Starting build with ninja
- +$(hide) export NINJA_STATUS="$(NINJA_STATUS)" && source $(KATI_ENV_SH) && $(NINJA_MAKEPARALLEL) $(NINJA) $(NINJA_GOALS) -C $(TOP) -f $(COMBINED_BUILD_NINJA) $(NINJA_ARGS)
-
-# Dummy Android.mk and CleanSpec.mk files so that kati won't recurse into the
-# out directory
-DUMMY_OUT_MKS := $(OUT_DIR)/Android.mk $(OUT_DIR)/CleanSpec.mk
-$(DUMMY_OUT_MKS):
- @mkdir -p $(dir $@)
- $(hide) echo '# This file prevents findleaves.py from traversing this directory further' >$@
-
-KATI_FIND_EMULATOR := --use_find_emulator
-ifeq ($(KATI_EMULATE_FIND),false)
- KATI_FIND_EMULATOR :=
-endif
-$(KATI_BUILD_NINJA): $(KATI) $(MAKEPARALLEL) $(DUMMY_OUT_MKS) $(SOONG_ANDROID_MK) FORCE
- @echo Running kati to generate build$(KATI_NINJA_SUFFIX).ninja...
- +$(hide) $(KATI_MAKEPARALLEL) $(KATI) --ninja --ninja_dir=$(OUT_DIR) --ninja_suffix=$(KATI_NINJA_SUFFIX) --regen --ignore_dirty=$(OUT_DIR)/% --no_ignore_dirty=$(SOONG_ANDROID_MK) --ignore_optional_include=$(OUT_DIR)/%.P --detect_android_echo $(KATI_FIND_EMULATOR) -f build/core/main.mk $(KATI_GOALS) --gen_all_targets BUILDING_WITH_NINJA=true SOONG_ANDROID_MK=$(SOONG_ANDROID_MK)
-
-ifneq ($(USE_SOONG_FOR_KATI),true)
-KATI_CXX := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_CFLAGS) $(CLANG_HOST_GLOBAL_CPPFLAGS)
-KATI_LD := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_LDFLAGS)
-# Build static ckati. Unfortunately Mac OS X doesn't officially support static exectuables.
-ifeq ($(BUILD_OS),linux)
-# We need everything in libpthread.a otherwise C++11's threading library will be disabled.
-KATI_LD += -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -ldl
-endif
-
-KATI_INTERMEDIATES_PATH := $(HOST_OUT_INTERMEDIATES)/EXECUTABLES/ckati_intermediates
-KATI_BIN_PATH := $(HOST_OUT_EXECUTABLES)
-include build/kati/Makefile.ckati
-
-MAKEPARALLEL_CXX := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_CFLAGS) $(CLANG_HOST_GLOBAL_CPPFLAGS)
-MAKEPARALLEL_LD := $(CLANG_CXX) $(CLANG_HOST_GLOBAL_LDFLAGS)
-# Build static makeparallel. Unfortunately Mac OS X doesn't officially support static exectuables.
-ifeq ($(BUILD_OS),linux)
-MAKEPARALLEL_LD += -static
-endif
-
-MAKEPARALLEL_INTERMEDIATES_PATH := $(HOST_OUT_INTERMEDIATES)/EXECUTABLES/makeparallel_intermediates
-MAKEPARALLEL_BIN_PATH := $(HOST_OUT_EXECUTABLES)
-include build/tools/makeparallel/Makefile
-endif
-
-.PHONY: FORCE
-FORCE:
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
new file mode 100644
index 0000000..ca2dcee
--- /dev/null
+++ b/core/ninja_config.mk
@@ -0,0 +1,70 @@
+ifeq ($(filter address,$(SANITIZE_HOST)),)
+NINJA ?= prebuilts/build-tools/$(HOST_PREBUILT_TAG)/bin/ninja
+else
+NINJA ?= prebuilts/build-tools/$(HOST_PREBUILT_TAG)/asan/bin/ninja
+endif
+
+KATI_OUTPUT_PATTERNS := $(OUT_DIR)/build%.ninja $(OUT_DIR)/ninja%.sh
+
+# Modifier goals we don't need to pass to Ninja.
+NINJA_EXCLUDE_GOALS := all dist APP-% PRODUCT-%
+
+# A list of goals which affect parsing of makefiles and we need to pass to Kati.
+PARSE_TIME_MAKE_GOALS := \
+ $(PARSE_TIME_MAKE_GOALS) \
+ $(dont_bother_goals) \
+ all \
+ ECLIPSE-% \
+ AUX-% \
+ boottarball-nodeps \
+ brillo_tests \
+ btnod \
+ build-art% \
+ build_kernel-nodeps \
+ clean-oat% \
+ continuous_instrumentation_tests \
+ continuous_native_tests \
+ cts \
+ custom_images \
+ deps-license \
+ dicttool_aosp \
+ dist \
+ dump-products \
+ eng \
+ fusion \
+ oem_image \
+ online-system-api-sdk-docs \
+ pdk \
+ platform \
+ platform-java \
+ product-graph \
+ samplecode \
+ sdk \
+ sdk_addon \
+ sdk_repo \
+ snod \
+ stnod \
+ systemimage-nodeps \
+ systemtarball-nodeps \
+ target-files-package \
+ test-art% \
+ user \
+ userdataimage \
+ userdebug \
+ valgrind-test-art% \
+ vts \
+ win_sdk \
+ winsdk-tools
+
+include $(wildcard vendor/*/build/ninja_config.mk)
+
+# Any Android goals that need to be built.
+ANDROID_GOALS := $(filter-out $(KATI_OUTPUT_PATTERNS) $(CKATI) $(MAKEPARALLEL),\
+ $(sort $(ORIGINAL_MAKECMDGOALS) $(MAKECMDGOALS)))
+# Goals we need to pass to Ninja.
+NINJA_GOALS := $(filter-out $(NINJA_EXCLUDE_GOALS), $(ANDROID_GOALS))
+ifndef NINJA_GOALS
+ NINJA_GOALS := droid
+endif
+# Goals we need to pass to Kati.
+KATI_GOALS := $(filter $(PARSE_TIME_MAKE_GOALS), $(ANDROID_GOALS))
diff --git a/core/no_java_path/jar b/core/no_java_path/jar
new file mode 120000
index 0000000..8586397
--- /dev/null
+++ b/core/no_java_path/jar
@@ -0,0 +1 @@
+java
\ No newline at end of file
diff --git a/core/no_java_path/jarsigner b/core/no_java_path/jarsigner
new file mode 120000
index 0000000..8586397
--- /dev/null
+++ b/core/no_java_path/jarsigner
@@ -0,0 +1 @@
+java
\ No newline at end of file
diff --git a/core/no_java_path/java b/core/no_java_path/java
new file mode 100755
index 0000000..f3422f3
--- /dev/null
+++ b/core/no_java_path/java
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+echo "Error: JAVA_NOT_REQUIRED=true, $(basename $0) is unavailable." 1>&2
+exit 1
diff --git a/core/no_java_path/javac b/core/no_java_path/javac
new file mode 120000
index 0000000..8586397
--- /dev/null
+++ b/core/no_java_path/javac
@@ -0,0 +1 @@
+java
\ No newline at end of file
diff --git a/core/no_java_path/keytool b/core/no_java_path/keytool
new file mode 120000
index 0000000..8586397
--- /dev/null
+++ b/core/no_java_path/keytool
@@ -0,0 +1 @@
+java
\ No newline at end of file
diff --git a/core/notice_files.mk b/core/notice_files.mk
index e7f8974..f850fff 100644
--- a/core/notice_files.mk
+++ b/core/notice_files.mk
@@ -1,6 +1,7 @@
###########################################################
## Track NOTICE files
###########################################################
+$(call record-module-type,NOTICE_FILE)
ifneq ($(LOCAL_NOTICE_FILE),)
notice_file:=$(strip $(LOCAL_NOTICE_FILE))
@@ -13,6 +14,14 @@
notice_file :=
endif
+# Soong generates stub libraries that don't need NOTICE files
+ifdef LOCAL_NO_NOTICE_FILE
+ ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ $(call pretty-error,LOCAL_NO_NOTICE_FILE should not be used by Android.mk files)
+ endif
+ notice_file :=
+endif
+
ifeq ($(LOCAL_MODULE_CLASS),NOTICE_FILES)
# If this is a NOTICE-only module, we don't include base_rule.mk,
# so my_prefix is not set at this point.
@@ -32,15 +41,15 @@
# compliance.
# Includes the leading slash
ifdef LOCAL_INSTALLED_MODULE
- module_installed_filename := $(patsubst $(PRODUCT_OUT)%,%,$(LOCAL_INSTALLED_MODULE))
+ module_installed_filename := $(patsubst $(PRODUCT_OUT)/%,%,$(LOCAL_INSTALLED_MODULE))
else
# This module isn't installable
- ifeq ($(LOCAL_MODULE_CLASS),STATIC_LIBRARIES)
+ ifneq ($(filter STATIC_LIBRARIES HEADER_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
# Stick the static libraries with the dynamic libraries.
# We can't use xxx_OUT_STATIC_LIBRARIES because it points into
# device-obj or host-obj.
module_installed_filename := \
- $(patsubst $(PRODUCT_OUT)%,%,$($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_SHARED_LIBRARIES))/$(notdir $(LOCAL_BUILT_MODULE))
+ $(patsubst $(PRODUCT_OUT)/%,%,$($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_SHARED_LIBRARIES))/$(notdir $(LOCAL_BUILT_MODULE))
else
ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
# Stick the static java libraries with the regular java libraries.
@@ -52,7 +61,7 @@
module_leaf := $(LOCAL_MODULE).jar
endif
module_installed_filename := \
- $(patsubst $(PRODUCT_OUT)%,%,$($(my_prefix)OUT_JAVA_LIBRARIES))/$(module_leaf)
+ $(patsubst $(PRODUCT_OUT)/%,%,$($(my_prefix)OUT_JAVA_LIBRARIES))/$(module_leaf)
else
$(error Cannot determine where to install NOTICE file for $(LOCAL_MODULE))
endif # JAVA_LIBRARIES
@@ -60,8 +69,8 @@
endif
# In case it's actually a host file
-module_installed_filename := $(patsubst $(HOST_OUT)%,%,$(module_installed_filename))
-module_installed_filename := $(patsubst $(HOST_CROSS_OUT)%,%,$(module_installed_filename))
+module_installed_filename := $(patsubst $(HOST_OUT)/%,%,$(module_installed_filename))
+module_installed_filename := $(patsubst $(HOST_CROSS_OUT)/%,%,$(module_installed_filename))
installed_notice_file := $($(my_prefix)OUT_NOTICE_FILES)/src/$(module_installed_filename).txt
diff --git a/core/package.mk b/core/package.mk
index 78b65db..f3713fc 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -2,9 +2,17 @@
# TARGET_ARCH and TARGET_2ND_ARCH.
# To build it for TARGET_2ND_ARCH in a 64bit product, use "LOCAL_MULTILIB := 32".
+$(call record-module-type,PACKAGE)
+
my_prefix := TARGET_
include $(BUILD_SYSTEM)/multilib.mk
+ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+ ifneq ($(TARGET_SUPPORTS_64_BIT_APPS)|$(my_module_multilib),|64)
+ my_module_multilib := first
+ endif
+endif
+
ifeq ($(TARGET_SUPPORTS_32_BIT_APPS)|$(TARGET_SUPPORTS_64_BIT_APPS),true|true)
# packages default to building for either architecture,
# the preferred if its supported, otherwise the non-preferred.
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 551f18e..6255ef1 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -92,6 +92,7 @@
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
else
need_compile_res := true
+ LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
endif
package_resource_overlays := $(strip \
@@ -100,7 +101,34 @@
$(wildcard $(foreach dir, $(DEVICE_PACKAGE_OVERLAYS), \
$(addprefix $(dir)/, $(LOCAL_RESOURCE_DIR)))))
+enforce_rro_enabled :=
+ifneq ($(PRODUCT_ENFORCE_RRO_TARGETS),)
+ ifneq ($(package_resource_overlays),)
+ ifeq ($(PRODUCT_ENFORCE_RRO_TARGETS),*)
+ enforce_rro_enabled := true
+ else ifneq (,$(filter $(LOCAL_PACKAGE_NAME), $(PRODUCT_ENFORCE_RRO_TARGETS)))
+ enforce_rro_enabled := true
+ endif
+ endif
+
+ ifdef enforce_rro_enabled
+ ifeq (,$(LOCAL_MODULE_PATH))
+ ifeq (true,$(LOCAL_PROPRIETARY_MODULE))
+ enforce_rro_enabled :=
+ else ifeq (true,$(LOCAL_OEM_MODULE))
+ enforce_rro_enabled :=
+ else ifeq (true,$(LOCAL_ODM_MODULE))
+ enforce_rro_enabled :=
+ endif
+ else ifeq ($(filter $(TARGET_OUT)/%,$(LOCAL_MODULE_PATH)),)
+ enforce_rro_enabled :=
+ endif
+ endif
+endif
+
+ifndef enforce_rro_enabled
LOCAL_RESOURCE_DIR := $(package_resource_overlays) $(LOCAL_RESOURCE_DIR)
+endif
all_assets := $(strip \
$(foreach dir, $(LOCAL_ASSET_DIR), \
@@ -140,9 +168,9 @@
$(addprefix $(d)/, \
$(call find-subdir-assets,$(d)))))
-my_res_resources := $(strip \
+my_res_resources := $(if $(my_res_dir),$(strip \
$(addprefix $(my_res_dir)/, \
- $(call find-subdir-assets,$(my_res_dir))))
+ $(call find-subdir-assets,$(my_res_dir)))))
all_resources := $(strip $(my_res_resources) $(my_overlay_resources))
@@ -251,25 +279,26 @@
LOCAL_PROGUARD_FLAGS += -include $(BUILD_SYSTEM)/proguard.jacoco.flags
LOCAL_JACK_PROGUARD_FLAGS += -include $(BUILD_SYSTEM)/proguard.jacoco.flags
endif # Contains java code
-else
+else # ! LOCAL_JACK_ENABLED
LOCAL_STATIC_JAVA_LIBRARIES += emma
-endif # LOCAL_JACK_ENABLED
-else
+endif # ! LOCAL_JACK_ENABLED
+else # ! TARGET_BUILD_APPS
+ifdef LOCAL_JACK_ENABLED
# If build against the SDK in full build, core.jar is not used
# so coverage classes are not present.
-ifdef LOCAL_JACK_ENABLED
# Jack needs jacoco on the classpath but we do not want it to be in
# the final apk. While it is a static library, we add it to the
# LOCAL_JAVA_LIBRARIES which are only present on the classpath.
# Note: we have nothing to do for proguard since jacoco will be
# on the classpath only, thus not modified during the compilation.
LOCAL_JAVA_LIBRARIES += jacocoagent
-else
-# We have to use prebuilt emma.jar to make Proguard happy;
+else # ! LOCAL_JACK_ENABLED
+# If build against the SDK in full build, core.jar is not used,
+# we have to use prebiult emma.jar to make Proguard happy;
# Otherwise emma classes are included in core.jar.
LOCAL_PROGUARD_FLAGS += -libraryjars $(EMMA_JAR)
-endif # LOCAL_JACK_ENABLED
-endif # full build
+endif # ! LOCAL_JACK_ENABLED
+endif # ! TARGET_BUILD_APPS
endif # LOCAL_SDK_VERSION
endif # EMMA_INSTRUMENT_STATIC
endif # LOCAL_EMMA_INSTRUMENT
@@ -307,13 +336,6 @@
$(LOCAL_INTERMEDIATE_TARGETS): \
PRIVATE_ANDROID_MANIFEST := $(full_android_manifest)
-ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-$(LOCAL_INTERMEDIATE_TARGETS): \
- PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
-else
-$(LOCAL_INTERMEDIATE_TARGETS): \
- PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
-endif
ifeq ($(LOCAL_DATA_BINDING),true)
data_binding_stamp := $(data_binding_intermediates)/data-binding.stamp
@@ -346,8 +368,23 @@
ifeq ($(need_compile_res),true)
ifdef LOCAL_USE_AAPT2
my_compiled_res_base_dir := $(intermediates)/flat-res
+renderscript_target_api :=
+ifneq (,$(LOCAL_RENDERSCRIPT_TARGET_API))
+renderscript_target_api := $(LOCAL_RENDERSCRIPT_TARGET_API)
+else
+ifneq (,$(LOCAL_SDK_VERSION))
+# Set target-api for LOCAL_SDK_VERSIONs other than current.
+ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+renderscript_target_api := $(LOCAL_SDK_VERSION)
+endif
+endif # LOCAL_SDK_VERSION is set
+endif # LOCAL_RENDERSCRIPT_TARGET_API is set
+ifneq (,$(renderscript_target_api))
+ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
my_generated_res_dirs := $(rs_generated_res_dir)
my_generated_res_dirs_deps := $(RenderScript_file_stamp)
+endif # renderscript_target_api < 21
+endif # renderscript_target_api is set
# Add AAPT2 link specific flags.
$(my_res_package): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --no-static-lib-packages
include $(BUILD_SYSTEM)/aapt2.mk
@@ -463,7 +500,7 @@
ifneq ($(full_classes_jar),)
$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
# Use the jarjar processed arhive as the initial package file.
-$(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE := $(full_classes_jarjar_jar)
+$(LOCAL_BUILT_MODULE): PRIVATE_SOURCE_ARCHIVE := $(full_classes_pre_proguard_jar)
$(LOCAL_BUILT_MODULE): $(built_dex)
else
$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE :=
@@ -494,6 +531,7 @@
endif
private_key := $(LOCAL_CERTIFICATE).pk8
certificate := $(LOCAL_CERTIFICATE).x509.pem
+additional_certificates := $(foreach c,$(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
$(LOCAL_BUILT_MODULE): $(private_key) $(certificate) $(SIGNAPK_JAR)
$(LOCAL_BUILT_MODULE): PRIVATE_PRIVATE_KEY := $(private_key)
@@ -502,8 +540,8 @@
PACKAGES.$(LOCAL_PACKAGE_NAME).PRIVATE_KEY := $(private_key)
PACKAGES.$(LOCAL_PACKAGE_NAME).CERTIFICATE := $(certificate)
-$(LOCAL_BUILT_MODULE): PRIVATE_ADDITIONAL_CERTIFICATES := $(foreach c,\
- $(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8)
+$(LOCAL_BUILT_MODULE): $(additional_certificates)
+$(LOCAL_BUILT_MODULE): PRIVATE_ADDITIONAL_CERTIFICATES := $(additional_certificates)
# Define the rule to build the actual package.
# PRIVATE_JNI_SHARED_LIBRARIES is a list of <abi>:<path_of_built_lib>.
@@ -535,15 +573,8 @@
endif
@echo "target Package: $(PRIVATE_MODULE) ($@)"
ifdef LOCAL_USE_AAPT2
-ifdef LOCAL_JACK_ENABLED
$(call copy-file-to-new-target)
-else
- @# TODO: implement merge-two-packages.
- $(if $(PRIVATE_SOURCE_ARCHIVE),\
- $(call merge-two-packages,$(PRIVATE_RES_PACKAGE) $(PRIVATE_SOURCE_ARCHIVE),$@),
- $(call copy-file-to-new-target))
-endif
-else # LOCAL_USE_AAPT2
+else # ! LOCAL_USE_AAPT2
ifdef LOCAL_JACK_ENABLED
$(create-empty-package)
else
@@ -605,7 +636,7 @@
# LOCAL_PACKAGE_SPLITS is a list of resource labels.
# aapt will convert comma inside resource lable to underscore in the file names.
my_split_suffixes := $(subst $(comma),_,$(LOCAL_PACKAGE_SPLITS))
-built_apk_splits := $(foreach s,$(my_split_suffixes),$(built_module_path)/package_$(s).apk)
+built_apk_splits := $(foreach s,$(my_split_suffixes),$(intermediates)/package_$(s).apk)
installed_apk_splits := $(foreach s,$(my_split_suffixes),$(my_module_path)/$(LOCAL_MODULE)_$(s).apk)
# The splits should have been built in the same command building the base apk.
@@ -615,7 +646,7 @@
# That way the build system will rerun the aapt after the user changes the splitting parameters.
$(built_apk_splits): PRIVATE_PRIVATE_KEY := $(private_key)
$(built_apk_splits): PRIVATE_CERTIFICATE := $(certificate)
-$(built_apk_splits) : $(built_module_path)/%.apk : $(LOCAL_BUILT_MODULE)
+$(built_apk_splits) : $(intermediates)/%.apk : $(LOCAL_BUILT_MODULE)
$(hide) if [ ! -f $@ ]; then \
echo 'No $@ generated, check your apk splitting parameters.' 1>&2; \
rm $<; exit 1; \
@@ -623,37 +654,33 @@
$(sign-package)
# Rules to install the splits
-$(installed_apk_splits) : $(my_module_path)/$(LOCAL_MODULE)_%.apk : $(built_module_path)/package_%.apk | $(ACP)
+$(installed_apk_splits) : $(my_module_path)/$(LOCAL_MODULE)_%.apk : $(intermediates)/package_%.apk
@echo "Install: $@"
$(copy-file-to-new-target)
# Register the additional built and installed files.
ALL_MODULES.$(my_register_name).INSTALLED += $(installed_apk_splits)
ALL_MODULES.$(my_register_name).BUILT_INSTALLED += \
- $(foreach s,$(my_split_suffixes),$(built_module_path)/package_$(s).apk:$(my_module_path)/$(LOCAL_MODULE)_$(s).apk)
+ $(foreach s,$(my_split_suffixes),$(intermediates)/package_$(s).apk:$(my_module_path)/$(LOCAL_MODULE)_$(s).apk)
# Make sure to install the splits when you run "make <module_name>".
-$(my_register_name): $(installed_apk_splits)
+$(my_all_targets): $(installed_apk_splits)
ifdef LOCAL_COMPATIBILITY_SUITE
-cts_testcase_file := $(foreach s,$(my_split_suffixes),$(COMPATIBILITY_TESTCASES_OUT_$(LOCAL_COMPATIBILITY_SUITE))/$(LOCAL_MODULE)_$(s).apk)
-$(cts_testcase_file) : $(COMPATIBILITY_TESTCASES_OUT_$(LOCAL_COMPATIBILITY_SUITE))/$(LOCAL_MODULE)_%.apk : $(built_module_path)/package_%.apk | $(ACP)
- $(copy-file-to-new-target)
-COMPATIBILITY.$(LOCAL_COMPATIBILITY_SUITE).FILES := \
- $(COMPATIBILITY.$(LOCAL_COMPATIBILITY_SUITE).FILES) \
- $(cts_testcase_file)
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_$(suite) := $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(foreach s,$(my_split_suffixes),\
+ $(intermediates)/package_$(s).apk:$(dir)/$(LOCAL_MODULE)_$(s).apk))))
-$(my_register_name) : $(cts_testcase_file)
+$(call create-suite-dependencies)
+
endif # LOCAL_COMPATIBILITY_SUITE
endif # LOCAL_PACKAGE_SPLITS
# Save information about this package
PACKAGES.$(LOCAL_PACKAGE_NAME).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
PACKAGES.$(LOCAL_PACKAGE_NAME).RESOURCE_FILES := $(all_resources)
-ifdef package_resource_overlays
-PACKAGES.$(LOCAL_PACKAGE_NAME).RESOURCE_OVERLAYS := $(package_resource_overlays)
-endif
PACKAGES := $(PACKAGES) $(LOCAL_PACKAGE_NAME)
@@ -661,3 +688,27 @@
# Reset internal variables.
all_res_assets :=
+
+ifdef enforce_rro_enabled
+ ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
+ enforce_rro_use_res_lib := true
+ else
+ enforce_rro_use_res_lib := false
+ endif
+
+ ifdef LOCAL_MANIFEST_PACKAGE_NAME
+ enforce_rro_is_manifest_package_name := true
+ enforce_rro_manifest_package_info := $(LOCAL_MANIFEST_PACKAGE_NAME)
+ else
+ enforce_rro_is_manifest_package_name := false
+ enforce_rro_manifest_package_info := $(full_android_manifest)
+ endif
+
+$(call append_enforce_rro_sources, \
+ $(my_register_name), \
+ $(enforce_rro_is_manifest_package_name), \
+ $(enforce_rro_manifest_package_info), \
+ $(enforce_rro_use_res_lib), \
+ $(package_resource_overlays) \
+ )
+endif # enforce_rro_enabled
diff --git a/core/pathmap.mk b/core/pathmap.mk
index effc878..c328e58 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -49,8 +49,7 @@
audio-route:system/media/audio_route/include \
wilhelm:frameworks/wilhelm/include \
wilhelm-ut:frameworks/wilhelm/src/ut \
- mediandk:frameworks/av/media/ndk/ \
- speex:external/speex/include
+ mediandk:frameworks/av/media/ndk/
#
# Returns the path to the requested module's include directory,
@@ -115,7 +114,6 @@
v7/cardview \
v7/mediarouter \
v7/palette \
- v8/renderscript \
v13 \
v17/leanback \
design \
@@ -142,6 +140,7 @@
FRAMEWORKS_SUPPORT_JAVA_SRC_DIRS := \
$(addprefix frameworks/support/,$(FRAMEWORKS_SUPPORT_SUBDIRS)) \
$(addprefix frameworks/,$(FRAMEWORKS_MULTIDEX_SUBDIRS)) \
+ frameworks/rs/support \
frameworks/support/graphics/drawable/animated \
frameworks/support/graphics/drawable/static \
frameworks/support/v7/appcompat/src \
@@ -157,6 +156,7 @@
android-support-animatedvectordrawable \
android-support-v7-appcompat \
android-support-v7-recyclerview \
+ android-support-v8-renderscript \
android-support-multidex \
android-support-multidex-instrumentation
diff --git a/core/pdk_config.mk b/core/pdk_config.mk
index c0aaacd..8c986d6 100644
--- a/core/pdk_config.mk
+++ b/core/pdk_config.mk
@@ -17,7 +17,7 @@
target/common/obj/JAVA_LIBRARIES/conscrypt_intermediates \
target/common/obj/JAVA_LIBRARIES/core-oj_intermediates \
target/common/obj/JAVA_LIBRARIES/core-libart_intermediates \
- target/common/obj/JAVA_LIBRARIES/core-junit_intermediates \
+ target/common/obj/JAVA_LIBRARIES/legacy-test_intermediates \
target/common/obj/JAVA_LIBRARIES/ext_intermediates \
target/common/obj/JAVA_LIBRARIES/framework_intermediates \
target/common/obj/JAVA_LIBRARIES/ims-common_intermediates \
diff --git a/core/pdk_fusion_modules.mk b/core/pdk_fusion_modules.mk
index 49b30dc..0c03f37 100644
--- a/core/pdk_fusion_modules.mk
+++ b/core/pdk_fusion_modules.mk
@@ -23,7 +23,7 @@
LOCAL_BUILT_MODULE_STEM:=$(7)
LOCAL_MODULE_SUFFIX:=$(suffix $(7))
LOCAL_PRIVILEGED_MODULE:=$(8)
-LOCAL_PROPRIETARY_MODULE:=$(9)
+LOCAL_VENDOR_MODULE:=$(9)
LOCAL_MODULE_TARGET_ARCH:=$(10)
LOCAL_REPLACE_PREBUILT_APK_INSTALLED:=$(11)
LOCAL_CERTIFICATE:=PRESIGNED
@@ -72,7 +72,7 @@
$(PDK.DEXPREOPT.$(a).DEX_PREOPT_FLAGS),\
package.apk,\
$(PDK.DEXPREOPT.$(a).PRIVILEGED_MODULE),\
- $(PDK.DEXPREOPT.$(a).PROPRIETARY_MODULE),\
+ $(PDK.DEXPREOPT.$(a).VENDOR_MODULE),\
$(PDK.DEXPREOPT.$(a).TARGET_ARCH),\
$(_pdk_fusion_intermediates)/$(PDK.DEXPREOPT.$(a).STRIPPED_SRC),\
)))
diff --git a/core/phony_package.mk b/core/phony_package.mk
index 866b13c..578d629 100644
--- a/core/phony_package.mk
+++ b/core/phony_package.mk
@@ -1,3 +1,4 @@
+$(call record-module-type,PHONY_PACKAGE)
ifneq ($(strip $(LOCAL_SRC_FILES)),)
$(error LOCAL_SRC_FILES are not allowed for phony packages)
endif
@@ -7,7 +8,7 @@
include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): $(LOCAL_MODULE_MAKEFILE_DEP) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
$(hide) echo "Fake: $@"
$(hide) mkdir -p $(dir $@)
$(hide) touch $@
diff --git a/core/post_clean.mk b/core/post_clean.mk
deleted file mode 100644
index f08abff..0000000
--- a/core/post_clean.mk
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# 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.
-
-# Clean steps that need global knowledge of individual modules.
-# This file must be included after all Android.mks have been loaded.
-
-#######################################################
-# Checks the current build configurations against the previous build,
-# clean artifacts in TARGET_COMMON_OUT_ROOT if necessary.
-# If a package's resource overlay has been changed, its R class needs to be
-# regenerated.
-previous_package_overlay_config := $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/previous_overlays.txt
-current_package_overlay_config := $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/current_overlays.txt
-current_all_packages_config := $(dir $(current_package_overlay_config))current_packages.txt
-
-$(shell rm -rf $(current_package_overlay_config) \
- && mkdir -p $(dir $(current_package_overlay_config)) \
- && touch $(current_package_overlay_config))
-$(shell echo '$(PACKAGES)' > $(current_all_packages_config))
-$(foreach p, $(PACKAGES), $(if $(PACKAGES.$(p).RESOURCE_OVERLAYS), \
- $(shell echo '$(p)' '$(PACKAGES.$(p).RESOURCE_OVERLAYS)' >> $(current_package_overlay_config))))
-
-ifneq (,$(wildcard $(previous_package_overlay_config)))
-packages_overlay_changed := $(shell build/tools/diff_package_overlays.py \
- $(current_all_packages_config) $(current_package_overlay_config) \
- $(previous_package_overlay_config))
-ifneq (,$(packages_overlay_changed))
-overlay_cleanup_cmd := $(strip rm -rf $(foreach p, $(packages_overlay_changed),\
- $(TARGET_OUT_COMMON_INTERMEDIATES)/APPS/$(p)_intermediates))
-$(info *** Overlay change detected, clean shared intermediate files...)
-$(info *** $(overlay_cleanup_cmd))
-$(shell $(overlay_cleanup_cmd))
-overlay_cleanup_cmd :=
-endif
-packages_overlay_changed :=
-endif
-
-# Now current becomes previous.
-$(shell mv -f $(current_package_overlay_config) $(previous_package_overlay_config))
-
-previous_package_overlay_config :=
-current_package_overlay_config :=
-current_all_packages_config :=
-
-#######################################################
-# Check if we need to delete obsolete generated java files.
-# When an aidl/proto/etc file gets deleted (or renamed), the generated java file is obsolete.
-previous_gen_java_config := $(TARGET_OUT_COMMON_INTERMEDIATES)/previous_gen_java_config.mk
-current_gen_java_config := $(TARGET_OUT_COMMON_INTERMEDIATES)/current_gen_java_config.mk
-
-$(shell rm -rf $(current_gen_java_config) \
- && mkdir -p $(dir $(current_gen_java_config))\
- && touch $(current_gen_java_config))
--include $(previous_gen_java_config)
-
-intermediates_to_clean :=
-modules_with_gen_java_files :=
-$(foreach p, $(ALL_MODULES), \
- $(eval gs := $(strip $(ALL_MODULES.$(p).AIDL_FILES)\
- $(ALL_MODULES.$(p).PROTO_FILES)\
- $(ALL_MODULES.$(p).RS_FILES)))\
- $(if $(gs),\
- $(eval modules_with_gen_java_files += $(p))\
- $(shell echo 'GEN_SRC_FILES.$(p) := $(gs)' >> $(current_gen_java_config)))\
- $(if $(filter-out $(gs),$(GEN_SRC_FILES.$(p))),\
- $(eval intermediates_to_clean += $(ALL_MODULES.$(p).INTERMEDIATE_SOURCE_DIR))))
-intermediates_to_clean := $(strip $(intermediates_to_clean))
-ifdef intermediates_to_clean
-$(info *** Obsolete generated java files detected, clean intermediate files...)
-$(info *** rm -rf $(intermediates_to_clean))
-$(shell rm -rf $(intermediates_to_clean))
-intermediates_to_clean :=
-endif
-
-# For modules not loaded by the current build (e.g. you are running mm/mmm),
-# we copy the info from the previous bulid.
-$(foreach p, $(filter-out $(ALL_MODULES),$(MODULES_WITH_GEN_JAVA_FILES)),\
- $(shell echo 'GEN_SRC_FILES.$(p) := $(GEN_SRC_FILES.$(p))' >> $(current_gen_java_config)))
-MODULES_WITH_GEN_JAVA_FILES := $(sort $(MODULES_WITH_GEN_JAVA_FILES) $(modules_with_gen_java_files))
-$(shell echo 'MODULES_WITH_GEN_JAVA_FILES := $(MODULES_WITH_GEN_JAVA_FILES)' >> $(current_gen_java_config))
-
-# Now current becomes previous.
-$(shell cmp $(current_gen_java_config) $(previous_gen_java_config) > /dev/null 2>&1 || mv -f $(current_gen_java_config) $(previous_gen_java_config))
-
-MODULES_WITH_GEN_JAVA_FILES :=
-modules_with_gen_java_files :=
-previous_gen_java_config :=
-current_gen_java_config :=
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index 428922b..839e14f 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -5,12 +5,20 @@
## None.
##
###########################################################
+$(call record-module-type,PREBUILT)
ifdef LOCAL_IS_HOST_MODULE
my_prefix := HOST_
LOCAL_HOST_PREFIX :=
else
my_prefix := TARGET_
+
+ ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+ # Only support prebuilt shared and static libraries for translated arch
+ ifeq ($(filter SHARED_LIBRARIES STATIC_LIBRARIES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+ LOCAL_MULTILIB := first
+ endif
+ endif
endif
include $(BUILD_SYSTEM)/multilib.mk
@@ -52,7 +60,7 @@
ifdef LOCAL_IS_HOST_MODULE
ifdef HOST_CROSS_OS
-ifneq (,$(filter EXECUTABLES STATIC_LIBRARIES SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS)))
+ifneq (,$(filter EXECUTABLES STATIC_LIBRARIES SHARED_LIBRARIES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)))
my_prefix := HOST_CROSS_
LOCAL_HOST_PREFIX := $(my_prefix)
include $(BUILD_SYSTEM)/module_arch_supported.mk
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index b6727fa..d2b88fa 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -16,9 +16,6 @@
$(error dont use LOCAL_PREBUILT_JAVA_LIBRARIES anymore LOCAL_PATH=$(LOCAL_PATH))
endif
-# Not much sense to check build prebuilts
-LOCAL_DONT_CHECK_MODULE := true
-
my_32_64_bit_suffix := $(if $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)IS_64_BIT),64,32)
ifdef LOCAL_PREBUILT_MODULE_FILE
@@ -38,6 +35,8 @@
endif
endif
+LOCAL_CHECKED_MODULE := $(my_prebuilt_src_file)
+
my_strip_module := $(firstword \
$(LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
$(LOCAL_STRIP_MODULE))
@@ -46,9 +45,18 @@
$(LOCAL_PACK_MODULE_RELOCATIONS))
ifeq (SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS))
- # Put the built targets of all shared libraries in a common directory
- # to simplify the link line.
- OVERRIDE_BUILT_MODULE_PATH := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)
+ # LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES indicates that this prebuilt should be
+ # installed to the common directory of libraries. This is needed for the NDK
+ # shared libraries built by soong, as we build many different versions of each
+ # library (one for each API level). Since they all have the same basename,
+ # they'd clobber each other (as well as any platform libraries by the same
+ # name).
+ ifneq ($(LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES),false)
+ # Put the built targets of all shared libraries in a common directory
+ # to simplify the link line.
+ OVERRIDE_BUILT_MODULE_PATH := \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)
+ endif
ifeq ($(LOCAL_IS_HOST_MODULE)$(my_strip_module),)
# Strip but not try to add debuglink
my_strip_module := no_debuglink
@@ -70,6 +78,16 @@
prebuilt_module_is_a_library :=
endif
+ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ ifeq ($(prebuilt_module_is_a_library),true)
+ SOONG_ALREADY_CONV := $(SOONG_ALREADY_CONV) $(LOCAL_MODULE)
+ endif
+
+ ifdef LOCAL_USE_VNDK
+ SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(patsubst %.vendor,%,$(LOCAL_MODULE)) := 1
+ endif
+endif
+
# Don't install static libraries by default.
ifndef LOCAL_UNINSTALLABLE_MODULE
ifeq (STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS))
@@ -90,11 +108,11 @@
endif
endif
-ifneq ($(filter true no_debuglink,$(my_strip_module) $(my_pack_module_relocations)),)
+ifneq ($(filter true keep_symbols no_debuglink mini-debug-info,$(my_strip_module) $(my_pack_module_relocations)),)
ifdef LOCAL_IS_HOST_MODULE
$(error Cannot strip/pack host module LOCAL_PATH=$(LOCAL_PATH))
endif
- ifeq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
+ ifeq ($(filter SHARED_LIBRARIES EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
$(error Can strip/pack only shared libraries or executables LOCAL_PATH=$(LOCAL_PATH))
endif
ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
@@ -112,19 +130,38 @@
ifdef prebuilt_module_is_a_library
export_includes := $(intermediates)/export_includes
-$(export_includes): PRIVATE_EXPORT_C_INCLUDE_DIRS := $(LOCAL_EXPORT_C_INCLUDE_DIRS)
-$(export_includes) : $(LOCAL_MODULE_MAKEFILE_DEP)
+export_cflags := $(foreach d,$(LOCAL_EXPORT_C_INCLUDE_DIRS),-I $(d))
+# Soong exports cflags instead of include dirs, so that -isystem can be included.
+ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+export_cflags += $(LOCAL_EXPORT_CFLAGS)
+else ifdef LOCAL_EXPORT_CFLAGS
+$(call pretty-error,LOCAL_EXPORT_CFLAGS can only be used by Soong, use LOCAL_EXPORT_C_INCLUDE_DIRS instead)
+endif
+$(export_includes): PRIVATE_EXPORT_CFLAGS := $(export_cflags)
+$(export_includes): $(LOCAL_EXPORT_C_INCLUDE_DEPS)
@echo Export includes file: $< -- $@
$(hide) mkdir -p $(dir $@) && rm -f $@
-ifdef LOCAL_EXPORT_C_INCLUDE_DIRS
- $(hide) for d in $(PRIVATE_EXPORT_C_INCLUDE_DIRS); do \
- echo "-I $$d" >> $@; \
- done
+ifdef export_cflags
+ $(hide) echo "$(PRIVATE_EXPORT_CFLAGS)" >$@
else
$(hide) touch $@
endif
+export_cflags :=
-$(LOCAL_BUILT_MODULE) : | $(intermediates)/export_includes
+ifdef LOCAL_SDK_VERSION
+my_link_type := native:ndk
+else ifdef LOCAL_USE_VNDK
+my_link_type := native:vendor
+else
+my_link_type := native:platform
+endif
+
+# TODO: check dependencies of prebuilt files
+my_link_deps :=
+
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+my_common :=
+include $(BUILD_SYSTEM)/link_type.mk
endif # prebuilt_module_is_a_library
# The real dependency will be added after all Android.mks are loaded and the install paths
@@ -134,6 +171,14 @@
my_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
# Extra shared libraries introduced by LOCAL_CXX_STL.
include $(BUILD_SYSTEM)/cxx_stl_setup.mk
+ifdef LOCAL_USE_VNDK
+ ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+ my_shared_libraries := $(addsuffix .vendor,$(my_shared_libraries))
+ else
+ my_shared_libraries := $(foreach l,$(my_shared_libraries),\
+ $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+ endif
+endif
$(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
$(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
@@ -151,6 +196,34 @@
# "my_strip_module not true" because otherwise the rules are defined in dynamic_binary.mk.
endif # my_strip_module not true
+ifeq ($(NATIVE_COVERAGE),true)
+ifneq (,$(strip $(LOCAL_PREBUILT_COVERAGE_ARCHIVE)))
+ $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(intermediates)/$(LOCAL_MODULE).gcnodir))
+ 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)/$(basename $(my_installed_module_stem)).gcnodir
+ $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(my_coverage_path)))
+ $(LOCAL_BUILT_MODULE): $(my_coverage_path)
+ endif
+else
+# Coverage information is needed when static lib is a dependency of another
+# coverage-enabled module.
+ifeq (STATIC_LIBRARIES, $(LOCAL_MODULE_CLASS))
+GCNO_ARCHIVE := $(LOCAL_MODULE).gcnodir
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_OBJECTS :=
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_WHOLE_STATIC_LIBRARIES :=
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_PREFIX := $(my_prefix)
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_2ND_ARCH_VAR_PREFIX := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+$(intermediates)/$(GCNO_ARCHIVE) :
+ $(transform-o-to-static-lib)
+endif
+endif
+endif
+
ifeq ($(LOCAL_MODULE_CLASS),APPS)
PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
@@ -200,6 +273,7 @@
LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
PACKAGES.$(LOCAL_MODULE).EXTERNAL_KEY := 1
+ $(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
$(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
$(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
endif
@@ -226,6 +300,7 @@
PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
+ $(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
$(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
$(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
endif
@@ -243,7 +318,7 @@
#######################################
ifneq ($(LOCAL_REPLACE_PREBUILT_APK_INSTALLED),)
# There is a replacement for the prebuilt .apk we can install without any processing.
-$(built_module) : $(LOCAL_REPLACE_PREBUILT_APK_INSTALLED) | $(ACP)
+$(built_module) : $(LOCAL_REPLACE_PREBUILT_APK_INSTALLED)
$(transform-prebuilt-to-target)
else # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
@@ -261,7 +336,7 @@
endif
$(built_module): PRIVATE_EMBEDDED_JNI_LIBS := $(embedded_prebuilt_jni_libs)
-$(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR) $(AAPT)
+$(built_module) : $(my_prebuilt_src_file) | $(ZIPALIGN) $(SIGNAPK_JAR)
$(transform-prebuilt-to-target)
$(uncompress-shared-libs)
ifdef LOCAL_DEX_PREOPT
@@ -295,7 +370,7 @@
## Install split apks.
ifdef LOCAL_PACKAGE_SPLITS
# LOCAL_PACKAGE_SPLITS is a list of apks to be installed.
-built_apk_splits := $(addprefix $(built_module_path)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
+built_apk_splits := $(addprefix $(intermediates)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
installed_apk_splits := $(addprefix $(my_module_path)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
# Rules to sign the split apks.
@@ -305,24 +380,25 @@
endif
my_src_dir := $(LOCAL_PATH)/$(my_src_dir)
+$(built_apk_splits) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
$(built_apk_splits) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
$(built_apk_splits) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
-$(built_apk_splits) : $(built_module_path)/%.apk : $(my_src_dir)/%.apk | $(ACP) $(AAPT)
+$(built_apk_splits) : $(intermediates)/%.apk : $(my_src_dir)/%.apk
$(copy-file-to-new-target)
$(sign-package)
# Rules to install the split apks.
-$(installed_apk_splits) : $(my_module_path)/%.apk : $(built_module_path)/%.apk | $(ACP)
+$(installed_apk_splits) : $(my_module_path)/%.apk : $(intermediates)/%.apk
@echo "Install: $@"
$(copy-file-to-new-target)
# Register the additional built and installed files.
ALL_MODULES.$(my_register_name).INSTALLED += $(installed_apk_splits)
ALL_MODULES.$(my_register_name).BUILT_INSTALLED += \
- $(foreach s,$(LOCAL_PACKAGE_SPLITS),$(built_module_path)/$(notdir $(s)):$(my_module_path)/$(notdir $(s)))
+ $(foreach s,$(LOCAL_PACKAGE_SPLITS),$(intermediates)/$(notdir $(s)):$(my_module_path)/$(notdir $(s)))
# Make sure to install the splits when you run "make <module_name>".
-$(my_register_name): $(installed_apk_splits)
+$(my_all_targets): $(installed_apk_splits)
endif # LOCAL_PACKAGE_SPLITS
@@ -337,7 +413,7 @@
ifneq ($(dexpreopt_boot_jar_module),) # boot jar
# boot jar's rules are defined in dex_preopt.mk
dexpreopted_boot_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module)_nodex.jar
-$(built_module) : $(dexpreopted_boot_jar) | $(ACP)
+$(built_module) : $(dexpreopted_boot_jar)
$(call copy-file-to-target)
# For libart boot jars, we don't have .odex files.
@@ -348,53 +424,72 @@
@echo "Dexpreopt Jar: $(PRIVATE_MODULE) ($@)"
$(call dexpreopt-one-file,$<,$@)
-$(built_module) : $(my_prebuilt_src_file) | $(ACP)
+$(built_module) : $(my_prebuilt_src_file)
$(call copy-file-to-target)
ifneq (nostripping,$(LOCAL_DEX_PREOPT))
$(call dexpreopt-remove-classes.dex,$@)
endif
endif # boot jar
else # ! LOCAL_DEX_PREOPT
-$(built_module) : $(my_prebuilt_src_file) | $(ACP)
+$(built_module) : $(my_prebuilt_src_file)
$(call copy-file-to-target)
endif # LOCAL_DEX_PREOPT
else # ! prebuilt_module_is_dex_javalib
+$(built_module) : $(my_prebuilt_src_file)
ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
-$(built_module) : $(my_prebuilt_src_file)
$(transform-prebuilt-to-target-strip-comments)
-ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
- $(hide) chmod +x $@
-endif
-else ifneq ($(LOCAL_ACP_UNAVAILABLE),true)
-$(built_module) : $(my_prebuilt_src_file) | $(ACP)
- $(transform-prebuilt-to-target)
-ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
- $(hide) chmod +x $@
-endif
else
-$(built_module) : $(my_prebuilt_src_file)
- $(copy-file-to-target-with-cp)
-ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
- $(hide) chmod +x $@
+ $(transform-prebuilt-to-target)
endif
+ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+ $(hide) chmod +x $@
endif
endif # ! prebuilt_module_is_dex_javalib
endif # LOCAL_MODULE_CLASS != APPS
ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
my_src_jar := $(my_prebuilt_src_file)
-ifeq ($(LOCAL_IS_HOST_MODULE),)
+
+ifdef LOCAL_IS_HOST_MODULE
+# for host java libraries deps should be in the common dir, so we make a copy in
+# the common dir.
+common_classes_jar := $(intermediates.COMMON)/classes.jar
+
+$(common_classes_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
+$(common_classes_jar): PRIVATE_PREFIX := $(my_prefix)
+
+$(common_classes_jar) : $(my_src_jar)
+ $(transform-prebuilt-to-target)
+
+else # !LOCAL_IS_HOST_MODULE
# for target java libraries, the LOCAL_BUILT_MODULE is in a product-specific dir,
# while the deps should be in the common dir, so we make a copy in the common dir.
common_classes_jar := $(intermediates.COMMON)/classes.jar
+common_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
common_javalib_jar := $(intermediates.COMMON)/javalib.jar
-$(common_classes_jar) $(common_javalib_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
+$(common_classes_jar) $(common_classes_pre_proguard_jar) $(common_javalib_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
+$(common_classes_jar) $(common_classes_pre_proguard_jar) $(common_javalib_jar): PRIVATE_PREFIX := $(my_prefix)
+
+ifeq ($(LOCAL_SDK_VERSION),system_current)
+my_link_type := java:system
+else ifneq ($(LOCAL_SDK_VERSION),)
+my_link_type := java:sdk
+else
+my_link_type := java:platform
+endif
+
+# TODO: check dependencies of prebuilt files
+my_link_deps :=
+
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+my_common := COMMON
+include $(BUILD_SYSTEM)/link_type.mk
ifeq ($(prebuilt_module_is_dex_javalib),true)
# For prebuilt shared Java library we don't have classes.jar.
-$(common_javalib_jar) : $(my_src_jar) | $(ACP)
+$(common_javalib_jar) : $(my_src_jar)
$(transform-prebuilt-to-target)
else # ! prebuilt_module_is_dex_javalib
@@ -412,10 +507,13 @@
endif
-$(common_classes_jar) : $(my_src_jar) | $(ACP)
+$(common_classes_jar) : $(my_src_jar)
$(transform-prebuilt-to-target)
-$(common_javalib_jar) : $(common_classes_jar) | $(ACP)
+$(common_classes_pre_proguard_jar) : $(my_src_jar)
+ $(transform-prebuilt-to-target)
+
+$(common_javalib_jar) : $(common_classes_jar)
$(transform-prebuilt-to-target)
$(call define-jar-to-toc-rule, $(common_classes_jar))
@@ -457,25 +555,26 @@
endif # LOCAL_IS_HOST_MODULE is not set
ifneq ($(prebuilt_module_is_dex_javalib),true)
-ifneq ($(LOCAL_JILL_FLAGS),)
-$(error LOCAL_JILL_FLAGS is not supported any more, please use jack options in LOCAL_JACK_FLAGS instead)
-endif
+ifdef LOCAL_JACK_ENABLED
# We may be building classes.jack from a host jar for host dalvik Java library.
$(intermediates.COMMON)/classes.jack : PRIVATE_JACK_FLAGS:=$(LOCAL_JACK_FLAGS)
-$(intermediates.COMMON)/classes.jack : PRIVATE_JACK_MIN_SDK_VERSION := 1
-$(intermediates.COMMON)/classes.jack : $(my_src_jar) $(LOCAL_MODULE_MAKEFILE_DEP) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES) $(JACK) | setup-jack-server
+$(intermediates.COMMON)/classes.jack : PRIVATE_JACK_MIN_SDK_VERSION := $(if $(strip $(LOCAL_MIN_SDK_VERSION)),$(LOCAL_MIN_SDK_VERSION),1)
+$(intermediates.COMMON)/classes.jack : PRIVATE_JACK_PLUGIN_PATH := $(LOCAL_JACK_PLUGIN_PATH)
+$(intermediates.COMMON)/classes.jack : PRIVATE_JACK_PLUGIN := $(LOCAL_JACK_PLUGIN)
+$(intermediates.COMMON)/classes.jack : $(LOCAL_JACK_PLUGIN_PATH) $(my_src_jar) \
+ $(LOCAL_ADDITIONAL_DEPENDENCIES) $(JACK_DEFAULT_ARGS) $(JACK) \
+ | setup-jack-server
$(transform-jar-to-jack)
# Update timestamps of .toc files for prebuilts so dependents will be
# always rebuilt.
$(intermediates.COMMON)/classes.dex.toc: $(intermediates.COMMON)/classes.jack
touch $@
-
+endif # LOCAL_JACK_ENABLED
endif # ! prebuilt_module_is_dex_javalib
endif # JAVA_LIBRARIES
-$(built_module) : $(LOCAL_MODULE_MAKEFILE_DEP) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+$(built_module) : $(LOCAL_ADDITIONAL_DEPENDENCIES)
my_prebuilt_src_file :=
diff --git a/core/product.mk b/core/product.mk
index c69e963..7742cc3 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -94,6 +94,7 @@
PRODUCT_EXTRA_RECOVERY_KEYS \
PRODUCT_PACKAGE_OVERLAYS \
DEVICE_PACKAGE_OVERLAYS \
+ PRODUCT_ENFORCE_RRO_TARGETS \
PRODUCT_SDK_ATREE_FILES \
PRODUCT_SDK_ADDON_NAME \
PRODUCT_SDK_ADDON_COPY_FILES \
@@ -111,6 +112,7 @@
PRODUCT_SUPPORTS_VERITY_FEC \
PRODUCT_OEM_PROPERTIES \
PRODUCT_SYSTEM_PROPERTY_BLACKLIST \
+ PRODUCT_SYSTEM_SERVER_APPS \
PRODUCT_SYSTEM_SERVER_JARS \
PRODUCT_VBOOT_SIGNING_KEY \
PRODUCT_VBOOT_SIGNING_SUBKEY \
@@ -124,6 +126,11 @@
PRODUCT_SYSTEM_BASE_FS_PATH \
PRODUCT_VENDOR_BASE_FS_PATH \
PRODUCT_SHIPPING_API_LEVEL \
+ VENDOR_PRODUCT_RESTRICT_VENDOR_FILES \
+ VENDOR_EXCEPTION_MODULES \
+ VENDOR_EXCEPTION_PATHS \
+ PRODUCT_ART_USE_READ_BARRIER \
+ PRODUCT_IOT \
PRODUCT_SYSTEM_HEADROOM \
@@ -286,41 +293,19 @@
_product_stash_var_list += \
DEFAULT_SYSTEM_DEV_CERTIFICATE \
WITH_DEXPREOPT \
- WITH_DEXPREOPT_BOOT_IMG_ONLY
-
-_product_stash_var_list += \
- GLOBAL_CFLAGS_NO_OVERRIDE \
- GLOBAL_CPPFLAGS_NO_OVERRIDE \
- GLOBAL_CLANG_CFLAGS_NO_OVERRIDE \
+ WITH_DEXPREOPT_BOOT_IMG_ONLY \
+ WITH_DEXPREOPT_APP_IMAGE
#
-# Stash values of the variables in _product_stash_var_list.
-# $(1): Renamed prefix
+# Mark the variables in _product_stash_var_list as readonly
#
-define stash-product-vars
+define readonly-product-vars
$(foreach v,$(_product_stash_var_list), \
- $(eval $(strip $(1))_$(call rot13,$(v)):=$$($$(v))) \
+ $(eval $(v) ?=) \
+ $(eval .KATI_READONLY := $(v)) \
)
endef
-#
-# Assert that the the variable stashed by stash-product-vars remains untouched.
-# $(1): The prefix as supplied to stash-product-vars
-#
-define assert-product-vars
-$(strip \
- $(eval changed_variables:=)
- $(foreach v,$(_product_stash_var_list), \
- $(if $(call streq,$($(v)),$($(strip $(1))_$(call rot13,$(v)))),, \
- $(eval $(warning $(v) has been modified: $($(v)))) \
- $(eval $(warning previous value: $($(strip $(1))_$(call rot13,$(v))))) \
- $(eval changed_variables := $(changed_variables) $(v))) \
- ) \
- $(if $(changed_variables),\
- $(eval $(error The following variables have been changed: $(changed_variables))),)
-)
-endef
-
define add-to-product-copy-files-if-exists
$(if $(wildcard $(word 1,$(subst :, ,$(1)))),$(1))
endef
diff --git a/core/product_config.mk b/core/product_config.mk
index 4117332..3623aa6 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -88,6 +88,7 @@
# Provide "PRODUCT-<prodname>-<goal>" targets, which lets you build
# a particular configuration without needing to set up the environment.
#
+ifndef KATI
product_goals := $(strip $(filter PRODUCT-%,$(MAKECMDGOALS)))
ifdef product_goals
# Scrape the product and build names out of the goal,
@@ -113,54 +114,42 @@
$(error "tests" has been deprecated as a build variant. Use it as a build goal instead.)
endif
- # The build server wants to do make PRODUCT-dream-installclean
- # which really means TARGET_PRODUCT=dream make installclean.
+ # The build server wants to do make PRODUCT-dream-sdk
+ # which really means TARGET_PRODUCT=dream make sdk.
ifneq ($(filter-out $(INTERNAL_VALID_VARIANTS),$(TARGET_BUILD_VARIANT)),)
- MAKECMDGOALS := $(MAKECMDGOALS) $(TARGET_BUILD_VARIANT)
+ override MAKECMDGOALS := $(MAKECMDGOALS) $(TARGET_BUILD_VARIANT)
TARGET_BUILD_VARIANT := userdebug
default_goal_substitution :=
else
- default_goal_substitution := $(DEFAULT_GOAL)
+ default_goal_substitution := droid
endif
# Replace the PRODUCT-* goal with the build goal that it refers to.
# Note that this will ensure that it appears in the same relative
# position, in case it matters.
- #
- # Note that modifying this will not affect the goals that make will
- # attempt to build, but it's important because we inspect this value
- # in certain situations (like for "make sdk").
- #
- MAKECMDGOALS := $(patsubst $(goal_name),$(default_goal_substitution),$(MAKECMDGOALS))
-
- # Define a rule for the PRODUCT-* goal, and make it depend on the
- # patched-up command-line goals as well as any other goals that we
- # want to force.
- #
-.PHONY: $(goal_name)
-$(goal_name): $(MAKECMDGOALS)
+ override MAKECMDGOALS := $(patsubst $(goal_name),$(default_goal_substitution),$(MAKECMDGOALS))
endif
+endif # !KATI
# else: Use the value set in the environment or buildspec.mk.
# ---------------------------------------------------------------
# Provide "APP-<appname>" targets, which lets you build
# an unbundled app.
#
+ifndef KATI
unbundled_goals := $(strip $(filter APP-%,$(MAKECMDGOALS)))
ifdef unbundled_goals
ifneq ($(words $(unbundled_goals)),1)
$(error Only one APP-* goal may be specified; saw "$(unbundled_goals)")
endif
TARGET_BUILD_APPS := $(strip $(subst -, ,$(patsubst APP-%,%,$(unbundled_goals))))
- ifneq ($(filter $(DEFAULT_GOAL),$(MAKECMDGOALS)),)
- MAKECMDGOALS := $(patsubst $(unbundled_goals),,$(MAKECMDGOALS))
+ ifneq ($(filter droid,$(MAKECMDGOALS)),)
+ override MAKECMDGOALS := $(patsubst $(unbundled_goals),,$(MAKECMDGOALS))
else
- MAKECMDGOALS := $(patsubst $(unbundled_goals),$(DEFAULT_GOAL),$(MAKECMDGOALS))
+ override MAKECMDGOALS := $(patsubst $(unbundled_goals),droid,$(MAKECMDGOALS))
endif
-
-.PHONY: $(unbundled_goals)
-$(unbundled_goals): $(MAKECMDGOALS)
endif # unbundled_goals
+endif
# Default to building dalvikvm on hosts that support it...
ifeq ($(HOST_OS),linux)
@@ -189,6 +178,8 @@
all_product_configs := $(get-all-product-makefiles)
endif
+all_named_products :=
+
# Find the product config makefile for the current product.
# all_product_configs consists items like:
# <product_name>:<path_to_the_product_makefile>
@@ -202,9 +193,11 @@
$(eval _cpm_word2 := $(word 2,$(_cpm_words)))\
$(if $(_cpm_word2),\
$(eval all_product_makefiles += $(_cpm_word2))\
+ $(eval all_named_products += $(_cpm_word1))\
$(if $(filter $(TARGET_PRODUCT),$(_cpm_word1)),\
$(eval current_product_makefile += $(_cpm_word2)),),\
$(eval all_product_makefiles += $(f))\
+ $(eval all_named_products += $(basename $(notdir $(f))))\
$(if $(filter $(TARGET_PRODUCT),$(basename $(notdir $(f)))),\
$(eval current_product_makefile += $(f)),)))
_cpm_words :=
@@ -264,6 +257,7 @@
# A list of module names of BOOTCLASSPATH (jar files)
PRODUCT_BOOT_JARS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_BOOT_JARS))
PRODUCT_SYSTEM_SERVER_JARS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_SERVER_JARS))
+PRODUCT_SYSTEM_SERVER_APPS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_SERVER_APPS))
# Find the device that this product maps to.
TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
@@ -319,9 +313,6 @@
PRODUCT_MANUFACTURER := unknown
endif
-# Add reserved headroom to a system image.
-PRODUCT_SYSTEM_HEADROOM := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM))
-
ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CHARACTERISTICS),)
TARGET_AAPT_CHARACTERISTICS := default
else
@@ -353,18 +344,16 @@
# whitespace characters on either side of the '='.
PRODUCT_PROPERTY_OVERRIDES := \
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PROPERTY_OVERRIDES))
+.KATI_READONLY := PRODUCT_PROPERTY_OVERRIDES
PRODUCT_SHIPPING_API_LEVEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SHIPPING_API_LEVEL))
-ifdef PRODUCT_SHIPPING_API_LEVEL
-ADDITIONAL_BUILD_PROPERTIES += \
- ro.product.first_api_level=$(PRODUCT_SHIPPING_API_LEVEL)
-endif
# A list of property assignments, like "key = value", with zero or more
# whitespace characters on either side of the '='.
# used for adding properties to default.prop
PRODUCT_DEFAULT_PROPERTY_OVERRIDES := \
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
+.KATI_READONLY := PRODUCT_DEFAULT_PROPERTY_OVERRIDES
# Should we use the default resources or add any product specific overlays
PRODUCT_PACKAGE_OVERLAYS := \
@@ -376,11 +365,6 @@
PRODUCT_VENDOR_KERNEL_HEADERS := \
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_KERNEL_HEADERS)
-# Add the product-defined properties to the build properties.
-ADDITIONAL_BUILD_PROPERTIES := \
- $(ADDITIONAL_BUILD_PROPERTIES) \
- $(PRODUCT_PROPERTY_OVERRIDES)
-
# The OTA key(s) specified by the product config, if any. The names
# of these keys are stored in the target-files zip so that post-build
# signing tools can substitute them for the test key embedded by
@@ -422,3 +406,19 @@
$(eval cf := $(subst $(_PSMC_SP_PLACE_HOLDER),$(space),$(cf)))\
$(eval SANITIZER.$(TARGET_PRODUCT).$(m).CONFIG := $(cf))))
_psmc_modules :=
+
+# Make this art variable visible to soong_config.mk.
+PRODUCT_ART_USE_READ_BARRIER := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ART_USE_READ_BARRIER))
+
+# Whether the product is an Android Things variant.
+PRODUCT_IOT := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_IOT))
+
+# Package list to apply enforcing RRO.
+PRODUCT_ENFORCE_RRO_TARGETS := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_RRO_TARGETS))
+
+# Add reserved headroom to a system image.
+PRODUCT_SYSTEM_HEADROOM := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_HEADROOM))
diff --git a/core/setup_one_odex.mk b/core/setup_one_odex.mk
index 36b6817..f0ffe81 100644
--- a/core/setup_one_odex.mk
+++ b/core/setup_one_odex.mk
@@ -34,8 +34,35 @@
my_installed_odex := $(call get-odex-installed-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
+my_built_vdex := $(patsubst %.odex,%.vdex,$(my_built_odex))
+my_installed_vdex := $(patsubst %.odex,%.vdex,$(my_installed_odex))
+my_installed_art := $(patsubst %.odex,%.art,$(my_installed_odex))
+
+ifndef LOCAL_DEX_PREOPT_APP_IMAGE
+# Local override not defined, use the global one.
+ifeq (true,$(WITH_DEX_PREOPT_APP_IMAGE))
+ LOCAL_DEX_PREOPT_APP_IMAGE := true
+endif
+endif
+
+ifeq (true,$(LOCAL_DEX_PREOPT_APP_IMAGE))
+my_built_art := $(patsubst %.odex,%.art,$(my_built_odex))
+$(my_built_odex): PRIVATE_ART_FILE_PREOPT_FLAGS := --app-image-file=$(my_built_art) \
+ --image-format=lz4
+$(eval $(call copy-one-file,$(my_built_art),$(my_installed_art)))
+built_art += $(my_built_art)
+installed_art += $(my_installed_art)
+built_installed_art += $(my_built_art):$(my_installed_art)
+endif
+
$(eval $(call copy-one-file,$(my_built_odex),$(my_installed_odex)))
+$(eval $(call copy-one-file,$(my_built_vdex),$(my_installed_vdex)))
built_odex += $(my_built_odex)
+built_vdex += $(my_built_vdex)
+
installed_odex += $(my_installed_odex)
+installed_vdex += $(my_installed_vdex)
+
built_installed_odex += $(my_built_odex):$(my_installed_odex)
+built_installed_vdex += $(my_built_vdex):$(my_installed_vdex)
diff --git a/core/shared_library.mk b/core/shared_library.mk
index 2f48341..a15b1a6 100644
--- a/core/shared_library.mk
+++ b/core/shared_library.mk
@@ -1,3 +1,4 @@
+$(call record-module-type,SHARED_LIBRARY)
my_prefix := TARGET_
include $(BUILD_SYSTEM)/multilib.mk
diff --git a/core/shared_library_internal.mk b/core/shared_library_internal.mk
index b9a5e3e..687536b 100644
--- a/core/shared_library_internal.mk
+++ b/core/shared_library_internal.mk
@@ -39,33 +39,26 @@
include $(BUILD_SYSTEM)/dynamic_binary.mk
# Define PRIVATE_ variables from global vars
-my_target_global_ld_dirs := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LD_DIRS)
ifeq ($(LOCAL_NO_LIBGCC),true)
my_target_libgcc :=
else
-my_target_libgcc := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCC)
+my_target_libgcc := $(call intermediates-dir-for,STATIC_LIBRARIES,libgcc,,,$(LOCAL_2ND_ARCH_VAR_PREFIX))/libgcc.a
endif
-my_target_libatomic := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBATOMIC)
+my_target_libatomic := $(call intermediates-dir-for,STATIC_LIBRARIES,libatomic,,,$(LOCAL_2ND_ARCH_VAR_PREFIX))/libatomic.a
ifeq ($(LOCAL_NO_CRT),true)
my_target_crtbegin_so_o :=
my_target_crtend_so_o :=
+else ifdef LOCAL_USE_VNDK
+my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.vendor.o
+my_target_crtend_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.vendor.o
else
-my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_SO_O)
-my_target_crtend_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTEND_SO_O)
+my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
+my_target_crtend_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
endif
-ifdef LOCAL_SDK_VERSION
-# Make sure the prebuilt NDK paths are put ahead of the TARGET_GLOBAL_LD_DIRS,
-# so we don't have race condition when the system libraries (such as libc, libstdc++) are also built in the tree.
-my_target_global_ld_dirs := \
- $(addprefix -L, $(patsubst %/,%,$(dir $(my_ndk_stl_shared_lib_fullpath))) \
- $(my_ndk_sysroot_lib)) \
- $(my_target_global_ld_dirs)
-my_target_global_ldflags := $(my_ndk_stl_shared_lib) $(my_target_global_ldflags)
+ifneq ($(LOCAL_SDK_VERSION),)
my_target_crtbegin_so_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_so.o)
my_target_crtend_so_o := $(wildcard $(my_ndk_sysroot_lib)/crtend_so.o)
endif
-$(linked_module): PRIVATE_TARGET_GLOBAL_LD_DIRS := $(my_target_global_ld_dirs)
-$(linked_module): PRIVATE_TARGET_GLOBAL_LDFLAGS := $(my_target_global_ldflags)
$(linked_module): PRIVATE_TARGET_LIBGCC := $(my_target_libgcc)
$(linked_module): PRIVATE_TARGET_LIBATOMIC := $(my_target_libatomic)
$(linked_module): PRIVATE_TARGET_CRTBEGIN_SO_O := $(my_target_crtbegin_so_o)
@@ -76,8 +69,44 @@
$(all_libraries) \
$(my_target_crtbegin_so_o) \
$(my_target_crtend_so_o) \
- $(LOCAL_MODULE_MAKEFILE_DEP) \
+ $(my_target_libgcc) \
+ $(my_target_libatomic) \
$(LOCAL_ADDITIONAL_DEPENDENCIES)
$(transform-o-to-shared-lib)
+ifeq ($(my_native_coverage),true)
+gcno_suffix := .gcnodir
+
+built_whole_gcno_libraries := \
+ $(foreach lib,$(my_whole_static_libraries), \
+ $(call intermediates-dir-for, \
+ STATIC_LIBRARIES,$(lib),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX), \
+ $(my_host_cross))/$(lib)$(gcno_suffix))
+
+built_static_gcno_libraries := \
+ $(foreach lib,$(my_static_libraries), \
+ $(call intermediates-dir-for, \
+ STATIC_LIBRARIES,$(lib),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX), \
+ $(my_host_cross))/$(lib)$(gcno_suffix))
+
+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
+
+GCNO_ARCHIVE := $(basename $(my_installed_module_stem))$(gcno_suffix)
+
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_OBJECTS := $(strip $(LOCAL_GCNO_FILES))
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_WHOLE_STATIC_LIBRARIES := $(strip $(built_whole_gcno_libraries)) $(strip $(built_static_gcno_libraries))
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_INTERMEDIATES_DIR := $(intermediates)
+$(intermediates)/$(GCNO_ARCHIVE) : $(LOCAL_GCNO_FILES) $(built_whole_gcno_libraries) $(built_static_gcno_libraries)
+ $(transform-o-to-static-lib)
+
+$(my_coverage_path)/$(GCNO_ARCHIVE) : $(intermediates)/$(GCNO_ARCHIVE)
+ $(copy-file-to-target)
+
+$(LOCAL_BUILT_MODULE): $(my_coverage_path)/$(GCNO_ARCHIVE)
+endif
+
endif # skip_build_from_source
diff --git a/core/shared_test_lib.mk b/core/shared_test_lib.mk
index fbfdc9c..1ea9fe7 100644
--- a/core/shared_test_lib.mk
+++ b/core/shared_test_lib.mk
@@ -1,8 +1 @@
-#############################################
-## A thin wrapper around BUILD_SHARED_LIBRARY
-## Common flags for native tests are added.
-#############################################
-
-include $(BUILD_SYSTEM)/target_test_internal.mk
-
-include $(BUILD_SHARED_LIBRARY)
+$(error BUILD_SHARED_TEST_LIBRARY is obsolete)
diff --git a/core/soong.mk b/core/soong.mk
deleted file mode 100644
index 2463953..0000000
--- a/core/soong.mk
+++ /dev/null
@@ -1,80 +0,0 @@
-SOONG_OUT_DIR := $(OUT_DIR)/soong
-SOONG_HOST_EXECUTABLES := $(SOONG_OUT_DIR)/host/$(HOST_PREBUILT_TAG)/bin
-KATI := $(SOONG_HOST_EXECUTABLES)/ckati
-MAKEPARALLEL := $(SOONG_HOST_EXECUTABLES)/makeparallel
-
-SOONG := $(SOONG_OUT_DIR)/soong
-SOONG_BOOTSTRAP := $(SOONG_OUT_DIR)/.soong.bootstrap
-SOONG_BUILD_NINJA := $(SOONG_OUT_DIR)/build.ninja
-SOONG_ANDROID_MK := $(SOONG_OUT_DIR)/Android.mk
-SOONG_IN_MAKE := $(SOONG_OUT_DIR)/.soong.in_make
-SOONG_VARIABLES := $(SOONG_OUT_DIR)/soong.variables
-
-# We need to rebootstrap soong if SOONG_OUT_DIR or the reverse path from
-# SOONG_OUT_DIR to TOP changes
-SOONG_NEEDS_REBOOTSTRAP :=
-ifneq ($(wildcard $(SOONG_BOOTSTRAP)),)
- ifneq ($(SOONG_OUT_DIR),$(strip $(shell source $(SOONG_BOOTSTRAP); echo $$BUILDDIR)))
- SOONG_NEEDS_REBOOTSTRAP := FORCE
- $(warning soong_out_dir changed)
- endif
- ifneq ($(strip $(shell build/soong/reverse_path.py $(SOONG_OUT_DIR))),$(strip $(shell source $(SOONG_BOOTSTRAP); echo $$SRCDIR_FROM_BUILDDIR)))
- SOONG_NEEDS_REBOOTSTRAP := FORCE
- $(warning reverse path changed)
- endif
-endif
-
-# Bootstrap soong.
-$(SOONG_BOOTSTRAP): bootstrap.bash $(SOONG_NEEDS_REBOOTSTRAP)
- $(hide) mkdir -p $(dir $@)
- $(hide) BUILDDIR=$(SOONG_OUT_DIR) ./bootstrap.bash
-
-# Create soong.variables with copies of makefile settings. Runs every build,
-# but only updates soong.variables if it changes
-SOONG_VARIABLES_TMP := $(SOONG_VARIABLES).$$$$
-$(SOONG_VARIABLES): FORCE
- $(hide) mkdir -p $(dir $@)
- $(hide) (\
- echo '{'; \
- echo ' "Device_uses_jemalloc": $(if $(filter true,$(MALLOC_SVELTE)),false,true),'; \
- echo ' "Device_uses_dlmalloc": $(if $(filter true,$(MALLOC_SVELTE)),true,false),'; \
- echo ' "Platform_sdk_version": $(PLATFORM_SDK_VERSION),'; \
- echo ' "Unbundled_build": $(if $(TARGET_BUILD_APPS),true,false),'; \
- echo ' "Brillo": $(if $(BRILLO),true,false),'; \
- echo ''; \
- echo ' "DeviceName": "$(TARGET_DEVICE)",'; \
- echo ' "DeviceArch": "$(TARGET_ARCH)",'; \
- echo ' "DeviceArchVariant": "$(TARGET_ARCH_VARIANT)",'; \
- echo ' "DeviceCpuVariant": "$(TARGET_CPU_VARIANT)",'; \
- echo ' "DeviceAbi": ["$(TARGET_CPU_ABI)", "$(TARGET_CPU_ABI2)"],'; \
- echo ' "DeviceUsesClang": $(if $(USE_CLANG_PLATFORM_BUILD),$(USE_CLANG_PLATFORM_BUILD),false),'; \
- echo ''; \
- echo ' "DeviceSecondaryArch": "$(TARGET_2ND_ARCH)",'; \
- echo ' "DeviceSecondaryArchVariant": "$(TARGET_2ND_ARCH_VARIANT)",'; \
- echo ' "DeviceSecondaryCpuVariant": "$(TARGET_2ND_CPU_VARIANT)",'; \
- echo ' "DeviceSecondaryAbi": ["$(TARGET_2ND_CPU_ABI)", "$(TARGET_2ND_CPU_ABI2)"],'; \
- echo ''; \
- echo ' "HostArch": "$(HOST_ARCH)",'; \
- echo ' "HostSecondaryArch": "$(HOST_2ND_ARCH)",'; \
- echo ''; \
- echo ' "CrossHost": "$(HOST_CROSS_OS)",'; \
- echo ' "CrossHostArch": "$(HOST_CROSS_ARCH)",'; \
- echo ' "CrossHostSecondaryArch": "$(HOST_CROSS_2ND_ARCH)"'; \
- echo '}') > $(SOONG_VARIABLES_TMP); \
- if ! cmp -s $(SOONG_VARIABLES_TMP) $(SOONG_VARIABLES); then \
- mv $(SOONG_VARIABLES_TMP) $(SOONG_VARIABLES); \
- else \
- rm $(SOONG_VARIABLES_TMP); \
- fi
-
-# Tell soong that it is embedded in make
-$(SOONG_IN_MAKE):
- $(hide) mkdir -p $(dir $@)
- $(hide) touch $@
-
-# Build an Android.mk listing all soong outputs as prebuilts
-$(SOONG_ANDROID_MK): $(SOONG_BOOTSTRAP) $(SOONG_VARIABLES) $(SOONG_IN_MAKE) FORCE
- $(hide) $(SOONG) $(KATI) $(MAKEPARALLEL) $(NINJA_ARGS)
-
-$(KATI): $(SOONG_ANDROID_MK)
-$(MAKEPARALLEL): $(SOONG_ANDROID_MK)
diff --git a/core/soong_config.mk b/core/soong_config.mk
new file mode 100644
index 0000000..e21083d
--- /dev/null
+++ b/core/soong_config.mk
@@ -0,0 +1,94 @@
+SOONG := $(SOONG_OUT_DIR)/soong
+SOONG_BOOTSTRAP := $(SOONG_OUT_DIR)/.soong.bootstrap
+SOONG_BUILD_NINJA := $(SOONG_OUT_DIR)/build.ninja
+SOONG_IN_MAKE := $(SOONG_OUT_DIR)/.soong.in_make
+SOONG_MAKEVARS_MK := $(SOONG_OUT_DIR)/make_vars-$(TARGET_PRODUCT).mk
+SOONG_VARIABLES := $(SOONG_OUT_DIR)/soong.variables
+SOONG_ANDROID_MK := $(SOONG_OUT_DIR)/Android-$(TARGET_PRODUCT).mk
+
+BINDER32BIT :=
+ifneq ($(TARGET_USES_64_BIT_BINDER),true)
+ifneq ($(TARGET_IS_64_BIT),true)
+BINDER32BIT := true
+endif
+endif
+
+# Converts a list to a JSON list.
+# $1: List separator.
+# $2: List.
+_json_list = [$(if $(2),"$(subst $(1),"$(comma)",$(2))")]
+
+# Converts a space-separated list to a JSON list.
+json_list = $(call _json_list,$(space),$(1))
+
+# Converts a comma-separated list to a JSON list.
+csv_to_json_list = $(call _json_list,$(comma),$(1))
+
+# Create soong.variables with copies of makefile settings. Runs every build,
+# but only updates soong.variables if it changes
+SOONG_VARIABLES_TMP := $(SOONG_VARIABLES).$$$$
+$(SOONG_VARIABLES): FORCE
+ $(hide) mkdir -p $(dir $@)
+ $(hide) (\
+ echo '{'; \
+ echo ' "Make_suffix": "-$(TARGET_PRODUCT)",'; \
+ echo ''; \
+ echo ' "Platform_sdk_version": $(PLATFORM_SDK_VERSION),'; \
+ echo ' "Platform_version_all_codenames": $(call csv_to_json_list,$(PLATFORM_VERSION_ALL_CODENAMES)),'; \
+ echo ' "Unbundled_build": $(if $(TARGET_BUILD_APPS),true,false),'; \
+ echo ' "Brillo": $(if $(BRILLO),true,false),'; \
+ echo ' "Malloc_not_svelte": $(if $(filter true,$(MALLOC_SVELTE)),false,true),'; \
+ echo ' "Allow_missing_dependencies": $(if $(ALLOW_MISSING_DEPENDENCIES),true,false),'; \
+ echo ' "SanitizeHost": $(call json_list,$(SANITIZE_HOST)),'; \
+ echo ' "SanitizeDevice": $(call json_list,$(SANITIZE_TARGET)),'; \
+ echo ' "SanitizeDeviceArch": $(call json_list,$(SANITIZE_TARGET_ARCH)),'; \
+ echo ' "HostStaticBinaries": $(if $(strip $(BUILD_HOST_static)),true,false),'; \
+ echo ' "Binder32bit": $(if $(BINDER32BIT),true,false),'; \
+ echo ' "DevicePrefer32BitExecutables": $(if $(filter true,$(TARGET_PREFER_32_BIT_EXECUTABLES)),true,false),'; \
+ echo ' "UseGoma": $(if $(filter-out false,$(USE_GOMA)),true,false),'; \
+ echo ' "Debuggable": $(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),true,false),'; \
+ echo ' "Eng": $(if $(filter eng,$(TARGET_BUILD_VARIANT)),true,false),'; \
+ echo ' "VendorPath": "$(TARGET_COPY_OUT_VENDOR)",'; \
+ echo ''; \
+ echo ' "ClangTidy": $(if $(filter 1 true,$(WITH_TIDY)),true,false),'; \
+ echo ' "TidyChecks": "$(WITH_TIDY_CHECKS)",'; \
+ echo ''; \
+ echo ' "NativeCoverage": $(if $(filter true,$(NATIVE_COVERAGE)),true,false),'; \
+ echo ' "CoveragePaths": $(call csv_to_json_list,$(COVERAGE_PATHS)),'; \
+ echo ' "CoverageExcludePaths": $(call csv_to_json_list,$(COVERAGE_EXCLUDE_PATHS)),'; \
+ echo ''; \
+ echo ' "DeviceName": "$(TARGET_DEVICE)",'; \
+ echo ' "DeviceArch": "$(TARGET_ARCH)",'; \
+ echo ' "DeviceArchVariant": "$(TARGET_ARCH_VARIANT)",'; \
+ echo ' "DeviceCpuVariant": "$(TARGET_CPU_VARIANT)",'; \
+ echo ' "DeviceAbi": ["$(TARGET_CPU_ABI)", "$(TARGET_CPU_ABI2)"],'; \
+ echo ' "DeviceUsesClang": $(if $(USE_CLANG_PLATFORM_BUILD),$(USE_CLANG_PLATFORM_BUILD),false),'; \
+ echo ' "DeviceVndkVersion": "$(BOARD_VNDK_VERSION)",'; \
+ echo ''; \
+ echo ' "DeviceSecondaryArch": "$(TARGET_2ND_ARCH)",'; \
+ echo ' "DeviceSecondaryArchVariant": "$(TARGET_2ND_ARCH_VARIANT)",'; \
+ echo ' "DeviceSecondaryCpuVariant": "$(TARGET_2ND_CPU_VARIANT)",'; \
+ echo ' "DeviceSecondaryAbi": ["$(TARGET_2ND_CPU_ABI)", "$(TARGET_2ND_CPU_ABI2)"],'; \
+ echo ''; \
+ echo ' "HostArch": "$(HOST_ARCH)",'; \
+ echo ' "HostSecondaryArch": "$(HOST_2ND_ARCH)",'; \
+ echo ''; \
+ echo ' "CrossHost": "$(HOST_CROSS_OS)",'; \
+ echo ' "CrossHostArch": "$(HOST_CROSS_ARCH)",'; \
+ echo ' "CrossHostSecondaryArch": "$(HOST_CROSS_2ND_ARCH)",'; \
+ echo ' "Safestack": $(if $(filter true,$(USE_SAFESTACK)),true,false),'; \
+ echo ' "EnableCFI": $(if $(filter false,$(ENABLE_CFI)),false,true),'; \
+ echo ' "Device_uses_hwc2": $(if $(filter true,$(TARGET_USES_HWC2)),true,false),'; \
+ echo ' "Override_rs_driver": "$(OVERRIDE_RS_DRIVER)",'; \
+ echo ' "Treble": $(if $(filter true,$(PRODUCT_FULL_TREBLE)),true,false),'; \
+ echo ' "Pdk": $(if $(filter true,$(TARGET_BUILD_PDK)),true,false),'; \
+ echo ''; \
+ echo ' "ArtUseReadBarrier": $(if $(filter false,$(PRODUCT_ART_USE_READ_BARRIER)),false,true),'; \
+ echo ''; \
+ echo ' "BtConfigIncludeDir": "$(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR)"'; \
+ echo '}') > $(SOONG_VARIABLES_TMP); \
+ if ! cmp -s $(SOONG_VARIABLES_TMP) $(SOONG_VARIABLES); then \
+ mv $(SOONG_VARIABLES_TMP) $(SOONG_VARIABLES); \
+ else \
+ rm $(SOONG_VARIABLES_TMP); \
+ fi
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 1279878..343b949 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -19,6 +19,7 @@
# classpaths. They can, however, be included wholesale in
# other java modules.
+$(call record-module-type,STATIC_JAVA_LIBRARY)
LOCAL_UNINSTALLABLE_MODULE := true
LOCAL_IS_STATIC_JAVA_LIBRARY := true
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
@@ -38,6 +39,7 @@
# A static Java library needs to explicily set LOCAL_RESOURCE_DIR.
ifdef LOCAL_RESOURCE_DIR
need_compile_res := true
+LOCAL_RESOURCE_DIR := $(foreach d,$(LOCAL_RESOURCE_DIR),$(call clean-path,$(d)))
endif
ifdef LOCAL_USE_AAPT2
ifneq ($(LOCAL_STATIC_ANDROID_LIBRARIES),)
@@ -140,12 +142,6 @@
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_RESOURCE_DIR := $(LOCAL_RESOURCE_DIR)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
-ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_DEFAULT_APP_TARGET_SDK := $(LOCAL_SDK_VERSION)
-else
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
-endif
-
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASSET_DIR :=
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_PROGUARD_OPTIONS_FILE := $(proguard_options_file)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_PACKAGE_NAME :=
@@ -154,8 +150,23 @@
ifdef LOCAL_USE_AAPT2
# One more level with name res so we can zip up the flat resources that can be linked by apps.
my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res/res
+renderscript_target_api :=
+ifneq (,$(LOCAL_RENDERSCRIPT_TARGET_API))
+renderscript_target_api := $(LOCAL_RENDERSCRIPT_TARGET_API)
+else
+ifneq (,$(LOCAL_SDK_VERSION))
+# Set target-api for LOCAL_SDK_VERSIONs other than current.
+ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+renderscript_target_api := $(LOCAL_SDK_VERSION)
+endif
+endif # LOCAL_SDK_VERSION is set
+endif # LOCAL_RENDERSCRIPT_TARGET_API is set
+ifneq (,$(renderscript_target_api))
+ifneq ($(call math_gt_or_eq,$(renderscript_target_api),21),true)
my_generated_res_dirs := $(rs_generated_res_dir)
my_generated_res_dirs_deps := $(RenderScript_file_stamp)
+endif # renderscript_target_api < 21
+endif # renderscript_target_api is set
include $(BUILD_SYSTEM)/aapt2.mk
$(my_res_package) : $(framework_res_package_export_deps)
else
diff --git a/core/static_library.mk b/core/static_library.mk
index a8ae399..25e5279 100644
--- a/core/static_library.mk
+++ b/core/static_library.mk
@@ -1,3 +1,4 @@
+$(call record-module-type,STATIC_LIBRARY)
my_prefix := TARGET_
include $(BUILD_SYSTEM)/multilib.mk
diff --git a/core/static_library_internal.mk b/core/static_library_internal.mk
index cabe823..6b4d22f 100644
--- a/core/static_library_internal.mk
+++ b/core/static_library_internal.mk
@@ -20,14 +20,26 @@
include $(BUILD_SYSTEM)/binary.mk
-ifeq ($(LOCAL_RAW_STATIC_LIBRARY),true)
-LOCAL_RAW_STATIC_LIBRARY:=
-$(all_objects) : PRIVATE_TARGET_PROJECT_INCLUDES :=
-$(all_objects) : PRIVATE_TARGET_C_INCLUDES :=
-$(all_objects) : PRIVATE_TARGET_GLOBAL_CFLAGS :=
-$(all_objects) : PRIVATE_TARGET_GLOBAL_CPPFLAGS :=
-endif
-
$(LOCAL_BUILT_MODULE) : $(built_whole_libraries)
$(LOCAL_BUILT_MODULE) : $(all_objects)
$(transform-o-to-static-lib)
+
+ifeq ($(NATIVE_COVERAGE),true)
+gcno_suffix := .gcnodir
+
+built_whole_gcno_libraries := \
+ $(foreach lib,$(my_whole_static_libraries), \
+ $(call intermediates-dir-for, \
+ STATIC_LIBRARIES,$(lib),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX), \
+ $(my_host_cross))/$(lib)$(gcno_suffix))
+
+GCNO_ARCHIVE := $(LOCAL_MODULE)$(gcno_suffix)
+
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_OBJECTS := $(strip $(LOCAL_GCNO_FILES))
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_WHOLE_STATIC_LIBRARIES := $(strip $(built_whole_gcno_libraries))
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_PREFIX := $(my_prefix)
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_2ND_ARCH_VAR_PREFIX := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_INTERMEDIATES_DIR := $(intermediates)
+$(intermediates)/$(GCNO_ARCHIVE) : $(LOCAL_GCNO_FILES) $(built_whole_gcno_libraries)
+ $(transform-o-to-static-lib)
+endif
diff --git a/core/static_test_lib.mk b/core/static_test_lib.mk
index 9d0bcc8..a0e2970 100644
--- a/core/static_test_lib.mk
+++ b/core/static_test_lib.mk
@@ -2,6 +2,7 @@
## A thin wrapper around BUILD_STATIC_LIBRARY
## Common flags for native tests are added.
#############################################
+$(call record-module-type,STATIC_TEST_LIBRARY)
include $(BUILD_SYSTEM)/target_test_internal.mk
diff --git a/core/target_test_internal.mk b/core/target_test_internal.mk
index 4715fe8..59a3a9e 100644
--- a/core/target_test_internal.mk
+++ b/core/target_test_internal.mk
@@ -2,14 +2,25 @@
## Shared definitions for all target test compilations.
#######################################################
-LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING
+ifeq ($(LOCAL_GTEST),true)
+ LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING
-LOCAL_C_INCLUDES += external/gtest/include
-
-ifndef LOCAL_SDK_VERSION
-LOCAL_STATIC_LIBRARIES += libgtest_main libgtest
-else
-LOCAL_STATIC_LIBRARIES += libgtest_main_ndk libgtest_ndk
+ ifndef LOCAL_SDK_VERSION
+ LOCAL_STATIC_LIBRARIES += libgtest_main libgtest
+ else
+ ifneq (,$(filter c++_%,$(LOCAL_NDK_STL_VARIANT)))
+ my_ndk_gtest_suffix := _c++
+ else ifneq ($(filter stlport_,$(LOCAL_NDK_STL_VARIANT)),)
+ my_ndk_gtest_suffix := _stlport
+ else ifneq ($(filter gnustl_,$(LOCAL_NDK_STL_VARIANT)),)
+ my_ndk_gtest_suffix := _gnustl
+ else # system STL, use stlport
+ my_ndk_gtest_suffix := _stlport
+ endif
+ LOCAL_STATIC_LIBRARIES += \
+ libgtest_main_ndk$(my_ndk_gtest_suffix) \
+ libgtest_ndk$(my_ndk_gtest_suffix)
+ endif
endif
ifdef LOCAL_MODULE_PATH
@@ -24,5 +35,6 @@
$(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH_64 when building test $(LOCAL_MODULE))
endif
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
-LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
+ifndef LOCAL_MODULE_RELATIVE_PATH
+LOCAL_MODULE_RELATIVE_PATH := $(LOCAL_MODULE)
+endif
diff --git a/core/tasks/build_custom_images.mk b/core/tasks/build_custom_images.mk
index 8ebf89b..0750217 100644
--- a/core/tasks/build_custom_images.mk
+++ b/core/tasks/build_custom_images.mk
@@ -37,6 +37,14 @@
# - CUSTOM_IMAGE_SELINUX, set to "true" if the image supports selinux.
# - CUSTOM_IMAGE_SUPPORT_VERITY, set to "true" if the product supports verity.
# - CUSTOM_IMAGE_VERITY_BLOCK_DEVICE
+# - CUSTOM_IMAGE_AVB_HASH_ENABLE, set to "true" to add AVB HASH footer.
+# - CUSTOM_IMAGE_AVB_ADD_HASH_FOOTER_ARGS, additional args of AVB HASH footer.
+# - CUSTOM_IMAGE_AVB_HASHTREE_ENABLE, set to "true" to add AVB HASHTREE
+# footer.
+# - CUSTOM_IMAGE_AVB_ADD_HASHTREE_FOOTER_ARGS, additional args of AVB
+# HASHTREE footer.
+# - CUSTOM_IMAGE_AVB_KEY_PATH, custom AVB signing key.
+# - CUSTOM_IMAGE_AVB_ALGORITHM, custom AVB signing algorithm.
#
# To build all those images, run "make custom_images".
@@ -54,6 +62,12 @@
CUSTOM_IMAGE_SELINUX \
CUSTOM_IMAGE_SUPPORT_VERITY \
CUSTOM_IMAGE_VERITY_BLOCK_DEVICE \
+ CUSTOM_IMAGE_AVB_HASH_ENABLE \
+ CUSTOM_IMAGE_AVB_ADD_HASH_FOOTER_ARGS \
+ CUSTOM_IMAGE_AVB_HASHTREE_ENABLE \
+ CUSTOM_IMAGE_AVB_ADD_HASHTREE_FOOTER_ARGS \
+ CUSTOM_IMAGE_AVB_KEY_PATH \
+ CUSTOM_IMAGE_AVB_ALGORITHM \
# We don't expect product makefile to inherit/override PRODUCT_CUSTOM_IMAGE_MAKEFILES,
# so we don't put it in the _product_var_list.
diff --git a/core/tasks/check_boot_jars/package_whitelist.txt b/core/tasks/check_boot_jars/package_whitelist.txt
index 3cb6e28..1889117 100644
--- a/core/tasks/check_boot_jars/package_whitelist.txt
+++ b/core/tasks/check_boot_jars/package_whitelist.txt
@@ -8,6 +8,7 @@
java\.io
java\.lang
java\.lang\.annotation
+java\.lang\.invoke
java\.lang\.ref
java\.lang\.reflect
java\.math
@@ -28,6 +29,11 @@
java\.sql
java\.text
java\.text\.spi
+java\.time
+java\.time\.chrono
+java\.time\.format
+java\.time\.temporal
+java\.time\.zone
java\.util
java\.util\.concurrent
java\.util\.concurrent\.atomic
@@ -61,10 +67,13 @@
javax\.xml\.transform\.stream
javax\.xml\.validation
javax\.xml\.xpath
+jdk\.net
org\.w3c\.dom
org\.w3c\.dom\.ls
org\.w3c\.dom\.traversal
# OpenJdk internal implementation.
+sun\.invoke\.util
+sun\.invoke\.empty
sun\.misc
sun\.util.*
sun\.text.*
@@ -112,9 +121,11 @@
###################################################
-# core-junit.jar
+# legacy-test.jar
junit\.extensions
junit\.framework
+android\.test
+android\.test\.suitebuilder\.annotation
###################################################
diff --git a/core/tasks/device-tests.mk b/core/tasks/device-tests.mk
new file mode 100644
index 0000000..b1b936a
--- /dev/null
+++ b/core/tasks/device-tests.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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 agrls eed 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.
+
+
+.PHONY: device-tests
+
+device-tests-zip := $(PRODUCT_OUT)/device-tests.zip
+$(device-tests-zip): $(COMPATIBILITY.device-tests.FILES) $(SOONG_ZIP)
+ echo $(sort $(COMPATIBILITY.device-tests.FILES)) > $@.list
+ sed -i -e 's/\s\+/\n/g' $@.list
+ grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
+ grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
+ $(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list
+
+device-tests: $(device-tests-zip)
+$(call dist-for-goals, device-tests, $(device-tests-zip))
+
+tests: device-tests
diff --git a/core/tasks/general-tests.mk b/core/tasks/general-tests.mk
new file mode 100644
index 0000000..763dd51
--- /dev/null
+++ b/core/tasks/general-tests.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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 agrls eed 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.
+
+.PHONY: general-tests
+
+general-tests-zip := $(PRODUCT_OUT)/general-tests.zip
+$(general-tests-zip): $(COMPATIBILITY.general-tests.FILES) $(SOONG_ZIP)
+ echo $(sort $(COMPATIBILITY.general-tests.FILES)) > $@.list
+ sed -i -e 's/\s\+/\n/g' $@.list
+ grep $(HOST_OUT_TESTCASES) $@.list > $@-host.list || true
+ grep $(TARGET_OUT_TESTCASES) $@.list > $@-target.list || true
+ $(hide) $(SOONG_ZIP) -d -o $@ -P host -C $(HOST_OUT) -l $@-host.list -P target -C $(PRODUCT_OUT) -l $@-target.list
+
+general-tests: $(general-tests-zip)
+$(call dist-for-goals, general-tests, $(general-tests-zip))
diff --git a/core/tasks/old-cts.mk b/core/tasks/old-cts.mk
deleted file mode 100644
index 7024638..0000000
--- a/core/tasks/old-cts.mk
+++ /dev/null
@@ -1,399 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# 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.
-
-cts_dir := $(HOST_OUT)/old-cts
-cts_tools_src_dir := cts/tools
-
-cts_name := old-android-cts
-
-JUNIT_HOST_JAR := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
-HOSTTESTLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/hosttestlib.jar
-TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
-CTS_TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/old-cts-tradefed.jar
-CTS_TF_EXEC_PATH ?= $(HOST_OUT_EXECUTABLES)/old-cts-tradefed
-CTS_TF_README_PATH := $(cts_tools_src_dir)/tradefed-host/README
-
-VMTESTSTF_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,vm-tests-tf,HOST)
-VMTESTSTF_JAR := $(VMTESTSTF_INTERMEDIATES)/android.core.vm-tests-tf.jar
-
-# The list of test packages that core-tests (libcore/Android.mk)
-# is split into.
-CTS_CORE_CASE_LIST := \
- android.core.tests.libcore.package.dalvik \
- android.core.tests.libcore.package.com \
- android.core.tests.libcore.package.conscrypt \
- android.core.tests.libcore.package.sun \
- android.core.tests.libcore.package.tests \
- android.core.tests.libcore.package.org \
- android.core.tests.libcore.package.libcore \
- android.core.tests.libcore.package.jsr166 \
- android.core.tests.libcore.package.harmony_annotation \
- android.core.tests.libcore.package.harmony_java_io \
- android.core.tests.libcore.package.harmony_java_lang \
- android.core.tests.libcore.package.harmony_java_math \
- android.core.tests.libcore.package.harmony_java_net \
- android.core.tests.libcore.package.harmony_java_nio \
- android.core.tests.libcore.package.harmony_java_text \
- android.core.tests.libcore.package.harmony_java_util \
- android.core.tests.libcore.package.harmony_javax_security \
- android.core.tests.libcore.package.okhttp \
- android.core.tests.runner
-
-# Additional CTS packages for code under libcore
-CTS_CORE_CASE_LIST += \
- android.core.tests.libcore.package.tzdata
-
-# The list of test packages that apache-harmony-tests (external/apache-harmony/Android.mk)
-# is split into.
-CTS_CORE_CASE_LIST += \
- android.core.tests.libcore.package.harmony_beans \
- android.core.tests.libcore.package.harmony_logging \
- android.core.tests.libcore.package.harmony_prefs \
- android.core.tests.libcore.package.harmony_sql
-
-
-CTS_TEST_JAR_LIST := \
- cts-junit \
- CtsJdwp \
- cts-testng \
- CtsLibcoreOj
-
-# Depend on the full package paths rather than the phony targets to avoid
-# rebuilding the packages every time.
-CTS_CORE_CASES := $(foreach pkg,$(CTS_CORE_CASE_LIST),$(call intermediates-dir-for,APPS,$(pkg))/package.apk)
-CTS_TEST_JAR_FILES := $(foreach c,$(CTS_TEST_JAR_LIST),$(call intermediates-dir-for,JAVA_LIBRARIES,$(c))/javalib.jar)
-
--include cts/OldCtsTestCaseList.mk
-
-# A module may have mutliple installed files (e.g. split apks)
-CTS_CASE_LIST_APKS :=
-$(foreach m, $(CTS_TEST_CASE_LIST),\
- $(foreach fp, $(ALL_MODULES.$(m).BUILT_INSTALLED),\
- $(eval pair := $(subst :,$(space),$(fp)))\
- $(eval CTS_CASE_LIST_APKS += $(CTS_TESTCASES_OUT)/$(notdir $(word 2,$(pair))))))\
-$(foreach m, $(CTS_CORE_CASE_LIST),\
- $(foreach fp, $(ALL_MODULES.$(m).BUILT_INSTALLED),\
- $(eval pair := $(subst :,$(space),$(fp)))\
- $(eval built := $(word 1,$(pair)))\
- $(eval installed := $(CTS_TESTCASES_OUT)/$(notdir $(word 2,$(pair))))\
- $(eval $(call copy-one-file, $(built), $(installed)))\
- $(eval CTS_CASE_LIST_APKS += $(installed))))
-
-CTS_CASE_LIST_JARS :=
-$(foreach m, $(CTS_TEST_JAR_LIST),\
- $(eval CTS_CASE_LIST_JARS += $(CTS_TESTCASES_OUT)/$(m).jar))
-
-CTS_SHARED_LIBS :=
-
-DEFAULT_TEST_PLAN := $(cts_dir)/$(cts_name)/resource/plans
-$(cts_dir)/all_cts_files_stamp: $(CTS_CORE_CASES) $(CTS_TEST_JAR_FILES) $(CTS_TEST_CASES) $(CTS_CASE_LIST_APKS) $(CTS_CASE_LIST_JARS) $(JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(VMTESTSTF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(ADDITIONAL_TF_JARS) $(ACP) $(CTS_SHARED_LIBS)
-
-# Make necessary directory for CTS
- $(hide) mkdir -p $(TMP_DIR)
- $(hide) mkdir -p $(PRIVATE_DIR)/docs
- $(hide) mkdir -p $(PRIVATE_DIR)/tools
- $(hide) mkdir -p $(PRIVATE_DIR)/repository/testcases
- $(hide) mkdir -p $(PRIVATE_DIR)/repository/plans
-# Copy executable and JARs to CTS directory
- $(hide) $(ACP) -fp $(VMTESTSTF_JAR) $(CTS_TESTCASES_OUT)
- $(hide) $(ACP) -fp $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(ADDITIONAL_TF_JARS) $(CTS_TF_README_PATH) $(PRIVATE_DIR)/tools
- $(hide) $(call copy-files-with-structure, $(CTS_SHARED_LIBS),$(HOST_OUT)/,$(PRIVATE_DIR))
- $(hide) touch $@
-
-# Generate the test descriptions for the core-tests
-# Parameters:
-# $1 : The output file where the description should be written (without the '.xml' extension)
-# $2 : The AndroidManifest.xml corresponding to the test package
-# $3 : The jar file name on PRIVATE_CLASSPATH containing junit tests to search for
-# $4 : The package prefix of classes to include, possible empty
-# $5 : The architecture of the current build
-# $6 : The directory containing vogar expectations files
-# $7 : The Android.mk corresponding to the test package (required for host-side tests only)
-define generate-core-test-description
-@echo "Generate core-test description ("$(notdir $(1))")"
-$(hide) java -Xmx256M \
- -Xbootclasspath/a:$(PRIVATE_CLASSPATH):$(JUNIT_HOST_JAR) \
- -classpath $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR) \
- $(PRIVATE_PARAMS) CollectAllTests $(1) $(2) $(3) "$(4)" $(5) $(6) $(7)
-endef
-
-OJ_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)
-CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)
-CONSCRYPT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,conscrypt,,COMMON)
-BOUNCYCASTLE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,bouncycastle,,COMMON)
-APACHEXML_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,apache-xml,,COMMON)
-OKHTTP_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,okhttp-nojarjar,,COMMON)
-OKHTTPTESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,okhttp-tests-nojarjar,,COMMON)
-OKHTTP_REPACKAGED_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,okhttp,,COMMON)
-APACHEHARMONYTESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,apache-harmony-tests,,COMMON)
-SQLITEJDBC_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,sqlite-jdbc,,COMMON)
-JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
-CORETESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
-JSR166TESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,jsr166-tests,,COMMON)
-CONSCRYPTTESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,conscrypt-tests,,COMMON)
-TZDATAUPDATETESTS_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,tzdata_update-tests,,COMMON)
-
-GEN_CLASSPATH := \
- $(OJ_INTERMEDIATES)/classes.jar:$(CORE_INTERMEDIATES)/classes.jar:$(CONSCRYPT_INTERMEDIATES)/classes.jar:$(BOUNCYCASTLE_INTERMEDIATES)/classes.jar:$(APACHEXML_INTERMEDIATES)/classes.jar:$(APACHEHARMONYTESTS_INTERMEDIATES)/classes.jar:$(OKHTTP_INTERMEDIATES)/classes.jar:$(OKHTTPTESTS_INTERMEDIATES)/classes.jar:$(OKHTTP_REPACKAGED_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(SQLITEJDBC_INTERMEDIATES)/javalib.jar:$(CORETESTS_INTERMEDIATES)/javalib.jar:$(JSR166TESTS_INTERMEDIATES)/javalib.jar:$(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar:$(TZDATAUPDATETESTS_INTERMEDIATES)/javalib.jar
-
-CTS_CORE_XMLS := \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.dalvik.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.com.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.conscrypt.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.sun.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tests.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.org.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.libcore.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.jsr166.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_annotation.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_io.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_lang.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_math.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_net.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_nio.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_text.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_util.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_javax_security.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_beans.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_logging.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_prefs.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_sql.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.okhttp.xml \
- $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tzdata.xml \
-
-$(CTS_CORE_XMLS): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
-# Why does this depend on javalib.jar instead of classes.jar? Because
-# even though the tool will operate on the classes.jar files, the
-# build system requires that dependencies use javalib.jar. If
-# javalib.jar is up-to-date, then classes.jar is as well. Depending
-# on classes.jar will build the files incorrectly.
-CTS_CORE_XMLS_DEPS := $(CTS_CORE_CASES) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(JUNIT_HOST_JAR) $(CORE_INTERMEDIATES)/javalib.jar $(BOUNCYCASTLE_INTERMEDIATES)/javalib.jar $(APACHEXML_INTERMEDIATES)/javalib.jar $(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar $(OKHTTP_INTERMEDIATES)/javalib.jar $(OKHTTPTESTS_INTERMEDIATES)/javalib.jar $(OKHTTP_REPACKAGED_INTERMEDIATES)/javalib.jar $(SQLITEJDBC_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(CORETESTS_INTERMEDIATES)/javalib.jar $(JSR166TESTS_INTERMEDIATES)/javalib.jar $(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar $(TZDATAUPDATETESTS_INTERMEDIATES)/javalib.jar build/core/tasks/cts.mk | $(ACP)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.dalvik.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.dalvik,\
- cts/tests/core/libcore/dalvik/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,dalvik,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.com.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.com,\
- cts/tests/core/libcore/com/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,com,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.conscrypt.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.conscrypt,\
- cts/tests/core/libcore/conscrypt/AndroidManifest.xml,\
- $(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar,,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.sun.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.sun,\
- cts/tests/core/libcore/sun/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,sun,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tests.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tests,\
- cts/tests/core/libcore/tests/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,tests,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.org.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.org,\
- cts/tests/core/libcore/org/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,\
- org.w3c.domts:\
- org.apache.harmony.security.tests:\
- org.apache.harmony.nio.tests:\
- org.apache.harmony.crypto.tests:\
- org.apache.harmony.regex.tests:\
- org.apache.harmony.luni.tests:\
- org.apache.harmony.tests.internal.net.www.protocol:\
- org.apache.harmony.tests.javax.net:\
- org.apache.harmony.tests.javax.xml:\
- org.json,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.libcore.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.libcore,\
- cts/tests/core/libcore/libcore/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,libcore,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.jsr166.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.jsr166,\
- cts/tests/core/libcore/jsr166/AndroidManifest.xml,\
- $(JSR166TESTS_INTERMEDIATES)/javalib.jar,jsr166,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_annotation.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_annotation,\
- cts/tests/core/libcore/harmony_annotation/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.annotation.tests,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_io.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_io,\
- cts/tests/core/libcore/harmony_java_io/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.io,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_lang.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_lang,\
- cts/tests/core/libcore/harmony_java_lang/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.lang,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_math.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_math,\
- cts/tests/core/libcore/harmony_java_math/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.math,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_net.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_net,\
- cts/tests/core/libcore/harmony_java_net/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.net,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_nio.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_nio,\
- cts/tests/core/libcore/harmony_java_nio/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.nio,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_text.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_text,\
- cts/tests/core/libcore/harmony_java_text/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.text,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_util.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_java_util,\
- cts/tests/core/libcore/harmony_java_util/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.java.util,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_javax_security.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_javax_security,\
- cts/tests/core/libcore/harmony_javax_security/AndroidManifest.xml,\
- $(CORETESTS_INTERMEDIATES)/javalib.jar,org.apache.harmony.tests.javax.security,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_beans.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_beans,\
- cts/tests/core/libcore/harmony_beans/AndroidManifest.xml,\
- $(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.beans,\
- $(TARGET_ARCH),libcore/expectations external/apache-harmony/Android.mk)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_logging.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_logging,\
- cts/tests/core/libcore/harmony_logging/AndroidManifest.xml,\
- $(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.logging,\
- $(TARGET_ARCH),libcore/expectations external/apache-harmony/Android.mk)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_prefs.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_prefs,\
- cts/tests/core/libcore/harmony_prefs/AndroidManifest.xml,\
- $(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.prefs,\
- $(TARGET_ARCH),libcore/expectations external/apache-harmony/Android.mk)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_sql.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.harmony_sql,\
- cts/tests/core/libcore/harmony_sql/AndroidManifest.xml,\
- $(APACHEHARMONYTESTS_INTERMEDIATES)/javalib.jar,com.android.org.apache.harmony.sql,\
- $(TARGET_ARCH),libcore/expectations external/apache-harmony/Android.mk)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.okhttp.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.okhttp,\
- cts/tests/core/libcore/okhttp/AndroidManifest.xml,\
- $(OKHTTPTESTS_INTERMEDIATES)/javalib.jar,,\
- $(TARGET_ARCH),libcore/expectations)
-
-$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tzdata.xml: $(CTS_CORE_XMLS_DEPS)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.tzdata,\
- cts/tests/core/libcore/tzdata/AndroidManifest.xml,\
- $(TZDATAUPDATETESTS_INTERMEDIATES)/javalib.jar,,\
- $(TARGET_ARCH),libcore/expectations)
-
-# ----- Generate the test descriptions for the vm-tests-tf -----
-#
-CORE_VM_TEST_TF_DESC := $(CTS_TESTCASES_OUT)/android.core.vm-tests-tf.xml
-
-# core tests only needed to get hold of junit-framework-classes
-OJ_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)
-CORE_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)
-JUNIT_INTERMEDIATES :=$(call intermediates-dir-for,JAVA_LIBRARIES,core-junit,,COMMON)
-
-GEN_CLASSPATH := $(OJ_INTERMEDIATES)/classes.jar:$(CORE_INTERMEDIATES)/classes.jar:$(JUNIT_INTERMEDIATES)/classes.jar:$(VMTESTSTF_JAR):$(TF_JAR)
-
-$(CORE_VM_TEST_TF_DESC): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
-# Please see big comment above on why this line depends on javalib.jar instead of classes.jar
-$(CORE_VM_TEST_TF_DESC): $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(JUNIT_HOST_JAR) $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(VMTESTSTF_JAR) | $(ACP)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.vm-tests-tf,\
- cts/tests/vm-tests-tf/AndroidManifest.xml,\
- $(VMTESTSTF_JAR),"",\
- $(TARGET_ARCH),\
- libcore/expectations,\
- cts/tools/vm-tests-tf/Android.mk)
-
-# Generate the default test plan for User.
-# Usage: buildCts.py <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>
-
-$(DEFAULT_TEST_PLAN): $(cts_dir)/all_cts_files_stamp $(cts_tools_src_dir)/utils/buildCts.py $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CTS_CORE_XMLS) $(CTS_TEST_XMLS) $(CORE_VM_TEST_TF_DESC)
- $(hide) $(cts_tools_src_dir)/utils/buildCts.py cts/tests/tests/ $(PRIVATE_DIR) $(TMP_DIR) \
- $(TOP) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar
- $(hide) mkdir -p $(dir $@) && touch $@
-
-# Package CTS and clean up.
-#
-# TODO:
-# Pack cts.bat into the same zip file as well. See http://buganizer/issue?id=1656821 for more details
-INTERNAL_CTS_TARGET := $(cts_dir)/$(cts_name).zip
-$(INTERNAL_CTS_TARGET): PRIVATE_NAME := $(cts_name)
-$(INTERNAL_CTS_TARGET): PRIVATE_CTS_DIR := $(cts_dir)
-$(INTERNAL_CTS_TARGET): PRIVATE_DIR := $(cts_dir)/$(cts_name)
-$(INTERNAL_CTS_TARGET): TMP_DIR := $(cts_dir)/temp
-$(INTERNAL_CTS_TARGET): $(cts_dir)/all_cts_files_stamp $(DEFAULT_TEST_PLAN)
- $(hide) echo "Package CTS: $@"
- $(hide) cd $(dir $@) && zip -rqX $(notdir $@) $(PRIVATE_NAME)
-
-.PHONY: old-cts
-old-cts: $(INTERNAL_CTS_TARGET) adb
-$(call dist-for-goals,old-cts,$(INTERNAL_CTS_TARGET))
diff --git a/core/tasks/tools/build_custom_image.mk b/core/tasks/tools/build_custom_image.mk
index ec491fa..8c098d6 100644
--- a/core/tasks/tools/build_custom_image.mk
+++ b/core/tasks/tools/build_custom_image.mk
@@ -62,6 +62,14 @@
$(eval my_image_copy_files += $(src))\
$(eval my_copy_pairs += $(src):$(my_staging_dir)/$(word 2,$(pair))))
+ifndef CUSTOM_IMAGE_AVB_KEY_PATH
+# If key path isn't specified, use the default signing args.
+my_avb_signing_args := $(INTERNAL_AVB_SIGNING_ARGS)
+else
+my_avb_signing_args := \
+ --algorithm $(CUSTOM_IMAGE_AVB_ALGORITHM) --key $(CUSTOM_IMAGE_AVB_KEY_PATH)
+endif
+
$(my_built_custom_image): PRIVATE_INTERMEDIATES := $(intermediates)
$(my_built_custom_image): PRIVATE_MOUNT_POINT := $(CUSTOM_IMAGE_MOUNT_POINT)
$(my_built_custom_image): PRIVATE_PARTITION_SIZE := $(CUSTOM_IMAGE_PARTITION_SIZE)
@@ -74,6 +82,17 @@
$(my_built_custom_image): PRIVATE_VERITY_KEY := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY)
$(my_built_custom_image): PRIVATE_VERITY_BLOCK_DEVICE := $(CUSTOM_IMAGE_VERITY_BLOCK_DEVICE)
$(my_built_custom_image): PRIVATE_DICT_FILE := $(CUSTOM_IMAGE_DICT_FILE)
+$(my_built_custom_image): PRIVATE_AVB_AVBTOOL := $(AVBTOOL)
+$(my_built_custom_image): PRIVATE_AVB_SIGNING_ARGS := $(my_avb_signing_args)
+$(my_built_custom_image): PRIVATE_AVB_HASH_ENABLE := $(CUSTOM_IMAGE_AVB_HASH_ENABLE)
+$(my_built_custom_image): PRIVATE_AVB_ADD_HASH_FOOTER_ARGS := $(CUSTOM_IMAGE_AVB_ADD_HASH_FOOTER_ARGS)
+$(my_built_custom_image): PRIVATE_AVB_HASHTREE_ENABLE := $(CUSTOM_IMAGE_AVB_HASHTREE_ENABLE)
+$(my_built_custom_image): PRIVATE_AVB_ADD_HASHTREE_FOOTER_ARGS := $(CUSTOM_IMAGE_AVB_ADD_HASHTREE_FOOTER_ARGS)
+ifeq (true,$(filter true, $(CUSTOM_IMAGE_AVB_HASH_ENABLE) $(CUSTOM_IMAGE_AVB_HASHTREE_ENABLE)))
+ $(my_built_custom_image): $(AVBTOOL)
+else ifneq (,$(filter true, $(CUSTOM_IMAGE_AVB_HASH_ENABLE) $(CUSTOM_IMAGE_AVB_HASHTREE_ENABLE)))
+ $(error Cannot set both CUSTOM_IMAGE_AVB_HASH_ENABLE and CUSTOM_IMAGE_AVB_HASHTREE_ENABLE to true)
+endif
$(my_built_custom_image): $(INTERNAL_USERIMAGES_DEPS) $(my_built_modules) $(my_image_copy_files) \
$(CUSTOM_IMAGE_DICT_FILE)
@echo "Build image $@"
@@ -88,14 +107,24 @@
# Generate the dict.
$(hide) echo "# For all accepted properties, see BuildImage() in tools/releasetools/build_image.py" > $(PRIVATE_INTERMEDIATES)/image_info.txt
$(hide) echo "mount_point=$(PRIVATE_MOUNT_POINT)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
+ $(hide) echo "partition_name=$(PRIVATE_MOUNT_POINT)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
$(hide) echo "fs_type=$(PRIVATE_FILE_SYSTEM_TYPE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
$(hide) echo "partition_size=$(PRIVATE_PARTITION_SIZE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
+ $(hide) echo "ext_mkuserimg=$(notdir $(MKEXTUSERIMG))" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
$(if $(PRIVATE_SELINUX),$(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt)
$(if $(PRIVATE_SUPPORT_VERITY),\
$(hide) echo "verity=$(PRIVATE_SUPPORT_VERITY)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt;\
echo "verity_key=$(PRIVATE_VERITY_KEY)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt;\
echo "verity_signer_cmd=$(VERITY_SIGNER)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt;\
echo "verity_block_device=$(PRIVATE_VERITY_BLOCK_DEVICE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt)
+ $(hide) echo "avb_avbtool=$(PRIVATE_AVB_AVBTOOL)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
+ $(hide) echo "avb_signing_args=$(PRIVATE_AVB_SIGNING_ARGS)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
+ $(if $(PRIVATE_AVB_HASH_ENABLE),\
+ $(hide) echo "avb_hash_enable=$(PRIVATE_AVB_HASH_ENABLE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt;\
+ echo "avb_add_hash_footer_args=$(PRIVATE_AVB_ADD_HASH_FOOTER_ARGS)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt)
+ $(if $(PRIVATE_AVB_HASHTREE_ENABLE),\
+ $(hide) echo "avb_hashtree_enable=$(PRIVATE_AVB_HASHTREE_ENABLE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt;\
+ echo "avb_add_hashtree_footer_args=$(PRIVATE_AVB_ADD_HASHTREE_FOOTER_ARGS)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt)
$(if $(PRIVATE_DICT_FILE),\
$(hide) echo "# Properties from $(PRIVATE_DICT_FILE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt;\
cat $(PRIVATE_DICT_FILE) >> $(PRIVATE_INTERMEDIATES)/image_info.txt)
diff --git a/core/tasks/tools/compatibility.mk b/core/tasks/tools/compatibility.mk
index d8f900e..1455a44 100644
--- a/core/tasks/tools/compatibility.mk
+++ b/core/tasks/tools/compatibility.mk
@@ -37,13 +37,14 @@
$(compatibility_zip): PRIVATE_TOOLS := $(test_tools)
$(compatibility_zip): PRIVATE_SUITE_NAME := $(test_suite_name)
$(compatibility_zip): PRIVATE_DYNAMIC_CONFIG := $(test_suite_dynamic_config)
-$(compatibility_zip): $(test_artifacts) $(test_tools) $(test_suite_dynamic_config) | $(ADB) $(ACP)
+$(compatibility_zip): $(test_artifacts) $(test_tools) $(test_suite_dynamic_config) $(SOONG_ZIP) | $(ADB) $(ACP)
# Make dir structure
$(hide) mkdir -p $(PRIVATE_OUT_DIR)/tools $(PRIVATE_OUT_DIR)/testcases
# Copy tools
$(hide) $(ACP) -fp $(PRIVATE_TOOLS) $(PRIVATE_OUT_DIR)/tools
$(if $(PRIVATE_DYNAMIC_CONFIG),$(hide) $(ACP) -fp $(PRIVATE_DYNAMIC_CONFIG) $(PRIVATE_OUT_DIR)/testcases/$(PRIVATE_SUITE_NAME).dynamic)
- $(hide) cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME)
+ $(hide) find $(dir $@)/$(PRIVATE_NAME) | sort >$@.list
+ $(hide) $(SOONG_ZIP) -d -o $@ -C $(dir $@) -l $@.list
# Reset all input variables
test_suite_name :=
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index 24a7608..63fab63 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -9,21 +9,38 @@
#
#
+my_makefile := $(lastword $(filter-out $(lastword $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
my_staging_dir := $(call intermediates-dir-for,PACKAGING,$(my_package_name))
my_built_modules :=
my_copy_pairs :=
my_pickup_files :=
+# Iterate over the modules and include their direct dependencies stated in the
+# LOCAL_REQUIRED_MODULES.
+my_modules_and_deps := $(my_modules)
+$(foreach m,$(my_modules),\
+ $(eval _explicitly_required := \
+ $(strip $(ALL_MODULES.$(m).EXPLICITLY_REQUIRED)\
+ $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).EXPLICITLY_REQUIRED)))\
+ $(eval my_modules_and_deps += $(_explicitly_required))\
+)
+
+# Ignore unknown installed files on partial builds
+my_missing_files :=
+ifneq ($(ALLOW_MISSING_DEPENDENCIES),true)
+my_missing_files = $(shell $(call echo-warning,$(my_makefile),$(my_package_name): Unknown installed file for module '$(1)'))
+endif
+
# Iterate over modules' built files and installed files;
# Calculate the dest files in the output zip file.
-$(foreach m,$(my_modules),\
+$(foreach m,$(my_modules_and_deps),\
$(eval _pickup_files := $(strip $(ALL_MODULES.$(m).PICKUP_FILES)\
$(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).PICKUP_FILES)))\
$(eval _built_files := $(strip $(ALL_MODULES.$(m).BUILT_INSTALLED)\
$(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).BUILT_INSTALLED)))\
$(if $(_pickup_files)$(_built_files),,\
- $(warning Unknown installed file for module '$(m)'))\
+ $(call my_missing_files,$(m)))\
$(eval my_pickup_files += $(_pickup_files))\
$(foreach i, $(_built_files),\
$(eval bui_ins := $(subst :,$(space),$(i)))\
@@ -37,26 +54,16 @@
$(eval my_copy_pairs += $(bui):$(my_staging_dir)/$(my_copy_dest)))\
))
-define copy-tests-in-batch
-$(hide) $(foreach p, $(1),\
- $(eval pair := $(subst :,$(space),$(p)))\
- mkdir -p $(dir $(word 2,$(pair)));\
- cp -Rf $(word 1,$(pair)) $(word 2,$(pair));)
-endef
-
my_package_zip := $(my_staging_dir)/$(my_package_name).zip
$(my_package_zip): PRIVATE_COPY_PAIRS := $(my_copy_pairs)
$(my_package_zip): PRIVATE_PICKUP_FILES := $(my_pickup_files)
$(my_package_zip) : $(my_built_modules)
@echo "Package $@"
@rm -rf $(dir $@) && mkdir -p $(dir $@)
- $(call copy-tests-in-batch,$(wordlist 1,200,$(PRIVATE_COPY_PAIRS)))
- $(call copy-tests-in-batch,$(wordlist 201,400,$(PRIVATE_COPY_PAIRS)))
- $(call copy-tests-in-batch,$(wordlist 401,600,$(PRIVATE_COPY_PAIRS)))
- $(call copy-tests-in-batch,$(wordlist 601,800,$(PRIVATE_COPY_PAIRS)))
- $(call copy-tests-in-batch,$(wordlist 801,1000,$(PRIVATE_COPY_PAIRS)))
- $(call copy-tests-in-batch,$(wordlist 1001,1200,$(PRIVATE_COPY_PAIRS)))
- $(call copy-tests-in-batch,$(wordlist 1201,9999,$(PRIVATE_COPY_PAIRS)))
+ $(foreach p, $(PRIVATE_COPY_PAIRS),\
+ $(eval pair := $(subst :,$(space),$(p)))\
+ mkdir -p $(dir $(word 2,$(pair))) && \
+ cp -Rf $(word 1,$(pair)) $(word 2,$(pair)) && ) true
$(hide) $(foreach f, $(PRIVATE_PICKUP_FILES),\
- cp -RfL $(f) $(dir $@);)
+ cp -RfL $(f) $(dir $@) && ) true
$(hide) cd $(dir $@) && zip -rqX $(notdir $@) *
diff --git a/core/tasks/vendor_module_check.mk b/core/tasks/vendor_module_check.mk
index e3761ae..ae967c6 100644
--- a/core/tasks/vendor_module_check.mk
+++ b/core/tasks/vendor_module_check.mk
@@ -47,19 +47,43 @@
widevine
-ifneq (,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_RESTRICT_VENDOR_FILES))
+_restrictions := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_RESTRICT_VENDOR_FILES))
-_vendor_check_modules := $(product_MODULES)
+ifneq (,$(_restrictions))
+ifneq (,$(PRODUCTS.$(INTERNAL_PRODUCT).VENDOR_PRODUCT_RESTRICT_VENDOR_FILES))
+$(error Error: cannot set both PRODUCT_RESTRICT_VENDOR_FILES and VENDOR_PRODUCT_RESTRICT_VENDOR_FILES)
+endif
+_vendor_exception_path_prefix :=
+_vendor_exception_modules :=
+else
+_restrictions := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).VENDOR_PRODUCT_RESTRICT_VENDOR_FILES))
+_vendor_exception_path_prefix := $(patsubst %, vendor/%/%, $(PRODUCTS.$(INTERNAL_PRODUCT).VENDOR_EXCEPTION_PATHS))
+_vendor_exception_modules := $(PRODUCTS.$(INTERNAL_PRODUCT).VENDOR_EXCEPTION_MODULES)
+endif
+
+
+ifneq (,$(_restrictions))
+
+_vendor_check_modules := \
+$(foreach m, $(filter-out $(_vendor_exception_modules), $(product_MODULES)), \
+ $(if $(filter-out FAKE, $(ALL_MODULES.$(m).CLASS)),\
+ $(if $(filter vendor/%, $(ALL_MODULES.$(m).PATH)),\
+ $(if $(filter-out $(_vendor_exception_path_prefix), $(ALL_MODULES.$(m).PATH)),\
+ $(m)))))
_vendor_module_owner_info :=
# Restrict owners
-ifneq (,$(filter true owner all, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_RESTRICT_VENDOR_FILES)))
+ifneq (,$(filter true owner all, $(_restrictions)))
-ifneq (,$(filter vendor/%, $(PRODUCT_PACKAGE_OVERLAYS) $(DEVICE_PACKAGE_OVERLAYS)))
-$(error Error: Product "$(TARGET_PRODUCT)" cannot have overlay in vendor tree: \
+_vendor_package_overlays := $(filter-out $(_vendor_exception_path_prefix),\
$(filter vendor/%, $(PRODUCT_PACKAGE_OVERLAYS) $(DEVICE_PACKAGE_OVERLAYS)))
+ifneq (,$(_vendor_package_overlays))
+$(error Error: Product "$(TARGET_PRODUCT)" cannot have overlay in vendor tree: $(_vendor_package_overlays))
endif
-_vendor_check_copy_files := $(filter vendor/%, $(PRODUCT_COPY_FILES))
+_vendor_package_overlays :=
+
+_vendor_check_copy_files := $(filter-out $(_vendor_exception_path_prefix),\
+ $(filter vendor/%, $(PRODUCT_COPY_FILES)))
ifneq (,$(_vendor_check_copy_files))
$(foreach c, $(_vendor_check_copy_files), \
$(if $(filter $(_vendor_owner_whitelist), $(call word-colon,3,$(c))),,\
@@ -69,28 +93,24 @@
_vendor_check_copy_files :=
$(foreach m, $(_vendor_check_modules), \
- $(if $(filter vendor/%, $(ALL_MODULES.$(m).PATH)),\
- $(if $(filter-out FAKE, $(ALL_MODULES.$(m).CLASS)),\
- $(if $(filter $(_vendor_owner_whitelist), $(ALL_MODULES.$(m).OWNER)),,\
- $(error Error: vendor module "$(m)" in $(ALL_MODULES.$(m).PATH) with unknown owner \
- "$(ALL_MODULES.$(m).OWNER)" in product "$(TARGET_PRODUCT)"))\
- $(if $(ALL_MODULES.$(m).INSTALLED),\
- $(eval _vendor_module_owner_info += $(patsubst $(PRODUCT_OUT)/%,%,$(ALL_MODULES.$(m).INSTALLED)):$(ALL_MODULES.$(m).OWNER))))))
+ $(if $(filter $(_vendor_owner_whitelist), $(ALL_MODULES.$(m).OWNER)),,\
+ $(error Error: vendor module "$(m)" in $(ALL_MODULES.$(m).PATH) with unknown owner \
+ "$(ALL_MODULES.$(m).OWNER)" in product "$(TARGET_PRODUCT)"))\
+ $(if $(ALL_MODULES.$(m).INSTALLED),\
+ $(eval _vendor_module_owner_info += $(patsubst $(PRODUCT_OUT)/%,%,$(ALL_MODULES.$(m).INSTALLED)):$(ALL_MODULES.$(m).OWNER))))
endif
# Restrict paths
-ifneq (,$(filter path all, $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_RESTRICT_VENDOR_FILES)))
+ifneq (,$(filter path all, $(_restrictions)))
$(foreach m, $(_vendor_check_modules), \
- $(if $(filter vendor/%, $(ALL_MODULES.$(m).PATH)),\
- $(if $(filter-out FAKE, $(ALL_MODULES.$(m).CLASS)),\
- $(if $(filter-out ,$(ALL_MODULES.$(m).INSTALLED)),\
- $(if $(filter $(TARGET_OUT_VENDOR)/% $(HOST_OUT)/%, $(ALL_MODULES.$(m).INSTALLED)),,\
- $(error Error: vendor module "$(m)" in $(ALL_MODULES.$(m).PATH) \
- in product "$(TARGET_PRODUCT)" being installed to \
- $(ALL_MODULES.$(m).INSTALLED) which is not in the vendor tree))))))
+ $(if $(filter-out ,$(ALL_MODULES.$(m).INSTALLED)),\
+ $(if $(filter $(TARGET_OUT_VENDOR)/% $(TARGET_OUT_ODM)/% $(HOST_OUT)/%, $(ALL_MODULES.$(m).INSTALLED)),,\
+ $(error Error: vendor module "$(m)" in $(ALL_MODULES.$(m).PATH) \
+ in product "$(TARGET_PRODUCT)" being installed to \
+ $(ALL_MODULES.$(m).INSTALLED) which is not in the vendor tree or odm tree))))
endif
@@ -113,4 +133,7 @@
_vendor_module_owner_info_txt :=
_vendor_module_owner_info :=
_vendor_check_modules :=
+_vendor_exception_path_prefix :=
+_vendor_exception_modules :=
+_restrictions :=
endif
diff --git a/core/tasks/vts.mk b/core/tasks/vts.mk
deleted file mode 100644
index 507f22e..0000000
--- a/core/tasks/vts.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# 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.
-
-test_suite_name := vts
-test_suite_tradefed := vts-tradefed
-test_suite_readme := test/vts/README.md
-
-include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
-
-.PHONY: vts
-vts: $(compatibility_zip)
-$(call dist-for-goals, vts, $(compatibility_zip))
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 369ca90..53bb111 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -34,28 +34,66 @@
# if the file exists.
#
INTERNAL_BUILD_ID_MAKEFILE := $(wildcard $(BUILD_SYSTEM)/build_id.mk)
-ifneq "" "$(INTERNAL_BUILD_ID_MAKEFILE)"
+ifdef INTERNAL_BUILD_ID_MAKEFILE
include $(INTERNAL_BUILD_ID_MAKEFILE)
endif
-ifeq "" "$(PLATFORM_VERSION)"
- # This is the canonical definition of the platform version,
- # which is the version that we reveal to the end user.
- # Update this value when the platform version changes (rather
- # than overriding it somewhere else). Can be an arbitrary string.
+DEFAULT_PLATFORM_VERSION := OPR1
+MIN_PLATFORM_VERSION := OPR1
+MAX_PLATFORM_VERSION := PPR1
- # When you add a new PLATFORM_VERSION which will result in a new
- # PLATFORM_SDK_VERSION please ensure you add a corresponding isAtLeast*
- # method in the following java file:
- # frameworks/support/compat/gingerbread/android/support/v4/os/BuildCompat.java
+ALLOWED_VERSIONS := $(call allowed-platform-versions,\
+ $(MIN_PLATFORM_VERSION),\
+ $(MAX_PLATFORM_VERSION),\
+ $(DEFAULT_PLATFORM_VERSION))
- # When you change PLATFORM_VERSION for a given PLATFORM_SDK_VERSION
- # please add that PLATFORM_VERSION to the following text file:
- # cts/tests/tests/os/assets/platform_versions.txt
- PLATFORM_VERSION := 7.1.2
+ifndef TARGET_PLATFORM_VERSION
+ TARGET_PLATFORM_VERSION := $(DEFAULT_PLATFORM_VERSION)
+else ifeq ($(TARGET_PLATFORM_VERSION),OPR1)
+ # HACK: lunch currently sets TARGET_PLATFORM_VERSION to
+ # DEFAULT_PLATFORM_VERSION, which causes unnecessary pain
+ # when the old DEFAULT_PLATFORM_VERSION becomes invalid.
+ # For now, silently upgrade OPR1 to the current default.
+ TARGET_PLATFORM_VERSION := $(DEFAULT_PLATFORM_VERSION)
endif
-ifeq "" "$(PLATFORM_SDK_VERSION)"
+ifeq (,$(filter $(ALLOWED_VERSIONS), $(TARGET_PLATFORM_VERSION)))
+ $(warning Invalid TARGET_PLATFORM_VERSION '$(TARGET_PLATFORM_VERSION)', must be one of)
+ $(error $(ALLOWED_VERSIONS))
+endif
+
+# Default versions for each TARGET_PLATFORM_VERSION
+# TODO: PLATFORM_VERSION, PLATFORM_SDK_VERSION, etc. should be conditional
+# on this
+
+# This is the canonical definition of the platform version,
+# which is the version that we reveal to the end user.
+# Update this value when the platform version changes (rather
+# than overriding it somewhere else). Can be an arbitrary string.
+
+# When you add a new PLATFORM_VERSION which will result in a new
+# PLATFORM_SDK_VERSION please ensure you add a corresponding isAtLeast*
+# method in the following java file:
+# frameworks/support/compat/gingerbread/android/support/v4/os/BuildCompat.java
+
+# When you change PLATFORM_VERSION for a given PLATFORM_SDK_VERSION
+# please add that PLATFORM_VERSION to the following text file:
+# cts/tests/tests/os/assets/platform_versions.txt
+PLATFORM_VERSION.OPR1 := O
+
+# These are the current development codenames.
+PLATFORM_VERSION_CODENAME.OPR1 := O
+PLATFORM_VERSION_CODENAME.PPR1 := P
+
+ifndef PLATFORM_VERSION
+ PLATFORM_VERSION := $(PLATFORM_VERSION.$(TARGET_PLATFORM_VERSION))
+ ifndef PLATFORM_VERSION
+ # PLATFORM_VERSION falls back to TARGET_PLATFORM_VERSION
+ PLATFORM_VERSION := $(TARGET_PLATFORM_VERSION)
+ endif
+endif
+
+ifndef PLATFORM_SDK_VERSION
# This is the canonical definition of the SDK version, which defines
# the set of APIs and functionality available in the platform. It
# is a single integer that increases monotonically as updates to
@@ -75,30 +113,47 @@
PLATFORM_SDK_VERSION := 25
endif
-ifeq "" "$(PLATFORM_JACK_MIN_SDK_VERSION)"
+ifndef PLATFORM_JACK_MIN_SDK_VERSION
# This is definition of the min SDK version given to Jack for the current
# platform. For released version it should be the same as
# PLATFORM_SDK_VERSION. During development, this number may be incremented
# before PLATFORM_SDK_VERSION if the plateform starts to add new java
# language supports.
- PLATFORM_JACK_MIN_SDK_VERSION := 25
+ PLATFORM_JACK_MIN_SDK_VERSION := o-b1
endif
-ifeq "" "$(PLATFORM_VERSION_CODENAME)"
- # This is the current development code-name, if the build is not a final
- # release build. If this is a final release build, it is simply "REL".
- PLATFORM_VERSION_CODENAME := REL
+ifndef PLATFORM_VERSION_CODENAME
+ PLATFORM_VERSION_CODENAME := $(PLATFORM_VERSION_CODENAME.$(TARGET_PLATFORM_VERSION))
+ ifndef PLATFORM_VERSION_CODENAME
+ # PLATFORM_VERSION_CODENAME falls back to TARGET_PLATFORM_VERSION
+ PLATFORM_VERSION_CODENAME := $(TARGET_PLATFORM_VERSION)
+ endif
# This is all of the development codenames that are active. Should be either
# the same as PLATFORM_VERSION_CODENAME or a comma-separated list of additional
# codenames after PLATFORM_VERSION_CODENAME.
- PLATFORM_VERSION_ALL_CODENAMES := $(PLATFORM_VERSION_CODENAME)
+ PLATFORM_VERSION_ALL_CODENAMES :=
+
+ # Build a list of all possible code names. Avoid duplicates, and stop when we
+ # reach a codename that matches PLATFORM_VERSION_CODENAME (anything beyond
+ # that is not included in our build.
+ _versions_in_target := \
+ $(call find_and_earlier,$(ALL_VERSIONS),$(TARGET_PLATFORM_VERSION))
+ $(foreach version,$(_versions_in_target),\
+ $(eval _codename := $(PLATFORM_VERSION_CODENAME.$(version)))\
+ $(if $(filter $(_codename),$(PLATFORM_VERSION_ALL_CODENAMES)),,\
+ $(eval PLATFORM_VERSION_ALL_CODENAMES += $(_codename))))
+
+ # And convert from space separated to comma separated.
+ PLATFORM_VERSION_ALL_CODENAMES := \
+ $(subst $(space),$(comma),$(strip $(PLATFORM_VERSION_ALL_CODENAMES)))
+
endif
-ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
+ifeq (REL,$(PLATFORM_VERSION_CODENAME))
PLATFORM_PREVIEW_SDK_VERSION := 0
else
- ifeq "" "$(PLATFORM_PREVIEW_SDK_VERSION)"
+ ifndef PLATFORM_PREVIEW_SDK_VERSION
# This is the definition of a preview SDK version over and above the current
# platform SDK version. Unlike the platform SDK version, a higher value
# for preview SDK version does NOT mean that all prior preview APIs are
@@ -112,20 +167,20 @@
endif
endif
-ifeq "" "$(DEFAULT_APP_TARGET_SDK)"
+ifndef DEFAULT_APP_TARGET_SDK
# This is the default minSdkVersion and targetSdkVersion to use for
# all .apks created by the build system. It can be overridden by explicitly
# setting these in the .apk's AndroidManifest.xml. It is either the code
# name of the development build or, if this is a release build, the official
# SDK version of this release.
- ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
+ ifeq (REL,$(PLATFORM_VERSION_CODENAME))
DEFAULT_APP_TARGET_SDK := $(PLATFORM_SDK_VERSION)
else
DEFAULT_APP_TARGET_SDK := $(PLATFORM_VERSION_CODENAME)
endif
endif
-ifeq "" "$(PLATFORM_SECURITY_PATCH)"
+ifndef PLATFORM_SECURITY_PATCH
# Used to indicate the security patch that has been applied to the device.
# It must signify that the build includes all security patches issued up through the designated Android Public Security Bulletin.
# It must be of the form "YYYY-MM-DD" on production devices.
@@ -134,7 +189,7 @@
PLATFORM_SECURITY_PATCH := 2017-07-05
endif
-ifeq "" "$(PLATFORM_BASE_OS)"
+ifndef PLATFORM_BASE_OS
# Used to indicate the base os applied to the device.
# Can be an arbitrary string, but must be a single word.
#
@@ -142,7 +197,7 @@
PLATFORM_BASE_OS :=
endif
-ifeq "" "$(BUILD_ID)"
+ifndef BUILD_ID
# Used to signify special builds. E.g., branches and/or releases,
# like "M5-RC7". Can be an arbitrary string, but must be a single
# word and a valid file name.
@@ -151,7 +206,7 @@
BUILD_ID := UNKNOWN
endif
-ifeq "" "$(BUILD_DATETIME)"
+ifndef BUILD_DATETIME
# Used to reproduce builds by setting the same time. Must be the number
# of seconds since the Epoch.
BUILD_DATETIME := $(shell date +%s)
@@ -163,7 +218,7 @@
DATE := date -d @$(BUILD_DATETIME)
endif
-ifeq "" "$(BUILD_NUMBER)"
+ifndef BUILD_NUMBER
# BUILD_NUMBER should be set to the source control value that
# represents the current state of the source code. E.g., a
# perforce changelist number or a git hash. Can be an arbitrary string
diff --git a/envsetup.sh b/envsetup.sh
index 35df2d5..b71a825 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -28,9 +28,9 @@
Look at the source to view more functions. The complete list is:
EOF
- T=$(gettop)
- local A
- A=""
+ local T=$(gettop)
+ local A=""
+ local i
for i in `cat $T/build/envsetup.sh | sed -n "/^[[:blank:]]*function /s/function \([a-z_]*\).*/\1/p" | sort | uniq`; do
A="$A $i"
done
@@ -40,7 +40,7 @@
# Get all the build variables needed by this script in a single call to the build system.
function build_build_var_cache()
{
- T=$(gettop)
+ local T=$(gettop)
# Grep out the variable names from the script.
cached_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
cached_abs_vars=`cat $T/build/envsetup.sh | tr '()' ' ' | awk '{for(i=1;i<=NF;i++) if($i~/get_abs_build_var/) print $(i+1)}' | sort -u | tr '\n' ' '`
@@ -74,6 +74,7 @@
function destroy_build_var_cache()
{
unset BUILD_VAR_CACHE_READY
+ local v
for v in $cached_vars; do
unset var_cache_$v
done
@@ -89,11 +90,11 @@
{
if [ "$BUILD_VAR_CACHE_READY" = "true" ]
then
- eval echo \"\${abs_var_cache_$1}\"
+ eval "echo \"\${abs_var_cache_$1}\""
return
fi
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
@@ -107,11 +108,11 @@
{
if [ "$BUILD_VAR_CACHE_READY" = "true" ]
then
- eval echo \"\${var_cache_$1}\"
+ eval "echo \"\${var_cache_$1}\""
return
fi
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
@@ -123,7 +124,7 @@
# check to see if the supplied product is one we can build
function check_product()
{
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
@@ -141,6 +142,7 @@
# check to see if the supplied variant is valid
function check_variant()
{
+ local v
for v in ${VARIANT_CHOICES[@]}
do
if [ "$v" = "$1" ]
@@ -153,7 +155,7 @@
function setpaths()
{
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP."
return
@@ -184,18 +186,19 @@
fi
# and in with the new
- prebuiltdir=$(getprebuilt)
- gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS)
+ local prebuiltdir=$(getprebuilt)
+ local gccprebuiltdir=$(get_abs_build_var ANDROID_GCC_PREBUILTS)
# defined in core/config.mk
- targetgccversion=$(get_build_var TARGET_GCC_VERSION)
- targetgccversion2=$(get_build_var 2ND_TARGET_GCC_VERSION)
+ local targetgccversion=$(get_build_var TARGET_GCC_VERSION)
+ local targetgccversion2=$(get_build_var 2ND_TARGET_GCC_VERSION)
export TARGET_GCC_VERSION=$targetgccversion
# The gcc toolchain does not exists for windows/cygwin. In this case, do not reference it.
export ANDROID_TOOLCHAIN=
export ANDROID_TOOLCHAIN_2ND_ARCH=
local ARCH=$(get_build_var TARGET_ARCH)
+ local toolchaindir toolchaindir2=
case $ARCH in
x86) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
;;
@@ -217,7 +220,7 @@
export ANDROID_TOOLCHAIN=$gccprebuiltdir/$toolchaindir
fi
- if [ -d "$gccprebuiltdir/$toolchaindir2" ]; then
+ if [ "$toolchaindir2" -a -d "$gccprebuiltdir/$toolchaindir2" ]; then
export ANDROID_TOOLCHAIN_2ND_ARCH=$gccprebuiltdir/$toolchaindir2
fi
@@ -260,6 +263,12 @@
unset ANDROID_HOST_OUT
export ANDROID_HOST_OUT=$(get_abs_build_var HOST_OUT)
+ unset ANDROID_HOST_OUT_TESTCASES
+ export ANDROID_HOST_OUT_TESTCASES=$(get_abs_build_var HOST_OUT_TESTCASES)
+
+ unset ANDROID_TARGET_OUT_TESTCASES
+ export ANDROID_TARGET_OUT_TESTCASES=$(get_abs_build_var TARGET_OUT_TESTCASES)
+
# needed for building linux on MacOS
# TODO: fix the path
#export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
@@ -267,7 +276,7 @@
function printconfig()
{
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
@@ -290,7 +299,7 @@
function set_sequence_number()
{
- export BUILD_ENV_SEQUENCE_NUMBER=10
+ export BUILD_ENV_SEQUENCE_NUMBER=13
}
function settitle()
@@ -393,6 +402,7 @@
#
function chooseproduct()
{
+ local default_value
if [ "x$TARGET_PRODUCT" != x ] ; then
default_value=$TARGET_PRODUCT
else
@@ -563,50 +573,46 @@
then
selection=${LUNCH_MENU_CHOICES[$(($answer-1))]}
fi
- elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
- then
+ else
selection=$answer
fi
- if [ -z "$selection" ]
- then
- echo
- echo "Invalid lunch combo: $answer"
- return 1
- fi
-
export TARGET_BUILD_APPS=
- local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
- check_variant $variant
- if [ $? -ne 0 ]
- then
- echo
- echo "** Invalid variant: '$variant'"
- echo "** Must be one of ${VARIANT_CHOICES[@]}"
- variant=
+ local product variant_and_version variant version
+
+ product=${selection%%-*} # Trim everything after first dash
+ variant_and_version=${selection#*-} # Trim everything up to first dash
+ if [ "$variant_and_version" != "$selection" ]; then
+ variant=${variant_and_version%%-*}
+ if [ "$variant" != "$variant_and_version" ]; then
+ version=${variant_and_version#*-}
+ fi
fi
- local product=$(echo -n $selection | sed -e "s/-.*$//")
- TARGET_PRODUCT=$product \
- TARGET_BUILD_VARIANT=$variant \
- build_build_var_cache
- if [ $? -ne 0 ]
+ if [ -z "$product" ]
then
echo
- echo "** Don't have a product spec for: '$product'"
- echo "** Do you have the right repo manifest?"
- product=
- fi
-
- if [ -z "$product" -o -z "$variant" ]
- then
- echo
+ echo "Invalid lunch combo: $selection"
return 1
fi
- export TARGET_PRODUCT=$product
- export TARGET_BUILD_VARIANT=$variant
+ TARGET_PRODUCT=$product \
+ TARGET_BUILD_VARIANT=$variant \
+ TARGET_PLATFORM_VERSION=$version \
+ build_build_var_cache
+ if [ $? -ne 0 ]
+ then
+ return 1
+ fi
+
+ export TARGET_PRODUCT=$(get_build_var TARGET_PRODUCT)
+ export TARGET_BUILD_VARIANT=$(get_build_var TARGET_BUILD_VARIANT)
+ if [ -n "$version" ]; then
+ export TARGET_PLATFORM_VERSION=$(get_build_var TARGET_PLATFORM_VERSION)
+ else
+ unset TARGET_PLATFORM_VERSION
+ fi
export TARGET_BUILD_TYPE=release
echo
@@ -696,7 +702,7 @@
PWD= /bin/pwd
else
local HERE=$PWD
- T=
+ local T=
while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
\cd ..
T=`PWD= /bin/pwd -P`
@@ -715,11 +721,18 @@
local T="$1"
test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER
if [ -n "$WITH_STATIC_ANALYZER" ]; then
+ # Use scan-build to collect all static analyzer reports into directory
+ # /tmp/scan-build-yyyy-mm-dd-hhmmss-*
+ # The clang compiler passed by --use-analyzer here is not important.
+ # build/core/binary.mk will set CLANG_CXX and CLANG before calling
+ # c++-analyzer and ccc-analyzer.
+ local CLANG_VERSION=$(get_build_var LLVM_PREBUILTS_VERSION)
+ local BUILD_OS=$(get_build_var BUILD_OS)
+ local CLANG_DIR="$T/prebuilts/clang/host/${BUILD_OS}-x86/${CLANG_VERSION}"
echo "\
-$T/prebuilts/misc/linux-x86/analyzer/tools/scan-build/scan-build \
---use-analyzer $T/prebuilts/misc/linux-x86/analyzer/bin/analyzer \
---status-bugs \
---top=$T"
+${CLANG_DIR}/tools/scan-build/bin/scan-build \
+--use-analyzer ${CLANG_DIR}/bin/clang \
+--status-bugs"
fi
}
@@ -737,12 +750,12 @@
function findmakefile()
{
- TOPFILE=build/core/envsetup.mk
+ local TOPFILE=build/core/envsetup.mk
local HERE=$PWD
- T=
+ local T=
while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
T=`PWD= /bin/pwd`
- if [ -f "$T/Android.mk" ]; then
+ if [ -f "$T/Android.mk" -o -f "$T/Android.bp" ]; then
echo $T/Android.mk
\cd $HERE
return
@@ -775,6 +788,7 @@
echo "Couldn't locate a makefile from the current directory."
return 1
else
+ local ARG
for ARG in $@; do
case $ARG in
GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;;
@@ -782,11 +796,17 @@
done
if [ -n "$GET_INSTALL_PATH" ]; then
MODULES=
- ARGS=GET-INSTALL-PATH
+ ARGS=GET-INSTALL-PATH-IN-$(dirname ${M})
+ ARGS=${ARGS//\//-}
else
- MODULES=all_modules
+ MODULES=MODULES-IN-$(dirname ${M})
+ # Convert "/" to "-".
+ MODULES=${MODULES//\//-}
ARGS=$@
fi
+ if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then
+ MODULES=tidy_only
+ fi
ONE_SHOT_MAKEFILE=$M $DRV make -C $T -f build/core/main.mk $MODULES $ARGS
fi
fi
@@ -799,28 +819,38 @@
if [ "$T" ]; then
local MAKEFILE=
local MODULES=
+ local MODULES_IN_PATHS=
local ARGS=
local DIR TO_CHOP
+ local DIR_MODULES
local GET_INSTALL_PATH=
+ local GET_INSTALL_PATHS=
local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
for DIR in $DIRS ; do
- MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`
- if [ "$MODULES" = "" ]; then
- MODULES=all_modules
- fi
+ DIR_MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`
DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`
- if [ -f $DIR/Android.mk ]; then
+ # Remove the leading ./ and trailing / if any exists.
+ DIR=${DIR#./}
+ DIR=${DIR%/}
+ if [ -f $DIR/Android.mk -o -f $DIR/Android.bp ]; then
local TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '`
local TO_CHOP=`expr $TO_CHOP + 1`
local START=`PWD= /bin/pwd`
- local MFILE=`echo $START | cut -c${TO_CHOP}-`
- if [ "$MFILE" = "" ] ; then
- MFILE=$DIR/Android.mk
+ local MDIR=`echo $START | cut -c${TO_CHOP}-`
+ if [ "$MDIR" = "" ] ; then
+ MDIR=$DIR
else
- MFILE=$MFILE/$DIR/Android.mk
+ MDIR=$MDIR/$DIR
fi
- MAKEFILE="$MAKEFILE $MFILE"
+ MDIR=${MDIR%/.}
+ if [ "$DIR_MODULES" = "" ]; then
+ MODULES_IN_PATHS="$MODULES_IN_PATHS MODULES-IN-$MDIR"
+ GET_INSTALL_PATHS="$GET_INSTALL_PATHS GET-INSTALL-PATH-IN-$MDIR"
+ else
+ MODULES="$MODULES $DIR_MODULES"
+ fi
+ MAKEFILE="$MAKEFILE $MDIR/Android.mk"
else
case $DIR in
showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;
@@ -835,10 +865,17 @@
fi
done
if [ -n "$GET_INSTALL_PATH" ]; then
- ARGS=$GET_INSTALL_PATH
+ ARGS=${GET_INSTALL_PATHS//\//-}
MODULES=
+ MODULES_IN_PATHS=
fi
- ONE_SHOT_MAKEFILE="$MAKEFILE" $DRV make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $ARGS
+ if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then
+ MODULES=tidy_only
+ MODULES_IN_PATHS=
+ fi
+ # Convert "/" to "-".
+ MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
+ ONE_SHOT_MAKEFILE="$MAKEFILE" $DRV make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $MODULES_IN_PATHS $ARGS
else
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
@@ -856,8 +893,10 @@
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
fi
- local MY_PWD=`PWD= /bin/pwd|sed 's:'$T'/::'`
- local MODULES_IN_PATHS=MODULES-IN-$MY_PWD
+ local M=$(findmakefile)
+ # Remove the path to top as the makefilepath needs to be relative
+ local M=`echo $M|sed 's:'$T'/::'`
+ local MODULES_IN_PATHS=MODULES-IN-$(dirname ${M})
# Convert "/" to "-".
MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
$DRV make -C $T -f build/core/main.mk $@ $MODULES_IN_PATHS
@@ -907,9 +946,13 @@
function croot()
{
- T=$(gettop)
+ local T=$(gettop)
if [ "$T" ]; then
- \cd $(gettop)
+ if [ "$1" ]; then
+ \cd $(gettop)/$1
+ else
+ \cd $(gettop)
+ fi
else
echo "Couldn't locate the top of the tree. Try setting TOP."
fi
@@ -917,9 +960,9 @@
function cproj()
{
- TOPFILE=build/core/envsetup.mk
+ local TOPFILE=build/core/envsetup.mk
local HERE=$PWD
- T=
+ local T=
while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
T=$PWD
if [ -f "$T/Android.mk" ]; then
@@ -1022,7 +1065,7 @@
return;
fi;
echo "Setting core limit for $PID to infinite...";
- adb shell prlimit $PID 4 -1 -1
+ adb shell /system/bin/ulimit -p $PID -c unlimited
}
# core - send SIGV and pull the core for process
@@ -1106,8 +1149,7 @@
adb shell cat $TMP
else
# Dump stacks of native process
- local USE64BIT="$(is64bit $PID)"
- adb shell debuggerd$USE64BIT -b $PID
+ adb shell debuggerd -b $PID
fi
fi
}
@@ -1171,6 +1213,7 @@
function resgrep()
{
+ local dir
for dir in `find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -name res -type d`; do
find $dir -type f -name '*\.xml' -exec grep --color -n "$@" {} +
done
@@ -1198,7 +1241,7 @@
Darwin)
function mgrep()
{
- find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk)' \
+ find -E . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -iregex '.*/(Makefile|Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regex '(.*/)?soong/[^/]*.go' \) -type f \
-exec grep --color -n "$@" {} +
}
@@ -1212,7 +1255,7 @@
*)
function mgrep()
{
- find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk)' -type f \
+ find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o \( -regextype posix-egrep -iregex '(.*\/Makefile|.*\/Makefile\..*|.*\.make|.*\.mak|.*\.mk|.*\.bp)' -o -regextype posix-extended -regex '(.*/)?soong/[^/]*.go' \) -type f \
-exec grep --color -n "$@" {} +
}
@@ -1232,7 +1275,7 @@
function tracedmdump()
{
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP."
return
@@ -1409,7 +1452,7 @@
echo "Couldn't locate output files. Try running 'lunch' first." >&2
return
fi
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
@@ -1426,7 +1469,7 @@
# simple shortcut to the runtest command
function runtest()
{
- T=$(gettop)
+ local T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
@@ -1439,7 +1482,8 @@
echo "Usage: godir <regex>"
return
fi
- T=$(gettop)
+ local T=$(gettop)
+ local FILELIST
if [ ! "$OUT_DIR" = "" ]; then
mkdir -p $OUT_DIR
FILELIST=$OUT_DIR/filelist
diff --git a/libs/host/Android.mk b/libs/host/Android.mk
deleted file mode 100644
index bc25e4b..0000000
--- a/libs/host/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- CopyFile.c
-
-LOCAL_CFLAGS := -Werror -Wall
-
-LOCAL_MODULE:= libhost
-LOCAL_MODULE_HOST_OS := darwin linux windows
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_CXX_STL := none
-
-# acp uses libhost, so we can't use
-# acp to install libhost.
-LOCAL_ACP_UNAVAILABLE:= true
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-# Include toolchain prebuilt modules if they exist.
--include $(TARGET_TOOLCHAIN_ROOT)/toolchain.mk
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 02c1c88..ed259db 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -35,6 +35,7 @@
ifeq ($(HOST_OS),linux)
ifeq ($(WITH_DEXPREOPT),)
WITH_DEXPREOPT := true
+ WITH_DEXPREOPT_BOOT_IMG_ONLY := false
endif
endif
diff --git a/target/board/generic/sepolicy/file.te b/target/board/generic/sepolicy/file.te
index 6fad80a..9227f80 100644
--- a/target/board/generic/sepolicy/file.te
+++ b/target/board/generic/sepolicy/file.te
@@ -1 +1,2 @@
type qemud_socket, file_type;
+type sysfs_writable, fs_type, sysfs_type, mlstrustedobject;
diff --git a/target/board/generic/sepolicy/goldfish_setup.te b/target/board/generic/sepolicy/goldfish_setup.te
index b8f121c..a863aa6 100644
--- a/target/board/generic/sepolicy/goldfish_setup.te
+++ b/target/board/generic/sepolicy/goldfish_setup.te
@@ -12,7 +12,9 @@
allow goldfish_setup toolbox_exec:file rx_file_perms;
allow goldfish_setup self:capability { net_admin net_raw };
allow goldfish_setup self:udp_socket create_socket_perms;
+allowxperm goldfish_setup self:udp_socket ioctl priv_sock_ioctls;
+wakelock_use(goldfish_setup)
net_domain(goldfish_setup)
# Set net.eth0.dns*, debug.sf.nobootanimation
diff --git a/target/board/generic/sepolicy/logd.te b/target/board/generic/sepolicy/logd.te
deleted file mode 100644
index b3e60d7..0000000
--- a/target/board/generic/sepolicy/logd.te
+++ /dev/null
@@ -1,11 +0,0 @@
-# goldfish logcat service: runs logcat -Q in logd domain
-
-# See global logd.te, these only set for eng & userdebug, allow for all builds
-
-domain_auto_trans(init, logcat_exec, logd)
-
-# Read from logd.
-read_logd(logd)
-
-# Write to /dev/ttyS2 and /dev/ttyGF2.
-allow logd serial_device:chr_file { write open };
diff --git a/target/board/generic/sepolicy/logpersist.te b/target/board/generic/sepolicy/logpersist.te
new file mode 100644
index 0000000..3fc0250
--- /dev/null
+++ b/target/board/generic/sepolicy/logpersist.te
@@ -0,0 +1,13 @@
+# goldfish logcat service: runs logcat -Q in logpersist domain
+
+# See global logcat.te/logpersist.te, only set for eng & userdebug,
+# allow for all builds in a non-conflicting manner.
+
+domain_auto_trans(init, logcat_exec, logpersist)
+
+# Read from logd.
+unix_socket_connect(logpersist, logdr, logd)
+
+# Write to /dev/ttyS2 and /dev/ttyGF2.
+allow logpersist serial_device:chr_file { write open };
+get_prop(logpersist, qemu_cmdline)
diff --git a/target/board/generic/sepolicy/property.te b/target/board/generic/sepolicy/property.te
index 22d580a..a486702 100644
--- a/target/board/generic/sepolicy/property.te
+++ b/target/board/generic/sepolicy/property.te
@@ -1,3 +1,4 @@
type qemu_prop, property_type;
+type qemu_cmdline, property_type;
type radio_noril_prop, property_type;
type opengles_prop, property_type;
diff --git a/target/board/generic/sepolicy/property_contexts b/target/board/generic/sepolicy/property_contexts
index 142b062..c66a85f 100644
--- a/target/board/generic/sepolicy/property_contexts
+++ b/target/board/generic/sepolicy/property_contexts
@@ -1,4 +1,5 @@
qemu. u:object_r:qemu_prop:s0
+qemu.cmdline u:object_r:qemu_cmdline:s0
ro.emu. u:object_r:qemu_prop:s0
ro.emulator. u:object_r:qemu_prop:s0
ro.radio.noril u:object_r:radio_noril_prop:s0
diff --git a/target/board/generic/sepolicy/qemu_props.te b/target/board/generic/sepolicy/qemu_props.te
index 6768ce7..95174d6 100644
--- a/target/board/generic/sepolicy/qemu_props.te
+++ b/target/board/generic/sepolicy/qemu_props.te
@@ -9,3 +9,4 @@
set_prop(qemu_props, dalvik_prop)
set_prop(qemu_props, config_prop)
set_prop(qemu_props, opengles_prop)
+set_prop(qemu_props, qemu_cmdline)
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 02d0a6f..34fffed 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -65,6 +65,7 @@
ifeq ($(HOST_OS),linux)
ifeq ($(WITH_DEXPREOPT),)
WITH_DEXPREOPT := true
+ WITH_DEXPREOPT_BOOT_IMG_ONLY := false
endif
endif
diff --git a/target/board/generic_mips/BoardConfig.mk b/target/board/generic_mips/BoardConfig.mk
index 1152105..b68d88b 100644
--- a/target/board/generic_mips/BoardConfig.mk
+++ b/target/board/generic_mips/BoardConfig.mk
@@ -42,6 +42,7 @@
ifeq ($(HOST_OS),linux)
ifeq ($(WITH_DEXPREOPT),)
WITH_DEXPREOPT := true
+ WITH_DEXPREOPT_BOOT_IMG_ONLY := false
endif
endif
diff --git a/target/board/generic_mips64/BoardConfig.mk b/target/board/generic_mips64/BoardConfig.mk
index ebc1675..44e6287 100644
--- a/target/board/generic_mips64/BoardConfig.mk
+++ b/target/board/generic_mips64/BoardConfig.mk
@@ -31,7 +31,10 @@
TARGET_2ND_ARCH := mips
ifeq (,$(TARGET_2ND_ARCH_VARIANT))
ifeq ($(TARGET_ARCH_VARIANT),mips64r6)
-TARGET_2ND_ARCH_VARIANT := mips32r6
+# Imgtec builds use 32r6 arch variant with Imgtec-maintained prebuilts/ndk library:
+# TARGET_2ND_ARCH_VARIANT := mips32r6
+# Aosp builds lack full set of mips32r6 NDK prebuilts, so use 32r2 abi:
+TARGET_2ND_ARCH_VARIANT := mips32r2-fp
else
TARGET_2ND_ARCH_VARIANT := mips32r2-fp
endif
@@ -54,6 +57,7 @@
ifeq ($(HOST_OS),linux)
ifeq ($(WITH_DEXPREOPT),)
WITH_DEXPREOPT := true
+ WITH_DEXPREOPT_BOOT_IMG_ONLY := false
endif
endif
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index 50ecb98..f8ac496 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -22,6 +22,7 @@
# of an SDK AVD. Note that this operation only works on Linux for now
ifeq ($(HOST_OS),linux)
WITH_DEXPREOPT ?= true
+WITH_DEXPREOPT_BOOT_IMG_ONLY ?= false
endif
# Build OpenGLES emulation host and guest libraries
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 283e9cc..bd2f987 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -13,7 +13,7 @@
TARGET_2ND_CPU_ABI := x86
TARGET_2ND_ARCH := x86
-TARGET_2ND_ARCH_VARIANT := x86
+TARGET_2ND_ARCH_VARIANT := x86_64
TARGET_USES_64_BIT_BINDER := true
@@ -28,6 +28,7 @@
# of an SDK AVD. Note that this operation only works on Linux for now
ifeq ($(HOST_OS),linux)
WITH_DEXPREOPT ?= true
+WITH_DEXPREOPT_BOOT_IMG_ONLY ?= false
endif
# Build OpenGLES emulation host and guest libraries
diff --git a/target/board/generic_x86_arm/BoardConfig.mk b/target/board/generic_x86_arm/BoardConfig.mk
new file mode 100644
index 0000000..75207fc
--- /dev/null
+++ b/target/board/generic_x86_arm/BoardConfig.mk
@@ -0,0 +1,61 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# 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.
+#
+
+# Configuration for generic_x86 + arm libraries needed by binary translation.
+
+# The generic product target doesn't have any hardware-specific pieces.
+TARGET_NO_BOOTLOADER := true
+TARGET_NO_KERNEL := true
+TARGET_CPU_ABI := x86
+TARGET_ARCH := x86
+TARGET_ARCH_VARIANT := x86
+
+TARGET_2ND_ARCH := arm
+TARGET_2ND_CPU_ABI := armeabi-v7a
+TARGET_2ND_CPU_ABI2 := armeabi
+TARGET_2ND_ARCH_VARIANT := armv7-a
+TARGET_2ND_CPU_VARIANT := generic
+
+# Tell the build system this isn't a typical 64bit+32bit multilib configuration.
+TARGET_TRANSLATE_2ND_ARCH := true
+
+# no hardware camera
+USE_CAMERA_STUB := true
+
+# Enable dex-preoptimization to speed up the first boot sequence
+# of an SDK AVD. Note that this operation only works on Linux for now
+ifeq ($(HOST_OS),linux)
+ ifeq ($(WITH_DEXPREOPT),)
+ WITH_DEXPREOPT := true
+ WITH_DEXPREOPT_BOOT_IMG_ONLY := false
+ endif
+endif
+
+# Build OpenGLES emulation host and guest libraries
+BUILD_EMULATOR_OPENGL := true
+
+# Build and enable the OpenGL ES View renderer. When running on the emulator,
+# the GLES renderer disables itself if host GL acceleration isn't available.
+USE_OPENGL_RENDERER := true
+
+TARGET_USERIMAGES_USE_EXT4 := true
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1879048192 # 1.75 GB
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
+BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
+BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_FLASH_BLOCK_SIZE := 512
+TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+
+BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 69edc72..42447f1 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -53,6 +53,7 @@
$(LOCAL_DIR)/aosp_arm.mk \
$(LOCAL_DIR)/full.mk \
$(LOCAL_DIR)/aosp_x86.mk \
+ $(LOCAL_DIR)/aosp_x86_arm.mk \
$(LOCAL_DIR)/full_x86.mk \
$(LOCAL_DIR)/aosp_mips.mk \
$(LOCAL_DIR)/full_mips.mk \
diff --git a/target/product/aosp_x86_arm.mk b/target/product/aosp_x86_arm.mk
new file mode 100644
index 0000000..85a2cf8
--- /dev/null
+++ b/target/product/aosp_x86_arm.mk
@@ -0,0 +1,42 @@
+#
+# Copyright 2016 The Android Open-Source Project
+#
+# 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.
+#
+
+
+# aosp_x86 with arm libraries needed by binary translation.
+
+include $(SRC_TARGET_DIR)/product/full_x86.mk
+
+# arm libraries. This is the list of shared libraries included in the NDK.
+# Their dependency libraries will be automatically pulled in.
+PRODUCT_PACKAGES += \
+ libandroid_arm \
+ libc_arm \
+ libdl_arm \
+ libEGL_arm \
+ libGLESv1_CM_arm \
+ libGLESv2_arm \
+ libGLESv3_arm \
+ libjnigraphics_arm \
+ liblog_arm \
+ libm_arm \
+ libmediandk_arm \
+ libOpenMAXAL_arm \
+ libstdc++_arm \
+ libOpenSLES_arm \
+ libz_arm \
+
+PRODUCT_NAME := aosp_x86_arm
+PRODUCT_DEVICE := generic_x86_arm
diff --git a/target/product/base.mk b/target/product/base.mk
index 4d70664..a671203 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -129,6 +129,10 @@
vold \
wm
+# Packages included only for eng or userdebug builds, previously debug tagged
+PRODUCT_PACKAGES_DEBUG := \
+ perfprofd \
+ sqlite3
PRODUCT_COPY_FILES := $(call add-to-product-copy-files-if-exists,\
frameworks/base/preloaded-classes:system/etc/preloaded-classes)
diff --git a/target/product/core.mk b/target/product/core.mk
index 0a4e0fd..72a7e8d 100644
--- a/target/product/core.mk
+++ b/target/product/core.mk
@@ -25,6 +25,7 @@
BlockedNumberProvider \
BookmarkProvider \
Browser2 \
+ BuiltInPrintService \
Calendar \
CalendarProvider \
CaptivePortalLogin \
@@ -44,6 +45,7 @@
Launcher2 \
ManagedProvisioning \
MtpDocumentsProvider \
+ NetworkRecommendation \
PicoTts \
PacProcessor \
libpac \
@@ -59,4 +61,11 @@
VpnDialogs \
MmsService
+# The set of packages whose code can be loaded by the system server.
+PRODUCT_SYSTEM_SERVER_APPS += \
+ FusedLocation \
+ InputDevices \
+ KeyChain \
+ Telecom \
+
$(call inherit-product, $(SRC_TARGET_DIR)/product/core_base.mk)
diff --git a/target/product/core_minimal.mk b/target/product/core_minimal.mk
index 009ca52..1cde844 100644
--- a/target/product/core_minimal.mk
+++ b/target/product/core_minimal.mk
@@ -59,7 +59,6 @@
keystore \
keystore.default \
ld.mc \
- libbcc \
libOpenMAXAL \
libOpenSLES \
libdownmix \
@@ -68,11 +67,14 @@
libfilterfw \
libkeystore \
libgatekeeper \
+ libwebviewchromium_loader \
+ libwebviewchromium_plat_support \
libwilhelm \
logd \
make_ext4fs \
e2fsck \
resize2fs \
+ tune2fs \
screencap \
sensorservice \
telephony-common \
@@ -80,6 +82,7 @@
uncrypt \
voip-common \
webview \
+ webview_zygote \
wifi-service
PRODUCT_COPY_FILES += \
@@ -91,7 +94,7 @@
core-libart \
conscrypt \
okhttp \
- core-junit \
+ legacy-test \
bouncycastle \
ext \
framework \
@@ -107,6 +110,11 @@
ethernet-service \
wifi-service
+# The set of packages whose code can be loaded by the system server.
+PRODUCT_SYSTEM_SERVER_APPS += \
+ SettingsProvider \
+ WallpaperBackup
+
# Adoptable external storage supports both ext4 and f2fs
PRODUCT_PACKAGES += \
e2fsck \
@@ -122,26 +130,8 @@
PRODUCT_COPY_FILES += \
system/core/rootdir/etc/public.libraries.android.txt:system/etc/public.libraries.txt
-# Different dexopt types for different package update/install times.
-# On eng builds, make "boot" reasons do pure JIT for faster turnaround.
-ifeq (eng,$(TARGET_BUILD_VARIANT))
- PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
- pm.dexopt.first-boot=verify-at-runtime \
- pm.dexopt.boot=verify-at-runtime
-else
- PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
- pm.dexopt.first-boot=interpret-only \
- pm.dexopt.boot=verify-profile
-endif
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
- pm.dexopt.install=interpret-only \
- pm.dexopt.bg-dexopt=speed-profile \
- pm.dexopt.ab-ota=speed-profile \
- pm.dexopt.nsys-library=speed \
- pm.dexopt.shared-apk=speed \
- pm.dexopt.forced-dexopt=speed \
- pm.dexopt.core-app=speed
-
+PRODUCT_COPY_FILES += \
+ system/core/rootdir/etc/ld.config.txt:system/etc/ld.config.txt
# Enable boot.oat filtering of compiled classes to reduce boot.oat size. b/28026683
PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
diff --git a/target/product/core_tiny.mk b/target/product/core_tiny.mk
index ec2fa41..2fb450d 100644
--- a/target/product/core_tiny.mk
+++ b/target/product/core_tiny.mk
@@ -72,6 +72,7 @@
make_ext4fs \
e2fsck \
resize2fs \
+ tune2fs \
nullwebview \
screencap \
sensorservice \
@@ -88,7 +89,7 @@
core-libart \
conscrypt \
okhttp \
- core-junit \
+ legacy-test \
bouncycastle \
ext \
framework \
@@ -104,6 +105,13 @@
services \
wifi-service
+# The set of packages whose code can be loaded by the system server.
+PRODUCT_SYSTEM_SERVER_APPS += \
+ FusedLocation \
+ InputDevices \
+ SettingsProvider \
+ WallpaperBackup \
+
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
ro.zygote=zygote32
PRODUCT_COPY_FILES += \
@@ -112,26 +120,6 @@
PRODUCT_PROPERTY_OVERRIDES += \
ro.carrier=unknown
-# Different dexopt types for different package update/install times.
-# On eng builds, make "boot" reasons do pure JIT for faster turnaround.
-ifeq (eng,$(TARGET_BUILD_VARIANT))
- PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
- pm.dexopt.first-boot=verify-at-runtime \
- pm.dexopt.boot=verify-at-runtime
-else
- PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
- pm.dexopt.first-boot=interpret-only \
- pm.dexopt.boot=verify-profile
-endif
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
- pm.dexopt.install=interpret-only \
- pm.dexopt.bg-dexopt=speed-profile \
- pm.dexopt.ab-ota=speed-profile \
- pm.dexopt.nsys-library=speed \
- pm.dexopt.shared-apk=speed \
- pm.dexopt.forced-dexopt=speed \
- pm.dexopt.core-app=speed
-
$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/base.mk)
$(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index 55de3b9..e04731c 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -20,18 +20,21 @@
PRODUCT_PACKAGES += \
adb \
adbd \
+ android.hardware.configstore@1.0-service \
+ android.hidl.allocator@1.0-service \
+ android.hidl.memory@1.0-impl \
atrace \
bootanimation \
bootstat \
cmd \
- debuggerd \
+ crash_dump \
+ debuggerd\
dumpstate \
dumpsys \
fastboot \
gralloc.default \
- grep \
- gzip \
healthd \
+ hwservicemanager \
init \
init.environ.rc \
init.rc \
@@ -65,26 +68,34 @@
lmkd \
logcat \
logwrapper \
- mkshrc \
- reboot \
+ lshal \
recovery \
service \
servicemanager \
- sh \
+ shell_and_utilities \
surfaceflinger \
- toolbox \
- toybox \
+ tombstoned \
tzdatacheck \
# SELinux packages
PRODUCT_PACKAGES += \
- sepolicy \
- file_contexts.bin \
- seapp_contexts \
- property_contexts \
- mac_permissions.xml \
- selinux_version \
- service_contexts
+ nonplat_mac_permissions.xml \
+ nonplat_property_contexts \
+ nonplat_seapp_contexts \
+ nonplat_service_contexts \
+ plat_mac_permissions.xml \
+ plat_property_contexts \
+ plat_seapp_contexts \
+ plat_service_contexts \
+ selinux_policy
+
+# AID Generation for
+# <pwd.h> and <grp.h>
+PRODUCT_PACKAGES += \
+ passwd \
+ group \
+ fs_config_files \
+ fs_config_dirs
# Ensure that this property is always defined so that bionic_systrace.cpp
# can rely on it being initially set by init.
@@ -96,3 +107,7 @@
system/core/rootdir/init.usb.configfs.rc:root/init.usb.configfs.rc \
system/core/rootdir/ueventd.rc:root/ueventd.rc \
system/core/rootdir/etc/hosts:system/etc/hosts
+
+# Framework Manifest
+PRODUCT_COPY_FILES += \
+ system/libhidl/manifest.xml:system/manifest.xml
diff --git a/target/product/product_launched_with_l.mk b/target/product/product_launched_with_l.mk
index b86f424..8127bc3 100644
--- a/target/product/product_launched_with_l.mk
+++ b/target/product/product_launched_with_l.mk
@@ -1,2 +1,3 @@
#PRODUCT_SHIPPING_API_LEVEL indicates the first api level, device has been commercially launced on.
PRODUCT_SHIPPING_API_LEVEL := 21
+
diff --git a/target/product/product_launched_with_n_mr1.mk b/target/product/product_launched_with_n_mr1.mk
new file mode 100644
index 0000000..65d4d3f
--- /dev/null
+++ b/target/product/product_launched_with_n_mr1.mk
@@ -0,0 +1,2 @@
+#PRODUCT_SHIPPING_API_LEVEL indicates the first api level, device has been commercially launced on.
+PRODUCT_SHIPPING_API_LEVEL := 25
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 5fd4d7e..a8e0dfa 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -16,41 +16,63 @@
# Provides a functioning ART environment without Android frameworks
+# Minimal boot classpath. This should be a subset of PRODUCT_BOOT_JARS, and equivalent to
+# TARGET_CORE_JARS.
PRODUCT_PACKAGES += \
apache-xml \
- ahat \
bouncycastle \
- cacerts \
- conscrypt \
core-oj \
- core-junit \
core-libart \
- dalvikvm \
- dex2oat \
- dexdeps \
- dexdump \
- dexlist \
- dmtracedump \
- dx \
+ conscrypt \
+ okhttp \
+
+# Additional mixins to the boot classpath.
+PRODUCT_PACKAGES += \
+ legacy-test \
+
+# Why are we pulling in ext, which is frameworks/base, depending on tagsoup and nist-sip?
+PRODUCT_PACKAGES += \
ext \
- hprof-conv \
- libart \
- libart_fake \
- libcrypto \
+
+# Why are we pulling in expat, which is used in frameworks, only, it seem?
+PRODUCT_PACKAGES += \
libexpat \
- libicui18n \
- libicuuc \
+
+# Libcore.
+PRODUCT_PACKAGES += \
libjavacore \
libopenjdk \
libopenjdkjvm \
- libnativehelper \
- libssl \
- libz \
- oatdump \
- okhttp \
+
+# Libcore ICU. TODO: Try to figure out if/why we need them explicitly.
+PRODUCT_PACKAGES += \
+ libicui18n \
+ libicuuc \
+
+# ART.
+PRODUCT_PACKAGES += \
+ dalvikvm \
+ dex2oat \
+ dexoptanalyzer \
+ libart \
+ libart_fake \
+ libopenjdkjvmti \
patchoat \
profman
+# ART/dex helpers.
+PRODUCT_PACKAGES += \
+ ahat \
+ dexdiag \
+ dexdump \
+ dexlist \
+ hprof-conv \
+ oatdump \
+
+# Certificates.
+PRODUCT_PACKAGES += \
+ cacerts \
+
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
dalvik.vm.image-dex2oat-Xms=64m \
dalvik.vm.image-dex2oat-Xmx=64m \
@@ -59,4 +81,26 @@
ro.dalvik.vm.native.bridge=0 \
dalvik.vm.usejit=true \
dalvik.vm.usejitprofiles=true \
+ dalvik.vm.dexopt.secondary=true \
dalvik.vm.appimageformat=lz4
+
+# Different dexopt types for different package update/install times.
+# On eng builds, make "boot" reasons only extract for faster turnaround.
+ifeq (eng,$(TARGET_BUILD_VARIANT))
+ PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+ pm.dexopt.first-boot=extract \
+ pm.dexopt.boot=extract
+else
+ PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+ pm.dexopt.first-boot=quicken \
+ pm.dexopt.boot=verify
+endif
+
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+ pm.dexopt.install=quicken \
+ pm.dexopt.bg-dexopt=speed-profile \
+ pm.dexopt.ab-ota=speed-profile \
+ pm.dexopt.nsys-library=speed \
+ pm.dexopt.shared-apk=speed \
+ pm.dexopt.forced-dexopt=speed \
+ pm.dexopt.core-app=speed
diff --git a/target/product/telephony.mk b/target/product/telephony.mk
index e840ba1..38a8caa 100644
--- a/target/product/telephony.mk
+++ b/target/product/telephony.mk
@@ -19,6 +19,7 @@
PRODUCT_PACKAGES := \
CarrierConfig \
+ CarrierDefaultApp \
Dialer \
CallLogBackup \
CellBroadcastReceiver \
diff --git a/tests/envsetup_tests.sh b/tests/envsetup_tests.sh
new file mode 100755
index 0000000..abdcd56
--- /dev/null
+++ b/tests/envsetup_tests.sh
@@ -0,0 +1,37 @@
+#!/bin/bash -e
+
+source $(dirname $0)/../envsetup.sh
+
+unset TARGET_PRODUCT TARGET_BUILD_VARIANT TARGET_PLATFORM_VERSION
+
+function check_lunch
+(
+ echo lunch $1
+ set +e
+ lunch $1 > /dev/null 2> /dev/null
+ set -e
+ [ "$TARGET_PRODUCT" = "$2" ] || ( echo "lunch $1: expected TARGET_PRODUCT='$2', got '$TARGET_PRODUCT'" && exit 1 )
+ [ "$TARGET_BUILD_VARIANT" = "$3" ] || ( echo "lunch $1: expected TARGET_BUILD_VARIANT='$3', got '$TARGET_BUILD_VARIANT'" && exit 1 )
+ [ "$TARGET_PLATFORM_VERSION" = "$4" ] || ( echo "lunch $1: expected TARGET_PLATFORM_VERSION='$4', got '$TARGET_PLATFORM_VERSION'" && exit 1 )
+)
+
+default_version=$(get_build_var DEFAULT_PLATFORM_VERSION)
+valid_version=PPR1
+
+# lunch tests
+check_lunch "aosp_arm64" "aosp_arm64" "eng" ""
+check_lunch "aosp_arm64-userdebug" "aosp_arm64" "userdebug" ""
+check_lunch "aosp_arm64-userdebug-$default_version" "aosp_arm64" "userdebug" "$default_version"
+check_lunch "aosp_arm64-userdebug-$valid_version" "aosp_arm64" "userdebug" "$valid_version"
+check_lunch "abc" "" "" ""
+check_lunch "aosp_arm64-abc" "" "" ""
+check_lunch "aosp_arm64-userdebug-abc" "" "" ""
+check_lunch "aosp_arm64-abc-$valid_version" "" "" ""
+check_lunch "abc-userdebug-$valid_version" "" "" ""
+check_lunch "-" "" "" ""
+check_lunch "--" "" "" ""
+check_lunch "-userdebug" "" "" ""
+check_lunch "-userdebug-" "" "" ""
+check_lunch "-userdebug-$valid_version" "" "" ""
+check_lunch "aosp_arm64-userdebug-$valid_version-" "" "" ""
+check_lunch "aosp_arm64-userdebug-$valid_version-abc" "" "" ""
diff --git a/tools/acp/Android.bp b/tools/acp/Android.bp
new file mode 100644
index 0000000..faf2034
--- /dev/null
+++ b/tools/acp/Android.bp
@@ -0,0 +1,13 @@
+// Copyright 2005 The Android Open Source Project
+//
+// Custom version of cp.
+
+cc_binary_host {
+
+ srcs: ["acp.c"],
+
+ static_libs: ["libhost"],
+ name: "acp",
+ stl: "none",
+
+}
diff --git a/tools/acp/Android.mk b/tools/acp/Android.mk
deleted file mode 100644
index eec9c9d..0000000
--- a/tools/acp/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2005 The Android Open Source Project
-#
-# Custom version of cp.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- acp.c
-
-LOCAL_STATIC_LIBRARIES := libhost
-LOCAL_MODULE := acp
-LOCAL_ACP_UNAVAILABLE := true
-LOCAL_CXX_STL := none
-
-include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/atree/atree.cpp b/tools/atree/atree.cpp
index b134e01..7deca7e 100644
--- a/tools/atree/atree.cpp
+++ b/tools/atree/atree.cpp
@@ -92,7 +92,7 @@
// Escape the filename so that it can be added to the makefile properly.
static string
-escape_filename(const string name)
+escape_filename(const string& name)
{
ostringstream new_name;
for (string::const_iterator iter = name.begin(); iter != name.end(); ++iter)
diff --git a/tools/brillo-clang-format b/tools/brillo-clang-format
new file mode 100644
index 0000000..a69d9d2
--- /dev/null
+++ b/tools/brillo-clang-format
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# 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.
+#
+
+### DO NOT COPY THIS FILE TO YOUR PROJECT. ###
+
+#
+# This is the .clang-format file used by all Brillo projects, conforming to the
+# style guide defined by Brillo. To use this file create a *relative* symlink in
+# your project pointing to this file, as this repository is expected to be
+# present in all manifests.
+#
+# See go/brillo-c++-style for details about the style guide.
+#
+
+BasedOnStyle: Google
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+BinPackArguments: false
+BinPackParameters: false
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+PointerAlignment: Left
+TabWidth: 2
diff --git a/tools/check_link_type.py b/tools/check_link_type.py
new file mode 100755
index 0000000..40754ad
--- /dev/null
+++ b/tools/check_link_type.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# 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.
+
+"""Utility to verify modules link against acceptable module types"""
+
+from __future__ import print_function
+import argparse
+import os
+import sys
+
+WARNING_MSG = ('\033[1m%(makefile)s: \033[35mwarning:\033[0m\033[1m '
+ '%(module)s (%(type)s) should not link to %(dep_name)s (%(dep_type)s)'
+ '\033[0m')
+ERROR_MSG = ('\033[1m%(makefile)s: \033[31merror:\033[0m\033[1m '
+ '%(module)s (%(type)s) should not link to %(dep_name)s (%(dep_type)s)'
+ '\033[0m')
+
+def parse_args():
+ """Parse commandline arguments."""
+ parser = argparse.ArgumentParser(description='Check link types')
+ parser.add_argument('--makefile', help='Makefile defining module')
+ parser.add_argument('--module', help='The module being checked')
+ parser.add_argument('--type', help='The link type of module')
+ parser.add_argument('--allowed', help='Allow deps to use these types',
+ action='append', default=[], metavar='TYPE')
+ parser.add_argument('--warn', help='Warn if deps use these types',
+ action='append', default=[], metavar='TYPE')
+ parser.add_argument('deps', help='The dependencies to check',
+ metavar='DEP', nargs='*')
+ return parser.parse_args()
+
+def print_msg(msg, args, dep_name, dep_type):
+ """Print a warning or error message"""
+ print(msg % {
+ "makefile": args.makefile,
+ "module": args.module,
+ "type": args.type,
+ "dep_name": dep_name,
+ "dep_type": dep_type}, file=sys.stderr)
+
+def main():
+ """Program entry point."""
+ args = parse_args()
+
+ failed = False
+ for dep in args.deps:
+ dep_name = os.path.basename(os.path.dirname(dep))
+ if dep_name.endswith('_intermediates'):
+ dep_name = dep_name[:len(dep_name)-len('_intermediates')]
+
+ with open(dep, 'r') as dep_file:
+ dep_types = dep_file.read().strip().split(' ')
+
+ for dep_type in dep_types:
+ if dep_type in args.allowed:
+ continue
+ if dep_type in args.warn:
+ print_msg(WARNING_MSG, args, dep_name, dep_type)
+ else:
+ print_msg(ERROR_MSG, args, dep_name, dep_type)
+ failed = True
+
+ if failed:
+ sys.exit(1)
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/checkowners.py b/tools/checkowners.py
new file mode 100755
index 0000000..b874955
--- /dev/null
+++ b/tools/checkowners.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+"""Parse and check syntax errors of a given OWNERS file."""
+
+import argparse
+import re
+import sys
+import urllib
+import urllib2
+
+parser = argparse.ArgumentParser(description='Check OWNERS file syntax')
+parser.add_argument('-v', '--verbose', dest='verbose',
+ action='store_true', default=False,
+ help='Verbose output to debug')
+parser.add_argument('-c', '--check_address', dest='check_address',
+ action='store_true', default=False,
+ help='Check email addresses')
+parser.add_argument(dest='owners', metavar='OWNERS', nargs='+',
+ help='Path to OWNERS file')
+args = parser.parse_args()
+
+gerrit_server = 'https://android-review.googlesource.com'
+checked_addresses = {}
+
+
+def echo(msg):
+ if args.verbose:
+ print msg
+
+
+def find_address(address):
+ if address not in checked_addresses:
+ request = (gerrit_server + '/accounts/?n=1&o=ALL_EMAILS&q=email:'
+ + urllib.quote(address))
+ echo('Checking email address: ' + address)
+ result = urllib2.urlopen(request).read()
+ expected = '"email": "' + address + '"'
+ checked_addresses[address] = (result.find(expected) >= 0)
+ return checked_addresses[address]
+
+
+def main():
+ # One regular expression to check all valid lines.
+ noparent = 'set +noparent'
+ email = '([^@ ]+@[^ @]+|\\*)'
+ directive = '(%s|%s)' % (email, noparent)
+ glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
+ perfile = 'per-file +' + glob + ' *= *' + directive
+ pats = '(|%s|%s|%s)$' % (noparent, email, perfile)
+ patterns = re.compile(pats)
+
+ # One pattern to capture email address.
+ email_address = '.*(@| |=|^)([^@ =]+@[^ @]+)'
+ address_pattern = re.compile(email_address)
+
+ error = 0
+ for fname in args.owners:
+ echo('Checking file: ' + fname)
+ num = 0
+ for line in open(fname, 'r'):
+ num += 1
+ stripped_line = re.sub('#.*$', '', line).strip()
+ if not patterns.match(stripped_line):
+ error = 1
+ print('%s:%d: ERROR: unknown line [%s]'
+ % (fname, num, line.strip()))
+ elif args.check_address and address_pattern.match(stripped_line):
+ address = address_pattern.match(stripped_line).group(2)
+ if find_address(address):
+ echo('Found email address: ' + address)
+ else:
+ error = 1
+ print('%s:%d: ERROR: unknown email address: %s'
+ % (fname, num, address))
+ sys.exit(error)
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/diff_package_overlays.py b/tools/diff_package_overlays.py
deleted file mode 100755
index 0e2c773..0000000
--- a/tools/diff_package_overlays.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# 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.
-
-"""
-Prints to stdout the package names that have overlay changes between
-current_overlays.txt and previous_overlays.txt.
-
-Usage: diff_package_overlays.py <current_packages.txt> <current_overlays.txt> <previous_overlays.txt>
-current_packages.txt contains all package names separated by space in the current build.
-This script modfies current_packages.txt if necessary: if there is a package in
-previous_overlays.txt but absent from current_packages.txt, we copy that line
-from previous_overlays.txt over to current_packages.txt. Usually that means we
-just don't care that package in the current build (for example we are switching
-from a full build to a partial build with mm/mmm), and we should carry on the
-previous overlay config so current_overlays.txt always reflects the current
-status of the entire tree.
-
-Format of current_overlays.txt and previous_overlays.txt:
- <package_name> <resource_overlay> [resource_overlay ...]
- <package_name> <resource_overlay> [resource_overlay ...]
- ...
-"""
-
-import sys
-
-def main(argv):
- if len(argv) != 4:
- print >> sys.stderr, __doc__
- sys.exit(1)
-
- f = open(argv[1])
- all_packages = set(f.read().split())
- f.close()
-
- def load_overlay_config(filename):
- f = open(filename)
- result = {}
- for line in f:
- line = line.strip()
- if not line or line.startswith("#"):
- continue
- words = line.split()
- result[words[0]] = " ".join(words[1:])
- f.close()
- return result
-
- current_overlays = load_overlay_config(argv[2])
- previous_overlays = load_overlay_config(argv[3])
-
- result = []
- carryon = []
- for p in current_overlays:
- if p not in previous_overlays:
- result.append(p)
- elif current_overlays[p] != previous_overlays[p]:
- result.append(p)
- for p in previous_overlays:
- if p not in current_overlays:
- if p in all_packages:
- # overlay changed
- result.append(p)
- else:
- # we don't build p in the current build.
- carryon.append(p)
-
- # Add carryon to the current overlay config file.
- if carryon:
- f = open(argv[2], "a")
- for p in carryon:
- f.write(p + " " + previous_overlays[p] + "\n")
- f.close()
-
- # Print out the package names that have overlay change.
- for r in result:
- print r
-
-if __name__ == "__main__":
- main(sys.argv)
diff --git a/tools/droiddoc/templates-ndk/customizations.cs b/tools/droiddoc/templates-ndk/customizations.cs
index 0c640de..808bc81 100644
--- a/tools/droiddoc/templates-ndk/customizations.cs
+++ b/tools/droiddoc/templates-ndk/customizations.cs
@@ -9,7 +9,7 @@
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
</div>
@@ -25,7 +25,7 @@
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
</div>
@@ -43,7 +43,7 @@
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html-ndk/ndk/guides/guides_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html-ndk/ndk/guides/guides_toc.cs" ?>
</div>
@@ -62,7 +62,7 @@
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html-ndk/ndk/reference/reference_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html-ndk/ndk/reference/reference_toc.cs" ?>
</div>
@@ -81,7 +81,7 @@
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html-ndk/ndk/samples/samples_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html-ndk/ndk/samples/samples_toc.cs" ?>
</div>
@@ -100,7 +100,7 @@
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html-ndk/ndk/downloads/downloads_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html-ndk/ndk/downloads/downloads_toc.cs" ?>
</div>
@@ -120,7 +120,7 @@
<?cs
- include:"../../../../frameworks/base/docs/html/training/training_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/training/training_toc.cs" ?>
</div>
@@ -136,7 +136,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/googleplay/googleplay_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/googleplay/googleplay_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -150,7 +150,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/essentials/essentials_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/essentials/essentials_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -164,7 +164,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/users/users_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/users/users_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -178,7 +178,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/engage/engage_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/engage/engage_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -192,7 +192,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/analyze/analyze_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/analyze/analyze_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -206,7 +206,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/monetize/monetize_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/monetize/monetize_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -220,7 +220,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/tools/disttools_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/tools/disttools_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -234,7 +234,7 @@
<div class="wrap clearfix" id="body-content">
<div class="col-3" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
-<?cs include:"../../../../frameworks/base/docs/html/distribute/stories/stories_toc.cs" ?>
+<?cs include:"../../../../../frameworks/base/docs/html/distribute/stories/stories_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -250,7 +250,7 @@
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
</div>
@@ -269,7 +269,7 @@
<?cs
- include:"../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
</div>
@@ -287,7 +287,7 @@
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/distribute/distribute_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/distribute/distribute_toc.cs" ?>
</div>
@@ -306,7 +306,7 @@
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
</div>
@@ -325,7 +325,7 @@
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
</div>
@@ -348,7 +348,7 @@
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
</div>
@@ -368,7 +368,7 @@
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/wear/wear_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/wear/wear_toc.cs" ?>
</div>
@@ -386,7 +386,7 @@
<div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav" class="scroll-pane">
<?cs
- include:"../../../../frameworks/base/docs/html/preview/preview_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/preview/preview_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
diff --git a/tools/droiddoc/templates-pdk/customizations.cs b/tools/droiddoc/templates-pdk/customizations.cs
index e4fbbb9..15f67ea 100644
--- a/tools/droiddoc/templates-pdk/customizations.cs
+++ b/tools/droiddoc/templates-pdk/customizations.cs
@@ -3,7 +3,7 @@
<div class="g-section g-tpl-240" id="body-content">
<div class="g-unit g-first" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav"><?cs
- include:"../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<?cs /def ?>
@@ -12,7 +12,7 @@
<div class="g-section g-tpl-240" id="body-content">
<div class="g-unit g-first" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav"><?cs
- include:"../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -26,7 +26,7 @@
<div class="g-section g-tpl-240" id="body-content">
<div class="g-unit g-first" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
<div id="devdoc-nav"><?cs
- include:"../../../../vendor/pdk/data/google/docs/guide/guide_toc.cs" ?>
+ include:"../../../../../vendor/pdk/data/google/docs/guide/guide_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
<script>
@@ -37,7 +37,7 @@
<?cs /def ?>
<?cs
def:design_nav() ?>
- <?cs include:"../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
<?cs /def ?>
<?cs # The default side navigation for the reference docs ?><?cs
diff --git a/tools/droiddoc/templates-sac/assets/css/default.css b/tools/droiddoc/templates-sac/assets/css/default.css
index 9b1fe5a..4eafa25 100644
--- a/tools/droiddoc/templates-sac/assets/css/default.css
+++ b/tools/droiddoc/templates-sac/assets/css/default.css
@@ -122,6 +122,10 @@
padding-right:16px;
}
+.nowrap {
+ white-space: nowrap;
+}
+
img {
border: none; }
#jd-content img {
diff --git a/tools/droiddoc/templates-sac/customizations.cs b/tools/droiddoc/templates-sac/customizations.cs
index 1120e70..01d3d72 100644
--- a/tools/droiddoc/templates-sac/customizations.cs
+++ b/tools/droiddoc/templates-sac/customizations.cs
@@ -10,7 +10,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
</div>
@@ -25,7 +25,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
</div>
@@ -43,7 +43,7 @@
<div id="devdoc-nav" class="scroll-pane">
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
</div>
@@ -63,7 +63,7 @@
<?cs
- include:"../../../../frameworks/base/docs/html/training/training_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/training/training_toc.cs" ?>
</div>
@@ -83,7 +83,7 @@
<?cs
- include:"../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
</div>
@@ -103,7 +103,7 @@
<?cs
- include:"../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
</div>
@@ -122,7 +122,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../frameworks/base/docs/html/distribute/distribute_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/distribute/distribute_toc.cs" ?>
</div>
@@ -142,7 +142,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
</div>
@@ -166,7 +166,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
</div>
@@ -186,7 +186,7 @@
<?cs
- include:"../../../../frameworks/base/docs/html/distribute/more/more_toc.cs" ?>
+ include:"../../../../../frameworks/base/docs/html/distribute/more/more_toc.cs" ?>
</div>
@@ -397,7 +397,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../docs/source.android.com/src/devices/devices_toc.cs" ?>
+ include:"../../../../../docs/source.android.com/src/devices/devices_toc.cs" ?>
</div>
<script type="text/javascript">
@@ -419,7 +419,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../docs/source.android.com/src/compatibility/compatibility_toc.cs" ?>
+ include:"../../../../../docs/source.android.com/src/compatibility/compatibility_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
@@ -438,7 +438,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../docs/source.android.com/src/source/source_toc.cs" ?>
+ include:"../../../../../docs/source.android.com/src/source/source_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
@@ -457,7 +457,7 @@
<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
<?cs
- include:"../../../../docs/source.android.com/src/security/security_toc.cs" ?>
+ include:"../../../../../docs/source.android.com/src/security/security_toc.cs" ?>
</div>
</div> <!-- end side-nav -->
diff --git a/tools/droiddoc/templates-sdk/customizations.cs b/tools/droiddoc/templates-sdk/customizations.cs
index 0b938ac..123ab32 100644
--- a/tools/droiddoc/templates-sdk/customizations.cs
+++ b/tools/droiddoc/templates-sdk/customizations.cs
@@ -18,7 +18,7 @@
<!-- End: Fullscreen toggler -->
<?cs if:reference.gcm || reference.gms ?>
- <?cs include:"../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
<script type="text/javascript">
showGoogleRefTree();
</script>
@@ -82,10 +82,10 @@
<div class="dac-toggle-content" id="devdoc-nav">
<div class="scroll-pane">
<?cs
-if:guide ?><?cs include:"../../../../frameworks/base/docs/html/ndk/guides/guides_toc.cs" ?><?cs
-elif:reference ?><?cs include:"../../../../frameworks/base/docs/html/ndk/reference/reference_toc.cs" ?><?cs
-elif:downloads ?><?cs include:"../../../../frameworks/base/docs/html/ndk/downloads/downloads_toc.cs" ?><?cs
-elif:samples ?><?cs include:"../../../../frameworks/base/docs/html/ndk/samples/samples_toc.cs" ?><?cs
+if:guide ?><?cs include:"../../../../../frameworks/base/docs/html/ndk/guides/guides_toc.cs" ?><?cs
+elif:reference ?><?cs include:"../../../../../frameworks/base/docs/html/ndk/reference/reference_toc.cs" ?><?cs
+elif:downloads ?><?cs include:"../../../../../frameworks/base/docs/html/ndk/downloads/downloads_toc.cs" ?><?cs
+elif:samples ?><?cs include:"../../../../../frameworks/base/docs/html/ndk/samples/samples_toc.cs" ?><?cs
/if ?>
</div>
</div>
@@ -161,52 +161,52 @@
if:referenceonly ?>style="top:0 !important;"<?cs /if ?>>
<?cs if:ndk ?>
<?cs if:guide ?>
- <?cs include:"../../../../frameworks/base/docs/html/ndk/guides/guides_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/ndk/guides/guides_toc.cs" ?>
<?cs elif:reference ?>
- <?cs include:"../../../../frameworks/base/docs/html/ndk/reference/reference_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/ndk/reference/reference_toc.cs" ?>
<?cs elif:downloads ?>
- <?cs include:"../../../../frameworks/base/docs/html/ndk/downloads/downloads_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/ndk/downloads/downloads_toc.cs" ?>
<?cs elif:samples ?>
- <?cs include:"../../../../frameworks/base/docs/html/ndk/samples/samples_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/ndk/samples/samples_toc.cs" ?>
<?cs else ?>
<?cs call:reference_default_nav() ?>
<?cs /if ?>
<?cs elif:guide ?>
- <?cs include:"../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
<?cs elif:design ?>
- <?cs include:"../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/design/design_toc.cs" ?>
<?cs elif:training ?>
- <?cs include:"../../../../frameworks/base/docs/html/training/training_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/training/training_toc.cs" ?>
<?cs elif:tools ?>
- <?cs include:"../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/tools/tools_toc.cs" ?>
<?cs elif:google ?>
- <?cs include:"../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/google/google_toc.cs" ?>
<?cs elif:samples ?>
- <?cs include:"../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/samples/samples_toc.cs" ?>
<?cs elif:preview ?>
- <?cs include:"../../../../frameworks/base/docs/html/preview/preview_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/preview/preview_toc.cs" ?>
<?cs elif:preview ?>
- <?cs include:"../../../../frameworks/base/docs/html/wear/preview/preview_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/wear/preview/preview_toc.cs" ?>
<?cs elif:distribute ?>
<?cs if:googleplay ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/googleplay/googleplay_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/googleplay/googleplay_toc.cs" ?>
<?cs elif:essentials ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/essentials/essentials_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/essentials/essentials_toc.cs" ?>
<?cs elif:users ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/users/users_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/users/users_toc.cs" ?>
<?cs elif:engage ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/engage/engage_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/engage/engage_toc.cs" ?>
<?cs elif:monetize ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/monetize/monetize_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/monetize/monetize_toc.cs" ?>
<?cs elif:analyze ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/analyze/analyze_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/analyze/analyze_toc.cs" ?>
<?cs elif:disttools ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/tools/disttools_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/tools/disttools_toc.cs" ?>
<?cs elif:stories ?>
- <?cs include:"../../../../frameworks/base/docs/html/distribute/stories/stories_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/distribute/stories/stories_toc.cs" ?>
<?cs /if ?>
<?cs elif:about ?>
- <?cs include:"../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
+ <?cs include:"../../../../../frameworks/base/docs/html/about/about_toc.cs" ?>
<?cs else ?>
<?cs call:reference_default_nav() ?>
<?cs /if ?>
@@ -245,4 +245,4 @@
<?cs /if ?>
<script src="<?cs var:toroot ?>timestamp.js" type="text/javascript"></script>
<script>document.write(BUILD_TIMESTAMP)</script>
-<?cs /def ?>
\ No newline at end of file
+<?cs /def ?>
diff --git a/tools/fat16copy.py b/tools/fat16copy.py
new file mode 100755
index 0000000..c20930a
--- /dev/null
+++ b/tools/fat16copy.py
@@ -0,0 +1,776 @@
+#!/usr/bin/env python
+#
+# Copyright 2016 The Android Open Source Project
+#
+# 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.
+
+import os
+import sys
+import struct
+
+FAT_TABLE_START = 0x200
+DEL_MARKER = 0xe5
+ESCAPE_DEL_MARKER = 0x05
+
+ATTRIBUTE_READ_ONLY = 0x1
+ATTRIBUTE_HIDDEN = 0x2
+ATTRIBUTE_SYSTEM = 0x4
+ATTRIBUTE_VOLUME_LABEL = 0x8
+ATTRIBUTE_SUBDIRECTORY = 0x10
+ATTRIBUTE_ARCHIVE = 0x20
+ATTRIBUTE_DEVICE = 0x40
+
+LFN_ATTRIBUTES = \
+ ATTRIBUTE_VOLUME_LABEL | \
+ ATTRIBUTE_SYSTEM | \
+ ATTRIBUTE_HIDDEN | \
+ ATTRIBUTE_READ_ONLY
+LFN_ATTRIBUTES_BYTE = struct.pack("B", LFN_ATTRIBUTES)
+
+MAX_CLUSTER_ID = 0x7FFF
+
+def read_le_short(f):
+ "Read a little-endian 2-byte integer from the given file-like object"
+ return struct.unpack("<H", f.read(2))[0]
+
+def read_le_long(f):
+ "Read a little-endian 4-byte integer from the given file-like object"
+ return struct.unpack("<L", f.read(4))[0]
+
+def read_byte(f):
+ "Read a 1-byte integer from the given file-like object"
+ return struct.unpack("B", f.read(1))[0]
+
+def skip_bytes(f, n):
+ "Fast-forward the given file-like object by n bytes"
+ f.seek(n, os.SEEK_CUR)
+
+def skip_short(f):
+ "Fast-forward the given file-like object 2 bytes"
+ skip_bytes(f, 2)
+
+def skip_byte(f):
+ "Fast-forward the given file-like object 1 byte"
+ skip_bytes(f, 1)
+
+def rewind_bytes(f, n):
+ "Rewind the given file-like object n bytes"
+ skip_bytes(f, -n)
+
+def rewind_short(f):
+ "Rewind the given file-like object 2 bytes"
+ rewind_bytes(f, 2)
+
+class fake_file(object):
+ """
+ Interface for python file-like objects that we use to manipulate the image.
+ Inheritors must have an idx member which indicates the file pointer, and a
+ size member which indicates the total file size.
+ """
+
+ def seek(self, amount, direction=0):
+ "Implementation of seek from python's file-like object interface."
+ if direction == os.SEEK_CUR:
+ self.idx += amount
+ elif direction == os.SEEK_END:
+ self.idx = self.size - amount
+ else:
+ self.idx = amount
+
+ if self.idx < 0:
+ self.idx = 0
+ if self.idx > self.size:
+ self.idx = self.size
+
+class fat_file(fake_file):
+ """
+ A file inside of our fat image. The file may or may not have a dentry, and
+ if it does this object knows nothing about it. All we see is a valid cluster
+ chain.
+ """
+
+ def __init__(self, fs, cluster, size=None):
+ """
+ fs: The fat() object for the image this file resides in.
+ cluster: The first cluster of data for this file.
+ size: The size of this file. If not given, we use the total length of the
+ cluster chain that starts from the cluster argument.
+ """
+ self.fs = fs
+ self.start_cluster = cluster
+ self.size = size
+
+ if self.size is None:
+ self.size = fs.get_chain_size(cluster)
+
+ self.idx = 0
+
+ def read(self, size):
+ "Read method for pythonic file-like interface."
+ if self.idx + size > self.size:
+ size = self.size - self.idx
+ got = self.fs.read_file(self.start_cluster, self.idx, size)
+ self.idx += len(got)
+ return got
+
+ def write(self, data):
+ "Write method for pythonic file-like interface."
+ self.fs.write_file(self.start_cluster, self.idx, data)
+ self.idx += len(data)
+
+ if self.idx > self.size:
+ self.size = self.idx
+
+def shorten(name, index):
+ """
+ Create a file short name from the given long name (with the extension already
+ removed). The index argument gives a disambiguating integer to work into the
+ name to avoid collisions.
+ """
+ name = "".join(name.split('.')).upper()
+ postfix = "~" + str(index)
+ return name[:8 - len(postfix)] + postfix
+
+class fat_dir(object):
+ "A directory in our fat filesystem."
+
+ def __init__(self, backing):
+ """
+ backing: A file-like object from which we can read dentry info. Should have
+ an fs member allowing us to get to the underlying image.
+ """
+ self.backing = backing
+ self.dentries = []
+ to_read = self.backing.size / 32
+
+ self.backing.seek(0)
+
+ while to_read > 0:
+ (dent, consumed) = self.backing.fs.read_dentry(self.backing)
+ to_read -= consumed
+
+ if dent:
+ self.dentries.append(dent)
+
+ def __str__(self):
+ return "\n".join([str(x) for x in self.dentries]) + "\n"
+
+ def add_dentry(self, attributes, shortname, ext, longname, first_cluster,
+ size):
+ """
+ Add a new dentry to this directory.
+ attributes: Attribute flags for this dentry. See the ATTRIBUTE_ constants
+ above.
+ shortname: Short name of this file. Up to 8 characters, no dots.
+ ext: Extension for this file. Up to 3 characters, no dots.
+ longname: The long name for this file, with extension. Largely unrestricted.
+ first_cluster: The first cluster in the cluster chain holding the contents
+ of this file.
+ size: The size of this file. Set to 0 for subdirectories.
+ """
+ new_dentry = dentry(self.backing.fs, attributes, shortname, ext,
+ longname, first_cluster, size)
+ new_dentry.commit(self.backing)
+ self.dentries.append(new_dentry)
+ return new_dentry
+
+ def make_short_name(self, name):
+ """
+ Given a long file name, return an 8.3 short name as a tuple. Name will be
+ engineered not to collide with other such names in this folder.
+ """
+ parts = name.rsplit('.', 1)
+
+ if len(parts) == 1:
+ parts.append('')
+
+ name = parts[0]
+ ext = parts[1].upper()
+
+ index = 1
+ shortened = shorten(name, index)
+
+ for dent in self.dentries:
+ assert dent.longname != name, "File must not exist"
+ if dent.shortname == shortened:
+ index += 1
+ shortened = shorten(name, index)
+
+ if len(name) <= 8 and len(ext) <= 3 and not '.' in name:
+ return (name.upper().ljust(8), ext.ljust(3))
+
+ return (shortened.ljust(8), ext[:3].ljust(3))
+
+ def new_file(self, name, data=None):
+ """
+ Add a new regular file to this directory.
+ name: The name of the new file.
+ data: The contents of the new file. Given as a file-like object.
+ """
+ size = 0
+ if data:
+ data.seek(0, os.SEEK_END)
+ size = data.tell()
+
+ # Empty files shouldn't have any clusters assigned.
+ chunk = self.backing.fs.allocate(size) if size > 0 else 0
+ (shortname, ext) = self.make_short_name(name)
+ self.add_dentry(0, shortname, ext, name, chunk, size)
+
+ if data is None:
+ return
+
+ data_file = fat_file(self.backing.fs, chunk, size)
+ data.seek(0)
+ data_file.write(data.read())
+
+ def open_subdirectory(self, name):
+ """
+ Open a subdirectory of this directory with the given name. If the
+ subdirectory doesn't exist, a new one is created instead.
+ Returns a fat_dir().
+ """
+ for dent in self.dentries:
+ if dent.longname == name:
+ return dent.open_directory()
+
+ chunk = self.backing.fs.allocate(1)
+ (shortname, ext) = self.make_short_name(name)
+ new_dentry = self.add_dentry(ATTRIBUTE_SUBDIRECTORY, shortname,
+ ext, name, chunk, 0)
+ result = new_dentry.open_directory()
+
+ parent_cluster = 0
+
+ if hasattr(self.backing, 'start_cluster'):
+ parent_cluster = self.backing.start_cluster
+
+ result.add_dentry(ATTRIBUTE_SUBDIRECTORY, '.', '', '', chunk, 0)
+ result.add_dentry(ATTRIBUTE_SUBDIRECTORY, '..', '', '', parent_cluster, 0)
+
+ return result
+
+def lfn_checksum(name_data):
+ """
+ Given the characters of an 8.3 file name (concatenated *without* the dot),
+ Compute a one-byte checksum which needs to appear in corresponding long file
+ name entries.
+ """
+ assert len(name_data) == 11, "Name data should be exactly 11 characters"
+ name_data = struct.unpack("B" * 11, name_data)
+
+ result = 0
+
+ for char in name_data:
+ last_bit = (result & 1) << 7
+ result = (result >> 1) | last_bit
+ result += char
+ result = result & 0xFF
+
+ return struct.pack("B", result)
+
+class dentry(object):
+ "A directory entry"
+ def __init__(self, fs, attributes, shortname, ext, longname,
+ first_cluster, size):
+ """
+ fs: The fat() object for the image we're stored in.
+ attributes: The attribute flags for this dentry. See the ATTRIBUTE_ flags
+ above.
+ shortname: The short name stored in this dentry. Up to 8 characters, no
+ dots.
+ ext: The file extension stored in this dentry. Up to 3 characters, no
+ dots.
+ longname: The long file name stored in this dentry.
+ first_cluster: The first cluster in the cluster chain backing the file
+ this dentry points to.
+ size: Size of the file this dentry points to. 0 for subdirectories.
+ """
+ self.fs = fs
+ self.attributes = attributes
+ self.shortname = shortname
+ self.ext = ext
+ self.longname = longname
+ self.first_cluster = first_cluster
+ self.size = size
+
+ def name(self):
+ "A friendly text file name for this dentry."
+ if self.longname:
+ return self.longname
+
+ if not self.ext or len(self.ext) == 0:
+ return self.shortname
+
+ return self.shortname + "." + self.ext
+
+ def __str__(self):
+ return self.name() + " (" + str(self.size) + \
+ " bytes @ " + str(self.first_cluster) + ")"
+
+ def is_directory(self):
+ "Return whether this dentry points to a directory."
+ return (self.attributes & ATTRIBUTE_SUBDIRECTORY) != 0
+
+ def open_file(self):
+ "Open the target of this dentry if it is a regular file."
+ assert not self.is_directory(), "Cannot open directory as file"
+ return fat_file(self.fs, self.first_cluster, self.size)
+
+ def open_directory(self):
+ "Open the target of this dentry if it is a directory."
+ assert self.is_directory(), "Cannot open file as directory"
+ return fat_dir(fat_file(self.fs, self.first_cluster))
+
+ def longname_records(self, checksum):
+ """
+ Get the longname records necessary to store this dentry's long name,
+ packed as a series of 32-byte strings.
+ """
+ if self.longname is None:
+ return []
+ if len(self.longname) == 0:
+ return []
+
+ encoded_long_name = self.longname.encode('utf-16-le')
+ long_name_padding = "\0" * (26 - (len(encoded_long_name) % 26))
+ padded_long_name = encoded_long_name + long_name_padding
+
+ chunks = [padded_long_name[i:i+26] for i in range(0,
+ len(padded_long_name), 26)]
+ records = []
+ sequence_number = 1
+
+ for c in chunks:
+ sequence_byte = struct.pack("B", sequence_number)
+ sequence_number += 1
+ record = sequence_byte + c[:10] + LFN_ATTRIBUTES_BYTE + "\0" + \
+ checksum + c[10:22] + "\0\0" + c[22:]
+ records.append(record)
+
+ last = records.pop()
+ last_seq = struct.unpack("B", last[0])[0]
+ last_seq = last_seq | 0x40
+ last = struct.pack("B", last_seq) + last[1:]
+ records.append(last)
+ records.reverse()
+
+ return records
+
+ def commit(self, f):
+ """
+ Write this dentry into the given file-like object,
+ which is assumed to contain a FAT directory.
+ """
+ f.seek(0)
+ padded_short_name = self.shortname.ljust(8)
+ padded_ext = self.ext.ljust(3)
+ name_data = padded_short_name + padded_ext
+ longname_record_data = self.longname_records(lfn_checksum(name_data))
+ record = struct.pack("<11sBBBHHHHHHHL",
+ name_data,
+ self.attributes,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ self.first_cluster,
+ self.size)
+ entry = "".join(longname_record_data + [record])
+
+ record_count = len(longname_record_data) + 1
+
+ found_count = 0
+ while found_count < record_count:
+ record = f.read(32)
+
+ if record is None or len(record) != 32:
+ # We reached the EOF, so we need to extend the file with a new cluster.
+ f.write("\0" * self.fs.bytes_per_cluster)
+ f.seek(-self.fs.bytes_per_cluster, os.SEEK_CUR)
+ record = f.read(32)
+
+ marker = struct.unpack("B", record[0])[0]
+
+ if marker == DEL_MARKER or marker == 0:
+ found_count += 1
+ else:
+ found_count = 0
+
+ f.seek(-(record_count * 32), os.SEEK_CUR)
+ f.write(entry)
+
+class root_dentry_file(fake_file):
+ """
+ File-like object for the root directory. The root directory isn't stored in a
+ normal file, so we can't use a normal fat_file object to create a view of it.
+ """
+ def __init__(self, fs):
+ self.fs = fs
+ self.idx = 0
+ self.size = fs.root_entries * 32
+
+ def read(self, count):
+ f = self.fs.f
+ f.seek(self.fs.data_start() + self.idx)
+
+ if self.idx + count > self.size:
+ count = self.size - self.idx
+
+ ret = f.read(count)
+ self.idx += len(ret)
+ return ret
+
+ def write(self, data):
+ f = self.fs.f
+ f.seek(self.fs.data_start() + self.idx)
+
+ if self.idx + len(data) > self.size:
+ data = data[:self.size - self.idx]
+
+ f.write(data)
+ self.idx += len(data)
+ if self.idx > self.size:
+ self.size = self.idx
+
+class fat(object):
+ "A FAT image"
+
+ def __init__(self, path):
+ """
+ path: Path to an image file containing a FAT file system.
+ """
+ f = open(path, "r+b")
+
+ self.f = f
+
+ f.seek(0xb)
+ bytes_per_sector = read_le_short(f)
+ sectors_per_cluster = read_byte(f)
+
+ self.bytes_per_cluster = bytes_per_sector * sectors_per_cluster
+
+ reserved_sectors = read_le_short(f)
+ assert reserved_sectors == 1, \
+ "Can only handle FAT with 1 reserved sector"
+
+ fat_count = read_byte(f)
+ assert fat_count == 2, "Can only handle FAT with 2 tables"
+
+ self.root_entries = read_le_short(f)
+
+ skip_short(f) # Image size. Sort of. Useless field.
+ skip_byte(f) # Media type. We don't care.
+
+ self.fat_size = read_le_short(f) * bytes_per_sector
+ self.root = fat_dir(root_dentry_file(self))
+
+ def data_start(self):
+ """
+ Index of the first byte after the FAT tables.
+ """
+ return FAT_TABLE_START + self.fat_size * 2
+
+ def get_chain_size(self, head_cluster):
+ """
+ Return how many total bytes are in the cluster chain rooted at the given
+ cluster.
+ """
+ if head_cluster == 0:
+ return 0
+
+ f = self.f
+ f.seek(FAT_TABLE_START + head_cluster * 2)
+
+ cluster_count = 0
+
+ while head_cluster <= MAX_CLUSTER_ID:
+ cluster_count += 1
+ head_cluster = read_le_short(f)
+ f.seek(FAT_TABLE_START + head_cluster * 2)
+
+ return cluster_count * self.bytes_per_cluster
+
+ def read_dentry(self, f=None):
+ """
+ Read and decode a dentry from the given file-like object at its current
+ seek position.
+ """
+ f = f or self.f
+ attributes = None
+
+ consumed = 1
+
+ lfn_entries = {}
+
+ while True:
+ skip_bytes(f, 11)
+ attributes = read_byte(f)
+ rewind_bytes(f, 12)
+
+ if attributes & LFN_ATTRIBUTES != LFN_ATTRIBUTES:
+ break
+
+ consumed += 1
+
+ seq = read_byte(f)
+ chars = f.read(10)
+ skip_bytes(f, 3) # Various hackish nonsense
+ chars += f.read(12)
+ skip_short(f) # Lots more nonsense
+ chars += f.read(4)
+
+ chars = unicode(chars, "utf-16-le").encode("utf-8")
+
+ lfn_entries[seq] = chars
+
+ ind = read_byte(f)
+
+ if ind == 0 or ind == DEL_MARKER:
+ skip_bytes(f, 31)
+ return (None, consumed)
+
+ if ind == ESCAPE_DEL_MARKER:
+ ind = DEL_MARKER
+
+ ind = str(unichr(ind))
+
+ if ind == '.':
+ skip_bytes(f, 31)
+ return (None, consumed)
+
+ shortname = ind + f.read(7).rstrip()
+ ext = f.read(3).rstrip()
+ skip_bytes(f, 15) # Assorted flags, ctime/atime/mtime, etc.
+ first_cluster = read_le_short(f)
+ size = read_le_long(f)
+
+ lfn = lfn_entries.items()
+ lfn.sort(key=lambda x: x[0])
+ lfn = reduce(lambda x, y: x + y[1], lfn, "")
+
+ if len(lfn) == 0:
+ lfn = None
+ else:
+ lfn = lfn.split('\0', 1)[0]
+
+ return (dentry(self, attributes, shortname, ext, lfn, first_cluster,
+ size), consumed)
+
+ def read_file(self, head_cluster, start_byte, size):
+ """
+ Read from a given FAT file.
+ head_cluster: The first cluster in the file.
+ start_byte: How many bytes in to the file to begin the read.
+ size: How many bytes to read.
+ """
+ f = self.f
+
+ assert size >= 0, "Can't read a negative amount"
+ if size == 0:
+ return ""
+
+ got_data = ""
+
+ while True:
+ size_now = size
+ if start_byte + size > self.bytes_per_cluster:
+ size_now = self.bytes_per_cluster - start_byte
+
+ if start_byte < self.bytes_per_cluster:
+ size -= size_now
+
+ cluster_bytes_from_root = (head_cluster - 2) * \
+ self.bytes_per_cluster
+ bytes_from_root = cluster_bytes_from_root + start_byte
+ bytes_from_data_start = bytes_from_root + self.root_entries * 32
+
+ f.seek(self.data_start() + bytes_from_data_start)
+ line = f.read(size_now)
+ got_data += line
+
+ if size == 0:
+ return got_data
+
+ start_byte -= self.bytes_per_cluster
+
+ if start_byte < 0:
+ start_byte = 0
+
+ f.seek(FAT_TABLE_START + head_cluster * 2)
+ assert head_cluster <= MAX_CLUSTER_ID, "Out-of-bounds read"
+ head_cluster = read_le_short(f)
+ assert head_cluster > 0, "Read free cluster"
+
+ return got_data
+
+ def write_cluster_entry(self, entry):
+ """
+ Write a cluster entry to the FAT table. Assumes our backing file is already
+ seeked to the correct entry in the first FAT table.
+ """
+ f = self.f
+ f.write(struct.pack("<H", entry))
+ skip_bytes(f, self.fat_size - 2)
+ f.write(struct.pack("<H", entry))
+ rewind_bytes(f, self.fat_size)
+
+ def allocate(self, amount):
+ """
+ Allocate a new cluster chain big enough to hold at least the given amount
+ of bytes.
+ """
+ assert amount > 0, "Must allocate a non-zero amount."
+
+ f = self.f
+ f.seek(FAT_TABLE_START + 4)
+
+ current = None
+ current_size = 0
+ free_zones = {}
+
+ pos = 2
+ while pos < self.fat_size / 2:
+ data = read_le_short(f)
+
+ if data == 0 and current is not None:
+ current_size += 1
+ elif data == 0:
+ current = pos
+ current_size = 1
+ elif current is not None:
+ free_zones[current] = current_size
+ current = None
+
+ pos += 1
+
+ if current is not None:
+ free_zones[current] = current_size
+
+ free_zones = free_zones.items()
+ free_zones.sort(key=lambda x: x[1])
+
+ grabbed_zones = []
+ grabbed = 0
+
+ while grabbed < amount and len(free_zones) > 0:
+ zone = free_zones.pop()
+ grabbed += zone[1] * self.bytes_per_cluster
+ grabbed_zones.append(zone)
+
+ if grabbed < amount:
+ return None
+
+ excess = (grabbed - amount) / self.bytes_per_cluster
+
+ grabbed_zones[-1] = (grabbed_zones[-1][0],
+ grabbed_zones[-1][1] - excess)
+
+ out = None
+ grabbed_zones.reverse()
+
+ for cluster, size in grabbed_zones:
+ entries = range(cluster + 1, cluster + size)
+ entries.append(out or 0xFFFF)
+ out = cluster
+ f.seek(FAT_TABLE_START + cluster * 2)
+ for entry in entries:
+ self.write_cluster_entry(entry)
+
+ return out
+
+ def extend_cluster(self, cluster, amount):
+ """
+ Given a cluster which is the *last* cluster in a chain, extend it to hold
+ at least `amount` more bytes.
+ """
+ if amount == 0:
+ return
+ f = self.f
+ entry_offset = FAT_TABLE_START + cluster * 2
+ f.seek(entry_offset)
+ assert read_le_short(f) == 0xFFFF, "Extending from middle of chain"
+
+ return_cluster = self.allocate(amount)
+ f.seek(entry_offset)
+ self.write_cluster_entry(return_cluster)
+ return return_cluster
+
+ def write_file(self, head_cluster, start_byte, data):
+ """
+ Write to a given FAT file.
+
+ head_cluster: The first cluster in the file.
+ start_byte: How many bytes in to the file to begin the write.
+ data: The data to write.
+ """
+ f = self.f
+ last_offset = start_byte + len(data)
+ current_offset = 0
+ current_cluster = head_cluster
+
+ while current_offset < last_offset:
+ # Write everything that falls in the cluster starting at current_offset.
+ data_begin = max(0, current_offset - start_byte)
+ data_end = min(len(data),
+ current_offset + self.bytes_per_cluster - start_byte)
+ if data_end > data_begin:
+ cluster_file_offset = (self.data_start() + self.root_entries * 32 +
+ (current_cluster - 2) * self.bytes_per_cluster)
+ f.seek(cluster_file_offset + max(0, start_byte - current_offset))
+ f.write(data[data_begin:data_end])
+
+ # Advance to the next cluster in the chain or get a new cluster if needed.
+ current_offset += self.bytes_per_cluster
+ if last_offset > current_offset:
+ f.seek(FAT_TABLE_START + current_cluster * 2)
+ next_cluster = read_le_short(f)
+ if next_cluster > MAX_CLUSTER_ID:
+ next_cluster = self.extend_cluster(current_cluster, len(data))
+ current_cluster = next_cluster
+ assert current_cluster > 0, "Cannot write free cluster"
+
+
+def add_item(directory, item):
+ """
+ Copy a file into the given FAT directory. If the path given is a directory,
+ copy recursively.
+ directory: fat_dir to copy the file in to
+ item: Path of local file to copy
+ """
+ if os.path.isdir(item):
+ base = os.path.basename(item)
+ if len(base) == 0:
+ base = os.path.basename(item[:-1])
+ sub = directory.open_subdirectory(base)
+ for next_item in sorted(os.listdir(item)):
+ add_item(sub, os.path.join(item, next_item))
+ else:
+ with open(item, 'rb') as f:
+ directory.new_file(os.path.basename(item), f)
+
+if __name__ == "__main__":
+ if len(sys.argv) < 3:
+ print("Usage: fat16copy.py <image> <file> [<file> ...]")
+ print("Files are copied into the root of the image.")
+ print("Directories are copied recursively")
+ sys.exit(1)
+
+ root = fat(sys.argv[1]).root
+
+ for p in sys.argv[2:]:
+ add_item(root, p)
diff --git a/tools/fileslist.py b/tools/fileslist.py
deleted file mode 100755
index b9e7350..0000000
--- a/tools/fileslist.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# 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.
-#
-
-import json, hashlib, operator, os, sys
-
-def get_file_size(path):
- st = os.lstat(path)
- return st.st_size;
-
-def get_file_digest(path):
- if os.path.isfile(path) == False:
- return "----------------------------------------------------------------"
- digest = hashlib.sha256()
- with open(path, 'rb') as f:
- while True:
- buf = f.read(1024*1024)
- if not buf:
- break
- digest.update(buf)
- return digest.hexdigest();
-
-def main(argv):
- output = []
- roots = argv[1:]
- for root in roots:
- base = len(root[:root.rfind(os.path.sep)])
- for dir, dirs, files in os.walk(root):
- relative = dir[base:]
- for f in files:
- try:
- path = os.path.sep.join((dir, f))
- row = {
- "Size": get_file_size(path),
- "Name": os.path.sep.join((relative, f)),
- "SHA256": get_file_digest(path),
- }
- output.append(row)
- except os.error:
- pass
- output.sort(key=operator.itemgetter("Size", "Name"), reverse=True)
- print json.dumps(output, indent=2, separators=(',',': '))
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/tools/findleaves.py b/tools/findleaves.py
index 3a9e508..f152a87 100755
--- a/tools/findleaves.py
+++ b/tools/findleaves.py
@@ -23,9 +23,10 @@
import os
import sys
-def perform_find(mindepth, prune, dirlist, filename):
+def perform_find(mindepth, prune, dirlist, filenames):
result = []
pruneleaves = set(map(lambda x: os.path.split(x)[1], prune))
+ seen = set()
for rootdir in dirlist:
rootdepth = rootdir.count("/")
for root, dirs, files in os.walk(rootdir, followlinks=True):
@@ -48,19 +49,36 @@
if depth < mindepth:
continue
# match
- if filename in files:
- result.append(os.path.join(root, filename))
- del dirs[:]
+ for filename in filenames:
+ if filename in files:
+ result.append(os.path.join(root, filename))
+ del dirs[:]
+
+ # filter out inodes that have already been seen due to symlink loops
+ i = 0
+ while i < len(dirs):
+ st = os.stat(os.path.join(root, dirs[i]))
+ key = (st.st_dev, st.st_ino)
+ if key in seen:
+ del dirs[i]
+ else:
+ i += 1
+ seen.add(key)
+
return result
def usage():
- sys.stderr.write("""Usage: %(progName)s [<options>] <dirlist> <filename>
+ sys.stderr.write("""Usage: %(progName)s [<options>] [--dir=<dir>] <filenames>
Options:
--mindepth=<mindepth>
Both behave in the same way as their find(1) equivalents.
--prune=<dirname>
Avoids returning results from inside any directory called <dirname>
(e.g., "*/out/*"). May be used multiple times.
+ --dir=<dir>
+ Add a directory to search. May be repeated multiple times. For backwards
+ compatibility, if no --dir argument is provided then all but the last entry
+ in <filenames> are treated as directories.
""" % {
"progName": os.path.split(sys.argv[0])[1],
})
@@ -69,6 +87,7 @@
def main(argv):
mindepth = -1
prune = []
+ dirlist = []
i=1
while i<len(argv) and len(argv[i])>2 and argv[i][0:2] == "--":
arg = argv[i]
@@ -82,14 +101,24 @@
if len(p) == 0:
usage()
prune.append(p)
+ elif arg.startswith("--dir="):
+ d = arg[len("--dir="):]
+ if len(p) == 0:
+ usage()
+ dirlist.append(d)
else:
usage()
i += 1
- if len(argv)-i < 2: # need both <dirlist> and <filename>
- usage()
- dirlist = argv[i:-1]
- filename = argv[-1]
- results = list(set(perform_find(mindepth, prune, dirlist, filename)))
+ if len(dirlist) == 0: # backwards compatibility
+ if len(argv)-i < 2: # need both <dirlist> and <filename>
+ usage()
+ dirlist = argv[i:-1]
+ filenames = [argv[-1]]
+ else:
+ if len(argv)-i < 1: # need <filename>
+ usage()
+ filenames = argv[i:]
+ results = list(set(perform_find(mindepth, prune, dirlist, filenames)))
results.sort()
for r in results:
print r
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index 34a3522..ab7f92d 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -23,20 +23,38 @@
include $(BUILD_HOST_EXECUTABLE)
-# To Build the custom target binary for the host to generate the fs_config
-# override files. The executable is hard coded to include the
-# $(TARGET_ANDROID_FILESYSTEM_CONFIG_H) file if it exists.
-# Expectations:
-# device/<vendor>/<device>/android_filesystem_config.h
-# fills in struct fs_path_config android_device_dirs[] and
-# struct fs_path_config android_device_files[]
-# device/<vendor>/<device>/device.mk
-# PRODUCT_PACKAGES += fs_config_dirs fs_config_files
-
-# If not specified, check if default one to be found
+# One can override the default android_filesystem_config.h file in one of two ways:
+#
+# 1. The old way:
+# To Build the custom target binary for the host to generate the fs_config
+# override files. The executable is hard coded to include the
+# $(TARGET_ANDROID_FILESYSTEM_CONFIG_H) file if it exists.
+# Expectations:
+# device/<vendor>/<device>/android_filesystem_config.h
+# fills in struct fs_path_config android_device_dirs[] and
+# struct fs_path_config android_device_files[]
+# device/<vendor>/<device>/device.mk
+# PRODUCT_PACKAGES += fs_config_dirs fs_config_files
+# If not specified, check if default one to be found
+#
+# 2. The new way:
+# set TARGET_FS_CONFIG_GEN to contain a list of intermediate format files
+# for generating the android_filesystem_config.h file.
+#
+# More information can be found in the README
ANDROID_FS_CONFIG_H := android_filesystem_config.h
ifneq ($(TARGET_ANDROID_FILESYSTEM_CONFIG_H),)
+ifneq ($(TARGET_FS_CONFIG_GEN),)
+$(error Cannot set TARGET_ANDROID_FILESYSTEM_CONFIG_H and TARGET_FS_CONFIG_GEN simultaneously)
+endif
+
+# One and only one file can be specified.
+ifneq ($(words $(TARGET_ANDROID_FILESYSTEM_CONFIG_H)),1)
+$(error Multiple fs_config files specified, \
+ see "$(TARGET_ANDROID_FILESYSTEM_CONFIG_H)".)
+endif
+
ifeq ($(filter %/$(ANDROID_FS_CONFIG_H),$(TARGET_ANDROID_FILESYSTEM_CONFIG_H)),)
$(error TARGET_ANDROID_FILESYSTEM_CONFIG_H file name must be $(ANDROID_FS_CONFIG_H), \
see "$(notdir $(TARGET_ANDROID_FILESYSTEM_CONFIG_H))".)
@@ -44,42 +62,280 @@
my_fs_config_h := $(TARGET_ANDROID_FILESYSTEM_CONFIG_H)
else ifneq ($(wildcard $(TARGET_DEVICE_DIR)/$(ANDROID_FS_CONFIG_H)),)
+
+ifneq ($(TARGET_FS_CONFIG_GEN),)
+$(error Cannot provide $(TARGET_DEVICE_DIR)/$(ANDROID_FS_CONFIG_H) and set TARGET_FS_CONFIG_GEN simultaneously)
+endif
my_fs_config_h := $(TARGET_DEVICE_DIR)/$(ANDROID_FS_CONFIG_H)
+
else
my_fs_config_h := $(LOCAL_PATH)/default/$(ANDROID_FS_CONFIG_H)
endif
+##################################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := fs_config_generate.c
LOCAL_MODULE := fs_config_generate_$(TARGET_DEVICE)
+LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_CFLAGS := -Werror -Wno-error=\#warnings
-LOCAL_C_INCLUDES := $(dir $(my_fs_config_h))
+
+ifneq ($(TARGET_FS_CONFIG_GEN),)
+system_android_filesystem_config := system/core/include/private/android_filesystem_config.h
+
+# Generate the "generated_oem_aid.h" file
+oem := $(local-generated-sources-dir)/generated_oem_aid.h
+$(oem): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+$(oem): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+$(oem): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
+$(oem): PRIVATE_CUSTOM_TOOL = $(PRIVATE_LOCAL_PATH)/fs_config_generator.py oemaid --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
+$(oem): $(TARGET_FS_CONFIG_GEN) $(LOCAL_PATH)/fs_config_generator.py
+ $(transform-generated-source)
+
+# Generate the fs_config header
+gen := $(local-generated-sources-dir)/$(ANDROID_FS_CONFIG_H)
+$(gen): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+$(gen): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+$(gen): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
+$(gen): PRIVATE_CUSTOM_TOOL = $(PRIVATE_LOCAL_PATH)/fs_config_generator.py fsconfig --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
+$(gen): $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(LOCAL_PATH)/fs_config_generator.py
+ $(transform-generated-source)
+
+LOCAL_GENERATED_SOURCES := $(oem) $(gen)
+
+my_fs_config_h := $(gen)
+my_gen_oem_aid := $(oem)
+gen :=
+oem :=
+endif
+
+LOCAL_C_INCLUDES := $(dir $(my_fs_config_h)) $(dir $(my_gen_oem_aid))
+
include $(BUILD_HOST_EXECUTABLE)
fs_config_generate_bin := $(LOCAL_INSTALLED_MODULE)
+# List of all supported vendor, oem and odm Partitions
+fs_config_generate_extra_partition_list := $(strip \
+ $(if $(BOARD_USES_VENDORIMAGE)$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),vendor) \
+ $(if $(BOARD_USES_OEMIMAGE)$(BOARD_OEMIMAGE_FILE_SYSTEM_TYPE),oem) \
+ $(if $(BOARD_USES_ODMIMAGE)$(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE),odm))
+##################################
# Generate the system/etc/fs_config_dirs binary file for the target
# Add fs_config_dirs to PRODUCT_PACKAGES in the device make file to enable
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_dirs
LOCAL_MODULE_CLASS := ETC
+LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),$(LOCAL_MODULE)_$(t))
include $(BUILD_SYSTEM)/base_rules.mk
$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
@mkdir -p $(dir $@)
- $< -D -o $@
+ $< -D $(if $(fs_config_generate_extra_partition_list), \
+ -P '$(subst $(space),$(comma),$(addprefix -,$(fs_config_generate_extra_partition_list)))') \
+ -o $@
+##################################
# Generate the system/etc/fs_config_files binary file for the target
# Add fs_config_files to PRODUCT_PACKAGES in the device make file to enable
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_files
LOCAL_MODULE_CLASS := ETC
+LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),$(LOCAL_MODULE)_$(t))
include $(BUILD_SYSTEM)/base_rules.mk
$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
@mkdir -p $(dir $@)
- $< -F -o $@
+ $< -F $(if $(fs_config_generate_extra_partition_list), \
+ -P '$(subst $(space),$(comma),$(addprefix -,$(fs_config_generate_extra_partition_list)))') \
+ -o $@
+
+ifneq ($(filter vendor,$(fs_config_generate_extra_partition_list)),)
+##################################
+# Generate the vendor/etc/fs_config_dirs binary file for the target
+# Add fs_config_dirs or fs_config_dirs_vendor to PRODUCT_PACKAGES in
+# the device make file to enable.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_dirs_vendor
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+ @mkdir -p $(dir $@)
+ $< -D -P vendor -o $@
+
+##################################
+# Generate the vendor/etc/fs_config_files binary file for the target
+# Add fs_config_files or fs_config_files_vendor to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_files_vendor
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_files
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+ @mkdir -p $(dir $@)
+ $< -F -P vendor -o $@
+
+endif
+
+ifneq ($(filter oem,$(fs_config_generate_extra_partition_list)),)
+##################################
+# Generate the oem/etc/fs_config_dirs binary file for the target
+# Add fs_config_dirs or fs_config_dirs_oem to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_dirs_oem
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
+LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+ @mkdir -p $(dir $@)
+ $< -D -P oem -o $@
+
+##################################
+# Generate the oem/etc/fs_config_files binary file for the target
+# Add fs_config_files or fs_config_files_oem to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_files_oem
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_files
+LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+ @mkdir -p $(dir $@)
+ $< -F -P oem -o $@
+
+endif
+
+ifneq ($(filter odm,$(fs_config_generate_extra_partition_list)),)
+##################################
+# Generate the odm/etc/fs_config_dirs binary file for the target
+# Add fs_config_dirs or fs_config_dirs_odm to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_dirs_odm
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
+LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+ @mkdir -p $(dir $@)
+ $< -D -P odm -o $@
+
+##################################
+# Generate the odm/etc/fs_config_files binary file for the target
+# Add fs_config_files of fs_config_files_odm to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_files_odm
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_files
+LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+ @mkdir -p $(dir $@)
+ $< -F -P odm -o $@
+
+endif
+
+# The newer passwd/group targets are only generated if you
+# use the new TARGET_FS_CONFIG_GEN method.
+ifneq ($(TARGET_FS_CONFIG_GEN),)
+
+##################################
+# Build the oemaid library when fs config files are present.
+# Intentionally break build if you require generated AIDS
+# header file, but are not using any fs config files.
+include $(CLEAR_VARS)
+LOCAL_MODULE := liboemaids
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(dir $(my_gen_oem_aid))
+LOCAL_EXPORT_C_INCLUDE_DEPS := $(my_gen_oem_aid)
+include $(BUILD_STATIC_LIBRARY)
+
+##################################
+# Generate the system/etc/passwd text file for the target
+# This file may be empty if no AIDs are defined in
+# TARGET_FS_CONFIG_GEN files.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := passwd
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
+ @mkdir -p $(dir $@)
+ $(hide) $< passwd --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
+
+##################################
+# Generate the system/etc/group text file for the target
+# This file may be empty if no AIDs are defined in
+# TARGET_FS_CONFIG_GEN files.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := group
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
+ @mkdir -p $(dir $@)
+ $(hide) $< group --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
+
+system_android_filesystem_config :=
+endif
ANDROID_FS_CONFIG_H :=
my_fs_config_h :=
fs_config_generate_bin :=
+my_gen_oem_aid :=
+fs_config_generate_extra_partition_list :=
+
+# -----------------------------------------------------------------------------
+# Unit tests.
+# -----------------------------------------------------------------------------
+
+test_c_flags := \
+ -fstack-protector-all \
+ -g \
+ -Wall \
+ -Wextra \
+ -Werror \
+ -fno-builtin \
+ -DANDROID_FILESYSTEM_CONFIG='"android_filesystem_config_test_data.h"'
+
+##################################
+# test executable
+include $(CLEAR_VARS)
+LOCAL_MODULE := fs_config_generate_test
+LOCAL_SRC_FILES := fs_config_generate.c
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_CFLAGS := $(test_c_flags)
+LOCAL_MODULE_RELATIVE_PATH := fs_config-unit-tests
+LOCAL_GTEST := false
+include $(BUILD_HOST_NATIVE_TEST)
+
+##################################
+# gTest tool
+include $(CLEAR_VARS)
+LOCAL_MODULE := fs_config-unit-tests
+LOCAL_CFLAGS += $(test_c_flags) -DHOST
+LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
+LOCAL_SRC_FILES := fs_config_test.cpp
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tools/fs_config/README b/tools/fs_config/README
new file mode 100644
index 0000000..5af407f
--- /dev/null
+++ b/tools/fs_config/README
@@ -0,0 +1,183 @@
+ _____ _____ _____ _____ __ __ _____
+/ _ \/ __\/ _ \| _ \/ \/ \/ __\
+| _ <| __|| _ || | || \/ || __|
+\__|\_/\_____/\__|__/|_____/\__ \__/\_____/
+
+Generating the android_filesystem_config.h:
+
+To generate the android_filesystem_config.h file, one can choose from
+one of two methods. The first method, is to declare
+TARGET_ANDROID_FILESYSTEM_CONFIG_H in the device BoardConfig.mk file. This
+variable can only have one item in it, and it is used directly as the
+android_filesystem_config.h header when building
+fs_config_generate_$(TARGET_DEVICE) which is used to generate fs_config_files
+and fs_config_dirs target executable.
+
+The limitation with this, is that it can only be set once, thus if the device
+has a make hierarchy, then each device needs its own file, and cannot share
+from a common source or that common source needs to include everything from
+both devices.
+
+The other way is to set TARGET_FS_CONFIG_GEN, which can be a list of
+intermediate fs configuration files. It is a build error on any one
+these conditions:
+ * Specify TARGET_FS_CONFIG_GEN and TARGET_ANDROID_FILESYSTEM_CONFIG_H
+ * Specify TARGET_FS_CONFIG_GEN and provide
+ $(TARGET_DEVICE_DIR)/android_filesystem_config.h
+
+The parsing of the config file follows the Python ConfigParser specification,
+with the sections and fields as defined below. There are two types of sections,
+both sections require all options to be specified. The first section type is
+the "caps" section.
+
+The "caps" section follows the following syntax:
+
+[path]
+mode: Octal file mode
+user: AID_<user>
+group: AID_<group>
+caps: cap*
+
+Where:
+
+[path]
+ The filesystem path to configure. A path ending in / is considered a dir,
+ else its a file.
+
+mode:
+ A valid octal file mode of at least 3 digits. If 3 is specified, it is
+ prefixed with a 0, else mode is used as is.
+
+user:
+ Either the C define for a valid AID or the friendly name. For instance both
+ AID_RADIO and radio are acceptable. Note custom AIDs can be defined in the
+ AID section documented below.
+
+group:
+ Same as user.
+
+caps:
+ The name as declared in
+ system/core/include/private/android_filesystem_capability.h without the
+ leading CAP_. Mixed case is allowed. Caps can also be the raw:
+ * binary (0b0101)
+ * octal (0455)
+ * int (42)
+ * hex (0xFF)
+ For multiple caps, just separate by whitespace.
+
+It is an error to specify multiple sections with the same [path] in different
+files. Note that the same file may contain sections that override the previous
+section in Python versions <= 3.2. In Python 3.2 it's set to strict mode.
+
+
+The next section type is the "AID" section, for specifying OEM specific AIDS.
+
+The AID section follows the following syntax:
+
+[AID_<name>]
+value: <number>
+
+Where:
+
+[AID_<name>]
+ The <name> can contain characters in the set uppercase, numbers
+ and underscores.
+
+value:
+ A valid C style number string. Hex, octal, binary and decimal are supported.
+ See "caps" above for more details on number formatting.
+
+It is an error to specify multiple sections with the same [AID_<name>]. With
+the same constraints as [path] described above. It is also an error to specify
+multiple sections with the same value option. It is also an error to specify a
+value that is outside of the inclusive OEM ranges:
+ * AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)
+ * AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)
+
+as defined by system/core/include/private/android_filesystem_config.h.
+
+Ordering within the TARGET_FS_CONFIG_GEN files is not relevant. The paths for files are sorted
+like so within their respective array definition:
+ * specified path before prefix match
+ ** ie foo before f*
+ * lexicographical less than before other
+ ** ie boo before foo
+
+Given these paths:
+
+paths=['ac', 'a', 'acd', 'an', 'a*', 'aa', 'ac*']
+
+The sort order would be:
+paths=['a', 'aa', 'ac', 'acd', 'an', 'ac*', 'a*']
+
+Thus the fs_config tools will match on specified paths before attempting prefix, and match on the
+longest matching prefix.
+
+The declared AIDS are sorted in ascending numerical order based on the option "value". The string
+representation of value is preserved. Both choices were made for maximum readability of the generated
+file and to line up files. Sync lines are placed with the source file as comments in the generated
+header file.
+
+For OEMs wishing to use the define AIDs in their native code, one can access the generated header
+file like so:
+ 1. In your C code just #include "generated_oem_aid.h" and start using the declared identifiers.
+ 2. In your Makefile add this static library like so: LOCAL_STATIC_LIBRARIES := liboemaids
+
+Unit Tests:
+
+From within the fs_config directory, unit tests can be executed like so:
+$ python -m unittest test_fs_config_generator.Tests
+.............
+----------------------------------------------------------------------
+Ran 13 tests in 0.004s
+
+OK
+
+One could also use nose if they would like:
+$ nose2
+
+To add new tests, simply add a test_<xxx> method to the test class. It will automatically
+get picked up and added to the test suite.
+
+Using the android_filesystem_config.h:
+
+The tool fs_config_generate is built as a dependency to fs_config_dirs and
+fs_config_files host targets, and #includes the above supplied or generated
+android_filesystem_config.h file, and can be instructed to generate the binary
+data that lands in the device target locations /system/etc/fs_config_dirs and
+/system/etc/fs_config_files and in the host's ${OUT} locations
+${OUT}/target/product/<device>/system/etc/fs_config_dirs and
+${OUT}/target/product/<device>/system/etc/fs_config_files. The binary files
+are interpreted by the libcutils fs_conf() function, along with the built-in
+defaults, to serve as overrides to complete the results. The Target files are
+used by filesystem and adb tools to ensure that the file and directory
+properties are preserved during runtime operations. The host files in the
+${OUT} directory are used in the final stages when building the filesystem
+images to set the file and directory properties.
+
+For systems with separate partition images, such as vendor or oem,
+fs_config_generate can be instructed to filter the specific file references
+to land in each partition's etc/fs_config_dirs or etc/fs_config_files
+locations. The filter can be instructed to blacklist a partition's data by
+providing the comma separated minus sign prefixed partition names. The filter
+can be instructed to whitelist partition data by providing the partition name.
+
+For example:
+- For system.img, but not vendor, oem or odm file references:
+ -P -vendor,-oem,-odm
+ This makes sure the results only contain content associated with the
+ system, and not vendor, oem or odm, blacklisting their content.
+- For vendor.img file references: -P vendor
+- For oem.img file references: -P oem
+- For odm.img file references: -P odm
+
+fs_config_generate --help reports:
+
+Generate binary content for fs_config_dirs (-D) and fs_config_files (-F)
+from device-specific android_filesystem_config.h override. Filter based
+on a comma separated partition list (-P) whitelist or prefixed by a
+minus blacklist. Partitions are identified as path references to
+<partition>/ or system/<partition>
+
+Usage: fs_config_generate -D|-F [-P list] [-o output-file]
diff --git a/tools/fs_config/android_filesystem_config_test_data.h b/tools/fs_config/android_filesystem_config_test_data.h
new file mode 100644
index 0000000..07bc8e5
--- /dev/null
+++ b/tools/fs_config/android_filesystem_config_test_data.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include <private/android_filesystem_config.h>
+
+/* Test Data */
+
+#undef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+#undef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
+
+static const struct fs_path_config android_device_dirs[] = {
+ {00555, AID_ROOT, AID_SYSTEM, 0, "system/etc"},
+ {00555, AID_ROOT, AID_SYSTEM, 0, "vendor/etc"},
+ {00555, AID_ROOT, AID_SYSTEM, 0, "oem/etc"},
+ {00555, AID_ROOT, AID_SYSTEM, 0, "odm/etc"},
+ {00755, AID_SYSTEM, AID_ROOT, 0, "system/oem/etc"},
+ {00755, AID_SYSTEM, AID_ROOT, 0, "system/odm/etc"},
+ {00755, AID_SYSTEM, AID_ROOT, 0, "system/vendor/etc"},
+ {00755, AID_SYSTEM, AID_ROOT, 0, "data/misc"},
+ {00755, AID_SYSTEM, AID_ROOT, 0, "oem/data/misc"},
+ {00755, AID_SYSTEM, AID_ROOT, 0, "odm/data/misc"},
+ {00755, AID_SYSTEM, AID_ROOT, 0, "vendor/data/misc"},
+ {00555, AID_SYSTEM, AID_ROOT, 0, "etc"},
+};
+
+static const struct fs_path_config android_device_files[] = {
+ {00444, AID_ROOT, AID_SYSTEM, 0, "system/etc/fs_config_dirs"},
+ {00444, AID_ROOT, AID_SYSTEM, 0, "vendor/etc/fs_config_dirs"},
+ {00444, AID_ROOT, AID_SYSTEM, 0, "oem/etc/fs_config_dirs"},
+ {00444, AID_ROOT, AID_SYSTEM, 0, "odm/etc/fs_config_dirs"},
+ {00444, AID_ROOT, AID_SYSTEM, 0, "system/etc/fs_config_files"},
+ {00444, AID_ROOT, AID_SYSTEM, 0, "vendor/etc/fs_config_files"},
+ {00444, AID_ROOT, AID_SYSTEM, 0, "oem/etc/fs_config_files"},
+ {00444, AID_ROOT, AID_SYSTEM, 0, "odm/etc/fs_config_files"},
+ {00644, AID_SYSTEM, AID_ROOT, 0, "system/vendor/etc/fs_config_dirs"},
+ {00644, AID_SYSTEM, AID_ROOT, 0, "system/oem/etc/fs_config_dirs"},
+ {00644, AID_SYSTEM, AID_ROOT, 0, "system/odm/etc/fs_config_dirs"},
+ {00644, AID_SYSTEM, AID_ROOT, 0, "system/vendor/etc/fs_config_files"},
+ {00644, AID_SYSTEM, AID_ROOT, 0, "system/oem/etc/fs_config_files"},
+ {00644, AID_SYSTEM, AID_ROOT, 0, "system/odm/etc/fs_config_files"},
+ {00644, AID_SYSTEM, AID_ROOT, 0, "etc/fs_config_files"},
+ {00666, AID_ROOT, AID_SYSTEM, 0, "data/misc/oem"},
+};
diff --git a/tools/fs_config/default/android_filesystem_config.h b/tools/fs_config/default/android_filesystem_config.h
index 820b04a..b7d936a 100644
--- a/tools/fs_config/default/android_filesystem_config.h
+++ b/tools/fs_config/default/android_filesystem_config.h
@@ -19,13 +19,6 @@
** by the device side of adb.
*/
-/*
-** Resorting to the default file means someone requested fs_config_dirs or
-** fs_config_files in their device configuration without providing an
-** associated header.
-*/
-#warning No device-supplied android_filesystem_config.h, using empty default.
-
/* Rules for directories.
** These rules are applied based on "first match", so they
** should start with the most specific path and work their
diff --git a/tools/fs_config/fs_config.c b/tools/fs_config/fs_config.c
index e797957..48f300b 100644
--- a/tools/fs_config/fs_config.c
+++ b/tools/fs_config/fs_config.c
@@ -105,6 +105,9 @@
switch (buffer[i]) {
case '\n':
buffer[i-is_dir] = '\0';
+ if (i == 0) {
+ is_dir = 1; // empty line is considered as root directory
+ }
i = 1025;
break;
case '/':
diff --git a/tools/fs_config/fs_config_generate.c b/tools/fs_config/fs_config_generate.c
index c06213f..cb7ff9d 100644
--- a/tools/fs_config/fs_config_generate.c
+++ b/tools/fs_config/fs_config_generate.c
@@ -14,9 +14,11 @@
* limitations under the License.
*/
+#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <private/android_filesystem_config.h>
@@ -28,38 +30,57 @@
* the binary format used in the /system/etc/fs_config_dirs and
* the /system/etc/fs_config_files to be used by the runtimes.
*/
+#ifdef ANDROID_FILESYSTEM_CONFIG
+#include ANDROID_FILESYSTEM_CONFIG
+#else
#include "android_filesystem_config.h"
+#endif
#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
- static const struct fs_path_config android_device_dirs[] = {
-};
+static const struct fs_path_config android_device_dirs[] = { };
#endif
#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
static const struct fs_path_config android_device_files[] = {
#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
- { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
+ {0000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs"},
+ {0000, AID_ROOT, AID_ROOT, 0, "vendor/etc/fs_config_dirs"},
+ {0000, AID_ROOT, AID_ROOT, 0, "oem/etc/fs_config_dirs"},
+ {0000, AID_ROOT, AID_ROOT, 0, "odm/etc/fs_config_dirs"},
#endif
- { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_files" },
+ {0000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_files"},
+ {0000, AID_ROOT, AID_ROOT, 0, "vendor/etc/fs_config_files"},
+ {0000, AID_ROOT, AID_ROOT, 0, "oem/etc/fs_config_files"},
+ {0000, AID_ROOT, AID_ROOT, 0, "odm/etc/fs_config_files"},
};
#endif
static void usage() {
fprintf(stderr,
"Generate binary content for fs_config_dirs (-D) and fs_config_files (-F)\n"
- "from device-specific android_filesystem_config.h override\n\n"
- "Usage: fs_config_generate -D|-F [-o output-file]\n");
+ "from device-specific android_filesystem_config.h override. Filter based\n"
+ "on a comma separated partition list (-P) whitelist or prefixed by a\n"
+ "minus blacklist. Partitions are identified as path references to\n"
+ "<partition>/ or system/<partition>/\n\n"
+ "Usage: fs_config_generate -D|-F [-P list] [-o output-file]\n");
}
-int main(int argc, char** argv) {
- const struct fs_path_config *pc;
- const struct fs_path_config *end;
- bool dir = false, file = false;
- FILE *fp = stdout;
- int opt;
+/* If tool switches to C++, use android-base/macros.h array_size() */
+#ifndef ARRAY_SIZE /* popular macro */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
- while((opt = getopt(argc, argv, "DFho:")) != -1) {
- switch(opt) {
+int main(int argc, char** argv) {
+ const struct fs_path_config* pc;
+ const struct fs_path_config* end;
+ bool dir = false, file = false;
+ const char* partitions = NULL;
+ FILE* fp = stdout;
+ int opt;
+ static const char optstring[] = "DFP:ho:";
+
+ while ((opt = getopt(argc, argv, optstring)) != -1) {
+ switch (opt) {
case 'D':
if (file) {
fprintf(stderr, "Must specify only -D or -F\n");
@@ -76,6 +97,30 @@
}
file = true;
break;
+ case 'P':
+ if (partitions) {
+ fprintf(stderr, "Specify only one partition list\n");
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ while (*optarg && isspace(*optarg)) ++optarg;
+ if (!optarg[0]) {
+ fprintf(stderr, "Partition list empty\n");
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ if (!optarg[1]) {
+ fprintf(stderr, "Partition list too short \"%s\"\n", optarg);
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ if ((optarg[0] == '-') && strchr(optstring, optarg[1]) && !optarg[2]) {
+ fprintf(stderr, "Partition list is a flag \"%s\"\n", optarg);
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ partitions = optarg;
+ break;
case 'o':
if (fp != stdout) {
fprintf(stderr, "Specify only one output file\n");
@@ -97,6 +142,12 @@
}
}
+ if (optind < argc) {
+ fprintf(stderr, "Unknown non-argument \"%s\"\n", argv[optind]);
+ usage();
+ exit(EXIT_FAILURE);
+ }
+
if (!file && !dir) {
fprintf(stderr, "Must specify either -F or -D\n");
usage();
@@ -105,19 +156,64 @@
if (dir) {
pc = android_device_dirs;
- end = &android_device_dirs[sizeof(android_device_dirs) / sizeof(android_device_dirs[0])];
+ end = &android_device_dirs[ARRAY_SIZE(android_device_dirs)];
} else {
pc = android_device_files;
- end = &android_device_files[sizeof(android_device_files) / sizeof(android_device_files[0])];
+ end = &android_device_files[ARRAY_SIZE(android_device_files)];
}
- for(; (pc < end) && pc->prefix; pc++) {
+ for (; (pc < end) && pc->prefix; pc++) {
+ bool submit;
char buffer[512];
ssize_t len = fs_config_generate(buffer, sizeof(buffer), pc);
if (len < 0) {
fprintf(stderr, "Entry too large\n");
exit(EXIT_FAILURE);
}
- if (fwrite(buffer, 1, len, fp) != (size_t)len) {
+ submit = true;
+ if (partitions) {
+ char* partitions_copy = strdup(partitions);
+ char* arg = partitions_copy;
+ char* sv = NULL; /* Do not leave uninitialized, NULL is known safe. */
+ /* Deal with case all iterated partitions are blacklists with no match */
+ bool all_blacklist_but_no_match = true;
+ submit = false;
+
+ if (!partitions_copy) {
+ fprintf(stderr, "Failed to allocate a copy of %s\n", partitions);
+ exit(EXIT_FAILURE);
+ }
+ /* iterate through (officially) comma separated list of partitions */
+ while (!!(arg = strtok_r(arg, ",:; \t\n\r\f", &sv))) {
+ static const char system[] = "system/";
+ size_t plen;
+ bool blacklist = false;
+ if (*arg == '-') {
+ blacklist = true;
+ ++arg;
+ } else {
+ all_blacklist_but_no_match = false;
+ }
+ plen = strlen(arg);
+ /* deal with evil callers */
+ while (arg[plen - 1] == '/') {
+ --plen;
+ }
+ /* check if we have <partition>/ or /system/<partition>/ */
+ if ((!strncmp(pc->prefix, arg, plen) && (pc->prefix[plen] == '/')) ||
+ (!strncmp(pc->prefix, system, strlen(system)) &&
+ !strncmp(pc->prefix + strlen(system), arg, plen) &&
+ (pc->prefix[strlen(system) + plen] == '/'))) {
+ all_blacklist_but_no_match = false;
+ /* we have a match !!! */
+ if (!blacklist) submit = true;
+ break;
+ }
+ arg = NULL;
+ }
+ free(partitions_copy);
+ if (all_blacklist_but_no_match) submit = true;
+ }
+ if (submit && (fwrite(buffer, 1, len, fp) != (size_t)len)) {
fprintf(stderr, "Write failure\n");
exit(EXIT_FAILURE);
}
diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py
new file mode 100755
index 0000000..c8d1dd3
--- /dev/null
+++ b/tools/fs_config/fs_config_generator.py
@@ -0,0 +1,1331 @@
+#!/usr/bin/env python
+"""Generates config files for Android file system properties.
+
+This script is used for generating configuration files for configuring
+Android filesystem properties. Internally, its composed of a plug-able
+interface to support the understanding of new input and output parameters.
+
+Run the help for a list of supported plugins and their capabilities.
+
+Further documentation can be found in the README.
+"""
+
+import argparse
+import ConfigParser
+import re
+import sys
+import textwrap
+
+# Keep the tool in one file to make it easy to run.
+# pylint: disable=too-many-lines
+
+
+# Lowercase generator used to be inline with @staticmethod.
+class generator(object): # pylint: disable=invalid-name
+ """A decorator class to add commandlet plugins.
+
+ Used as a decorator to classes to add them to
+ the internal plugin interface. Plugins added
+ with @generator() are automatically added to
+ the command line.
+
+ For instance, to add a new generator
+ called foo and have it added just do this:
+
+ @generator("foo")
+ class FooGen(object):
+ ...
+ """
+ _generators = {}
+
+ def __init__(self, gen):
+ """
+ Args:
+ gen (str): The name of the generator to add.
+
+ Raises:
+ ValueError: If there is a similarly named generator already added.
+
+ """
+ self._gen = gen
+
+ if gen in generator._generators:
+ raise ValueError('Duplicate generator name: ' + gen)
+
+ generator._generators[gen] = None
+
+ def __call__(self, cls):
+
+ generator._generators[self._gen] = cls()
+ return cls
+
+ @staticmethod
+ def get():
+ """Gets the list of generators.
+
+ Returns:
+ The list of registered generators.
+ """
+ return generator._generators
+
+
+class Utils(object):
+ """Various assorted static utilities."""
+
+ @staticmethod
+ def in_any_range(value, ranges):
+ """Tests if a value is in a list of given closed range tuples.
+
+ A range tuple is a closed range. That means it's inclusive of its
+ start and ending values.
+
+ Args:
+ value (int): The value to test.
+ range [(int, int)]: The closed range list to test value within.
+
+ Returns:
+ True if value is within the closed range, false otherwise.
+ """
+
+ return any(lower <= value <= upper for (lower, upper) in ranges)
+
+ @staticmethod
+ def get_login_and_uid_cleansed(aid):
+ """Returns a passwd/group file safe logon and uid.
+
+ This checks that the logon and uid of the AID do not
+ contain the delimiter ":" for a passwd/group file.
+
+ Args:
+ aid (AID): The aid to check
+
+ Returns:
+ logon, uid of the AID after checking its safe.
+
+ Raises:
+ ValueError: If there is a delimiter charcter found.
+ """
+ logon = aid.friendly
+ uid = aid.normalized_value
+ if ':' in uid:
+ raise ValueError(
+ 'Cannot specify delimiter character ":" in uid: "%s"' % uid)
+ if ':' in logon:
+ raise ValueError(
+ 'Cannot specify delimiter character ":" in logon: "%s"' % logon)
+ return logon, uid
+
+
+class AID(object):
+ """This class represents an Android ID or an AID.
+
+ Attributes:
+ identifier (str): The identifier name for a #define.
+ value (str) The User Id (uid) of the associate define.
+ found (str) The file it was found in, can be None.
+ normalized_value (str): Same as value, but base 10.
+ friendly (str): The friendly name of aid.
+ """
+
+ PREFIX = 'AID_'
+
+ # Some of the AIDS like AID_MEDIA_EX had names like mediaex
+ # list a map of things to fixup until we can correct these
+ # at a later date.
+ _FIXUPS = {
+ 'media_drm': 'mediadrm',
+ 'media_ex': 'mediaex',
+ 'media_codec': 'mediacodec'
+ }
+
+ def __init__(self, identifier, value, found):
+ """
+ Args:
+ identifier: The identifier name for a #define <identifier>.
+ value: The value of the AID, aka the uid.
+ found (str): The file found in, not required to be specified.
+
+ Raises:
+ ValueError: if value is not a valid string number as processed by
+ int(x, 0)
+ """
+ self.identifier = identifier
+ self.value = value
+ self.found = found
+ self.normalized_value = str(int(value, 0))
+
+ # Where we calculate the friendly name
+ friendly = identifier[len(AID.PREFIX):].lower()
+ self.friendly = AID._fixup_friendly(friendly)
+
+ def __eq__(self, other):
+
+ return self.identifier == other.identifier \
+ and self.value == other.value and self.found == other.found \
+ and self.normalized_value == other.normalized_value
+
+ @staticmethod
+ def is_friendly(name):
+ """Determines if an AID is a freindly name or C define.
+
+ For example if name is AID_SYSTEM it returns false, if name
+ was system, it would return true.
+
+ Returns:
+ True if name is a friendly name False otherwise.
+ """
+
+ return not name.startswith(AID.PREFIX)
+
+ @staticmethod
+ def _fixup_friendly(friendly):
+ """Fixup friendly names that historically don't follow the convention.
+
+ Args:
+ friendly (str): The friendly name.
+
+ Returns:
+ The fixedup friendly name as a str.
+ """
+
+ if friendly in AID._FIXUPS:
+ return AID._FIXUPS[friendly]
+
+ return friendly
+
+
+class FSConfig(object):
+ """Represents a filesystem config array entry.
+
+ Represents a file system configuration entry for specifying
+ file system capabilities.
+
+ Attributes:
+ mode (str): The mode of the file or directory.
+ user (str): The uid or #define identifier (AID_SYSTEM)
+ group (str): The gid or #define identifier (AID_SYSTEM)
+ caps (str): The capability set.
+ filename (str): The file it was found in.
+ """
+
+ def __init__(self, mode, user, group, caps, path, filename):
+ """
+ Args:
+ mode (str): The mode of the file or directory.
+ user (str): The uid or #define identifier (AID_SYSTEM)
+ group (str): The gid or #define identifier (AID_SYSTEM)
+ caps (str): The capability set as a list.
+ filename (str): The file it was found in.
+ """
+ self.mode = mode
+ self.user = user
+ self.group = group
+ self.caps = caps
+ self.path = path
+ self.filename = filename
+
+ def __eq__(self, other):
+
+ return self.mode == other.mode and self.user == other.user \
+ and self.group == other.group and self.caps == other.caps \
+ and self.path == other.path and self.filename == other.filename
+
+
+class AIDHeaderParser(object):
+ """Parses an android_filesystem_config.h file.
+
+ Parses a C header file and extracts lines starting with #define AID_<name>
+ while capturing the OEM defined ranges and ignoring other ranges. It also
+ skips some hardcoded AIDs it doesn't need to generate a mapping for.
+ It provides some basic sanity checks. The information extracted from this
+ file can later be used to sanity check other things (like oem ranges) as
+ well as generating a mapping of names to uids. It was primarily designed to
+ parse the private/android_filesystem_config.h, but any C header should
+ work.
+ """
+
+
+ _SKIP_AIDS = [
+ re.compile(r'%sUNUSED[0-9].*' % AID.PREFIX),
+ re.compile(r'%sAPP' % AID.PREFIX), re.compile(r'%sUSER' % AID.PREFIX)
+ ]
+ _AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % AID.PREFIX)
+ _OEM_START_KW = 'START'
+ _OEM_END_KW = 'END'
+ _OEM_RANGE = re.compile('%sOEM_RESERVED_[0-9]*_{0,1}(%s|%s)' %
+ (AID.PREFIX, _OEM_START_KW, _OEM_END_KW))
+ # AID lines cannot end with _START or _END, ie AID_FOO is OK
+ # but AID_FOO_START is skiped. Note that AID_FOOSTART is NOT skipped.
+ _AID_SKIP_RANGE = ['_' + _OEM_START_KW, '_' + _OEM_END_KW]
+ _COLLISION_OK = ['AID_APP', 'AID_APP_START', 'AID_USER', 'AID_USER_OFFSET']
+
+ def __init__(self, aid_header):
+ """
+ Args:
+ aid_header (str): file name for the header
+ file containing AID entries.
+ """
+ self._aid_header = aid_header
+ self._aid_name_to_value = {}
+ self._aid_value_to_name = {}
+ self._oem_ranges = {}
+
+ with open(aid_header) as open_file:
+ self._parse(open_file)
+
+ try:
+ self._process_and_check()
+ except ValueError as exception:
+ sys.exit('Error processing parsed data: "%s"' % (str(exception)))
+
+ def _parse(self, aid_file):
+ """Parses an AID header file. Internal use only.
+
+ Args:
+ aid_file (file): The open AID header file to parse.
+ """
+
+ for lineno, line in enumerate(aid_file):
+
+ def error_message(msg):
+ """Creates an error message with the current parsing state."""
+ # pylint: disable=cell-var-from-loop
+ return 'Error "{}" in file: "{}" on line: {}'.format(
+ msg, self._aid_header, str(lineno))
+
+ if AIDHeaderParser._AID_DEFINE.match(line):
+ chunks = line.split()
+ identifier = chunks[1]
+ value = chunks[2]
+
+ if any(x.match(identifier) for x in AIDHeaderParser._SKIP_AIDS):
+ continue
+
+ try:
+ if AIDHeaderParser._is_oem_range(identifier):
+ self._handle_oem_range(identifier, value)
+ elif not any(
+ identifier.endswith(x)
+ for x in AIDHeaderParser._AID_SKIP_RANGE):
+ self._handle_aid(identifier, value)
+ except ValueError as exception:
+ sys.exit(
+ error_message('{} for "{}"'.format(exception,
+ identifier)))
+
+ def _handle_aid(self, identifier, value):
+ """Handle an AID C #define.
+
+ Handles an AID, sanity checking, generating the friendly name and
+ adding it to the internal maps. Internal use only.
+
+ Args:
+ identifier (str): The name of the #define identifier. ie AID_FOO.
+ value (str): The value associated with the identifier.
+
+ Raises:
+ ValueError: With message set to indicate the error.
+ """
+
+ aid = AID(identifier, value, self._aid_header)
+
+ # duplicate name
+ if aid.friendly in self._aid_name_to_value:
+ raise ValueError('Duplicate aid "%s"' % identifier)
+
+ if value in self._aid_value_to_name and aid.identifier not in AIDHeaderParser._COLLISION_OK:
+ raise ValueError('Duplicate aid value "%s" for %s' % (value,
+ identifier))
+
+ self._aid_name_to_value[aid.friendly] = aid
+ self._aid_value_to_name[value] = aid.friendly
+
+ def _handle_oem_range(self, identifier, value):
+ """Handle an OEM range C #define.
+
+ When encountering special AID defines, notably for the OEM ranges
+ this method handles sanity checking and adding them to the internal
+ maps. For internal use only.
+
+ Args:
+ identifier (str): The name of the #define identifier.
+ ie AID_OEM_RESERVED_START/END.
+ value (str): The value associated with the identifier.
+
+ Raises:
+ ValueError: With message set to indicate the error.
+ """
+
+ try:
+ int_value = int(value, 0)
+ except ValueError:
+ raise ValueError(
+ 'Could not convert "%s" to integer value, got: "%s"' %
+ (identifier, value))
+
+ # convert AID_OEM_RESERVED_START or AID_OEM_RESERVED_<num>_START
+ # to AID_OEM_RESERVED or AID_OEM_RESERVED_<num>
+ is_start = identifier.endswith(AIDHeaderParser._OEM_START_KW)
+
+ if is_start:
+ tostrip = len(AIDHeaderParser._OEM_START_KW)
+ else:
+ tostrip = len(AIDHeaderParser._OEM_END_KW)
+
+ # ending _
+ tostrip = tostrip + 1
+
+ strip = identifier[:-tostrip]
+ if strip not in self._oem_ranges:
+ self._oem_ranges[strip] = []
+
+ if len(self._oem_ranges[strip]) > 2:
+ raise ValueError('Too many same OEM Ranges "%s"' % identifier)
+
+ if len(self._oem_ranges[strip]) == 1:
+ tmp = self._oem_ranges[strip][0]
+
+ if tmp == int_value:
+ raise ValueError('START and END values equal %u' % int_value)
+ elif is_start and tmp < int_value:
+ raise ValueError('END value %u less than START value %u' %
+ (tmp, int_value))
+ elif not is_start and tmp > int_value:
+ raise ValueError('END value %u less than START value %u' %
+ (int_value, tmp))
+
+ # Add START values to the head of the list and END values at the end.
+ # Thus, the list is ordered with index 0 as START and index 1 as END.
+ if is_start:
+ self._oem_ranges[strip].insert(0, int_value)
+ else:
+ self._oem_ranges[strip].append(int_value)
+
+ def _process_and_check(self):
+ """Process, check and populate internal data structures.
+
+ After parsing and generating the internal data structures, this method
+ is responsible for sanity checking ALL of the acquired data.
+
+ Raises:
+ ValueError: With the message set to indicate the specific error.
+ """
+
+ # tuplefy the lists since range() does not like them mutable.
+ self._oem_ranges = [
+ AIDHeaderParser._convert_lst_to_tup(k, v)
+ for k, v in self._oem_ranges.iteritems()
+ ]
+
+ # Check for overlapping ranges
+ for i, range1 in enumerate(self._oem_ranges):
+ for range2 in self._oem_ranges[i + 1:]:
+ if AIDHeaderParser._is_overlap(range1, range2):
+ raise ValueError("Overlapping OEM Ranges found %s and %s" %
+ (str(range1), str(range2)))
+
+ # No core AIDs should be within any oem range.
+ for aid in self._aid_value_to_name:
+
+ if Utils.in_any_range(aid, self._oem_ranges):
+ name = self._aid_value_to_name[aid]
+ raise ValueError(
+ 'AID "%s" value: %u within reserved OEM Range: "%s"' %
+ (name, aid, str(self._oem_ranges)))
+
+ @property
+ def oem_ranges(self):
+ """Retrieves the OEM closed ranges as a list of tuples.
+
+ Returns:
+ A list of closed range tuples: [ (0, 42), (50, 105) ... ]
+ """
+ return self._oem_ranges
+
+ @property
+ def aids(self):
+ """Retrieves the list of found AIDs.
+
+ Returns:
+ A list of AID() objects.
+ """
+ return self._aid_name_to_value.values()
+
+ @staticmethod
+ def _convert_lst_to_tup(name, lst):
+ """Converts a mutable list to a non-mutable tuple.
+
+ Used ONLY for ranges and thus enforces a length of 2.
+
+ Args:
+ lst (List): list that should be "tuplefied".
+
+ Raises:
+ ValueError if lst is not a list or len is not 2.
+
+ Returns:
+ Tuple(lst)
+ """
+ if not lst or len(lst) != 2:
+ raise ValueError('Mismatched range for "%s"' % name)
+
+ return tuple(lst)
+
+ @staticmethod
+ def _is_oem_range(aid):
+ """Detects if a given aid is within the reserved OEM range.
+
+ Args:
+ aid (int): The aid to test
+
+ Returns:
+ True if it is within the range, False otherwise.
+ """
+
+ return AIDHeaderParser._OEM_RANGE.match(aid)
+
+ @staticmethod
+ def _is_overlap(range_a, range_b):
+ """Calculates the overlap of two range tuples.
+
+ A range tuple is a closed range. A closed range includes its endpoints.
+ Note that python tuples use () notation which collides with the
+ mathematical notation for open ranges.
+
+ Args:
+ range_a: The first tuple closed range eg (0, 5).
+ range_b: The second tuple closed range eg (3, 7).
+
+ Returns:
+ True if they overlap, False otherwise.
+ """
+
+ return max(range_a[0], range_b[0]) <= min(range_a[1], range_b[1])
+
+
+class FSConfigFileParser(object):
+ """Parses a config.fs ini format file.
+
+ This class is responsible for parsing the config.fs ini format files.
+ It collects and checks all the data in these files and makes it available
+ for consumption post processed.
+ """
+
+ # These _AID vars work together to ensure that an AID section name
+ # cannot contain invalid characters for a C define or a passwd/group file.
+ # Since _AID_PREFIX is within the set of _AID_MATCH the error logic only
+ # checks end, if you change this, you may have to update the error
+ # detection code.
+ _AID_MATCH = re.compile('%s[A-Z0-9_]+' % AID.PREFIX)
+ _AID_ERR_MSG = 'Expecting upper case, a number or underscore'
+
+ # list of handler to required options, used to identify the
+ # parsing section
+ _SECTIONS = [('_handle_aid', ('value',)),
+ ('_handle_path', ('mode', 'user', 'group', 'caps'))]
+
+ def __init__(self, config_files, oem_ranges):
+ """
+ Args:
+ config_files ([str]): The list of config.fs files to parse.
+ Note the filename is not important.
+ oem_ranges ([(),()]): range tuples indicating reserved OEM ranges.
+ """
+
+ self._files = []
+ self._dirs = []
+ self._aids = []
+
+ self._seen_paths = {}
+ # (name to file, value to aid)
+ self._seen_aids = ({}, {})
+
+ self._oem_ranges = oem_ranges
+
+ self._config_files = config_files
+
+ for config_file in self._config_files:
+ self._parse(config_file)
+
+ def _parse(self, file_name):
+ """Parses and verifies config.fs files. Internal use only.
+
+ Args:
+ file_name (str): The config.fs (PythonConfigParser file format)
+ file to parse.
+
+ Raises:
+ Anything raised by ConfigParser.read()
+ """
+
+ # Separate config parsers for each file found. If you use
+ # read(filenames...) later files can override earlier files which is
+ # not what we want. Track state across files and enforce with
+ # _handle_dup(). Note, strict ConfigParser is set to true in
+ # Python >= 3.2, so in previous versions same file sections can
+ # override previous
+ # sections.
+
+ config = ConfigParser.ConfigParser()
+ config.read(file_name)
+
+ for section in config.sections():
+
+ found = False
+
+ for test in FSConfigFileParser._SECTIONS:
+ handler = test[0]
+ options = test[1]
+
+ if all([config.has_option(section, item) for item in options]):
+ handler = getattr(self, handler)
+ handler(file_name, section, config)
+ found = True
+ break
+
+ if not found:
+ sys.exit('Invalid section "%s" in file: "%s"' %
+ (section, file_name))
+
+ # sort entries:
+ # * specified path before prefix match
+ # ** ie foo before f*
+ # * lexicographical less than before other
+ # ** ie boo before foo
+ # Given these paths:
+ # paths=['ac', 'a', 'acd', 'an', 'a*', 'aa', 'ac*']
+ # The sort order would be:
+ # paths=['a', 'aa', 'ac', 'acd', 'an', 'ac*', 'a*']
+ # Thus the fs_config tools will match on specified paths before
+ # attempting prefix, and match on the longest matching prefix.
+ self._files.sort(key=FSConfigFileParser._file_key)
+
+ # sort on value of (file_name, name, value, strvalue)
+ # This is only cosmetic so AIDS are arranged in ascending order
+ # within the generated file.
+ self._aids.sort(key=lambda item: item.normalized_value)
+
+ def _handle_aid(self, file_name, section_name, config):
+ """Verifies an AID entry and adds it to the aid list.
+
+ Calls sys.exit() with a descriptive message of the failure.
+
+ Args:
+ file_name (str): The filename of the config file being parsed.
+ section_name (str): The section name currently being parsed.
+ config (ConfigParser): The ConfigParser section being parsed that
+ the option values will come from.
+ """
+
+ def error_message(msg):
+ """Creates an error message with current parsing state."""
+ return '{} for: "{}" file: "{}"'.format(msg, section_name,
+ file_name)
+
+ FSConfigFileParser._handle_dup_and_add('AID', file_name, section_name,
+ self._seen_aids[0])
+
+ match = FSConfigFileParser._AID_MATCH.match(section_name)
+ invalid = match.end() if match else len(AID.PREFIX)
+ if invalid != len(section_name):
+ tmp_errmsg = ('Invalid characters in AID section at "%d" for: "%s"'
+ % (invalid, FSConfigFileParser._AID_ERR_MSG))
+ sys.exit(error_message(tmp_errmsg))
+
+ value = config.get(section_name, 'value')
+
+ if not value:
+ sys.exit(error_message('Found specified but unset "value"'))
+
+ try:
+ aid = AID(section_name, value, file_name)
+ except ValueError:
+ sys.exit(
+ error_message('Invalid "value", not aid number, got: \"%s\"' %
+ value))
+
+ # Values must be within OEM range
+ if not Utils.in_any_range(int(aid.value, 0), self._oem_ranges):
+ emsg = '"value" not in valid range %s, got: %s'
+ emsg = emsg % (str(self._oem_ranges), value)
+ sys.exit(error_message(emsg))
+
+ # use the normalized int value in the dict and detect
+ # duplicate definitions of the same value
+ FSConfigFileParser._handle_dup_and_add(
+ 'AID', file_name, aid.normalized_value, self._seen_aids[1])
+
+ # Append aid tuple of (AID_*, base10(value), _path(value))
+ # We keep the _path version of value so we can print that out in the
+ # generated header so investigating parties can identify parts.
+ # We store the base10 value for sorting, so everything is ascending
+ # later.
+ self._aids.append(aid)
+
+ def _handle_path(self, file_name, section_name, config):
+ """Add a file capability entry to the internal list.
+
+ Handles a file capability entry, verifies it, and adds it to
+ to the internal dirs or files list based on path. If it ends
+ with a / its a dir. Internal use only.
+
+ Calls sys.exit() on any validation error with message set.
+
+ Args:
+ file_name (str): The current name of the file being parsed.
+ section_name (str): The name of the section to parse.
+ config (str): The config parser.
+ """
+
+ FSConfigFileParser._handle_dup_and_add('path', file_name, section_name,
+ self._seen_paths)
+
+ mode = config.get(section_name, 'mode')
+ user = config.get(section_name, 'user')
+ group = config.get(section_name, 'group')
+ caps = config.get(section_name, 'caps')
+
+ errmsg = ('Found specified but unset option: \"%s" in file: \"' +
+ file_name + '\"')
+
+ if not mode:
+ sys.exit(errmsg % 'mode')
+
+ if not user:
+ sys.exit(errmsg % 'user')
+
+ if not group:
+ sys.exit(errmsg % 'group')
+
+ if not caps:
+ sys.exit(errmsg % 'caps')
+
+ caps = caps.split()
+
+ tmp = []
+ for cap in caps:
+ try:
+ # test if string is int, if it is, use as is.
+ int(cap, 0)
+ tmp.append('(' + cap + ')')
+ except ValueError:
+ tmp.append('CAP_MASK_LONG(CAP_' + cap.upper() + ')')
+
+ caps = tmp
+
+ if len(mode) == 3:
+ mode = '0' + mode
+
+ try:
+ int(mode, 8)
+ except ValueError:
+ sys.exit('Mode must be octal characters, got: "%s"' % mode)
+
+ if len(mode) != 4:
+ sys.exit('Mode must be 3 or 4 characters, got: "%s"' % mode)
+
+ caps_str = '|'.join(caps)
+
+ entry = FSConfig(mode, user, group, caps_str, section_name, file_name)
+ if section_name[-1] == '/':
+ self._dirs.append(entry)
+ else:
+ self._files.append(entry)
+
+ @property
+ def files(self):
+ """Get the list of FSConfig file entries.
+
+ Returns:
+ a list of FSConfig() objects for file paths.
+ """
+ return self._files
+
+ @property
+ def dirs(self):
+ """Get the list of FSConfig dir entries.
+
+ Returns:
+ a list of FSConfig() objects for directory paths.
+ """
+ return self._dirs
+
+ @property
+ def aids(self):
+ """Get the list of AID entries.
+
+ Returns:
+ a list of AID() objects.
+ """
+ return self._aids
+
+ @staticmethod
+ def _file_key(fs_config):
+ """Used as the key paramter to sort.
+
+ This is used as a the function to the key parameter of a sort.
+ it wraps the string supplied in a class that implements the
+ appropriate __lt__ operator for the sort on path strings. See
+ StringWrapper class for more details.
+
+ Args:
+ fs_config (FSConfig): A FSConfig entry.
+
+ Returns:
+ A StringWrapper object
+ """
+
+ # Wrapper class for custom prefix matching strings
+ class StringWrapper(object):
+ """Wrapper class used for sorting prefix strings.
+
+ The algorithm is as follows:
+ - specified path before prefix match
+ - ie foo before f*
+ - lexicographical less than before other
+ - ie boo before foo
+
+ Given these paths:
+ paths=['ac', 'a', 'acd', 'an', 'a*', 'aa', 'ac*']
+ The sort order would be:
+ paths=['a', 'aa', 'ac', 'acd', 'an', 'ac*', 'a*']
+ Thus the fs_config tools will match on specified paths before
+ attempting prefix, and match on the longest matching prefix.
+ """
+
+ def __init__(self, path):
+ """
+ Args:
+ path (str): the path string to wrap.
+ """
+ self.is_prefix = path[-1] == '*'
+ if self.is_prefix:
+ self.path = path[:-1]
+ else:
+ self.path = path
+
+ def __lt__(self, other):
+
+ # if were both suffixed the smallest string
+ # is 'bigger'
+ if self.is_prefix and other.is_prefix:
+ result = len(self.path) > len(other.path)
+ # If I am an the suffix match, im bigger
+ elif self.is_prefix:
+ result = False
+ # If other is the suffix match, he's bigger
+ elif other.is_prefix:
+ result = True
+ # Alphabetical
+ else:
+ result = self.path < other.path
+ return result
+
+ return StringWrapper(fs_config.path)
+
+ @staticmethod
+ def _handle_dup_and_add(name, file_name, section_name, seen):
+ """Tracks and detects duplicates. Internal use only.
+
+ Calls sys.exit() on a duplicate.
+
+ Args:
+ name (str): The name to use in the error reporting. The pretty
+ name for the section.
+ file_name (str): The file currently being parsed.
+ section_name (str): The name of the section. This would be path
+ or identifier depending on what's being parsed.
+ seen (dict): The dictionary of seen things to check against.
+ """
+ if section_name in seen:
+ dups = '"' + seen[section_name] + '" and '
+ dups += file_name
+ sys.exit('Duplicate %s "%s" found in files: %s' %
+ (name, section_name, dups))
+
+ seen[section_name] = file_name
+
+
+class BaseGenerator(object):
+ """Interface for Generators.
+
+ Base class for generators, generators should implement
+ these method stubs.
+ """
+
+ def add_opts(self, opt_group):
+ """Used to add per-generator options to the command line.
+
+ Args:
+ opt_group (argument group object): The argument group to append to.
+ See the ArgParse docs for more details.
+ """
+
+ raise NotImplementedError("Not Implemented")
+
+ def __call__(self, args):
+ """This is called to do whatever magic the generator does.
+
+ Args:
+ args (dict): The arguments from ArgParse as a dictionary.
+ ie if you specified an argument of foo in add_opts, access
+ it via args['foo']
+ """
+
+ raise NotImplementedError("Not Implemented")
+
+
+@generator('fsconfig')
+class FSConfigGen(BaseGenerator):
+ """Generates the android_filesystem_config.h file.
+
+ Output is used in generating fs_config_files and fs_config_dirs.
+ """
+
+ _GENERATED = textwrap.dedent("""\
+ /*
+ * THIS IS AN AUTOGENERATED FILE! DO NOT MODIFY
+ */
+ """)
+
+ _INCLUDES = [
+ '<private/android_filesystem_config.h>', '"generated_oem_aid.h"'
+ ]
+
+ _DEFINE_NO_DIRS = '#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS'
+ _DEFINE_NO_FILES = '#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES'
+
+ _DEFAULT_WARNING = (
+ '#warning No device-supplied android_filesystem_config.h,'
+ ' using empty default.')
+
+ # Long names.
+ # pylint: disable=invalid-name
+ _NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS_ENTRY = (
+ '{ 00000, AID_ROOT, AID_ROOT, 0,'
+ '"system/etc/fs_config_dirs" },')
+
+ _NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES_ENTRY = (
+ '{ 00000, AID_ROOT, AID_ROOT, 0,'
+ '"system/etc/fs_config_files" },')
+
+ _IFDEF_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS = (
+ '#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS')
+ # pylint: enable=invalid-name
+
+ _ENDIF = '#endif'
+
+ _OPEN_FILE_STRUCT = (
+ 'static const struct fs_path_config android_device_files[] = {')
+
+ _OPEN_DIR_STRUCT = (
+ 'static const struct fs_path_config android_device_dirs[] = {')
+
+ _CLOSE_FILE_STRUCT = '};'
+
+ _GENERIC_DEFINE = "#define %s\t%s"
+
+ _FILE_COMMENT = '// Defined in file: \"%s\"'
+
+ def __init__(self, *args, **kwargs):
+ BaseGenerator.__init__(args, kwargs)
+
+ self._oem_parser = None
+ self._base_parser = None
+ self._friendly_to_aid = None
+
+ def add_opts(self, opt_group):
+
+ opt_group.add_argument(
+ 'fsconfig', nargs='+', help='The list of fsconfig files to parse')
+
+ opt_group.add_argument(
+ '--aid-header',
+ required=True,
+ help='An android_filesystem_config.h file'
+ ' to parse AIDs and OEM Ranges from')
+
+ def __call__(self, args):
+
+ self._base_parser = AIDHeaderParser(args['aid_header'])
+ self._oem_parser = FSConfigFileParser(args['fsconfig'],
+ self._base_parser.oem_ranges)
+ base_aids = self._base_parser.aids
+ oem_aids = self._oem_parser.aids
+
+ # Detect name collisions on AIDs. Since friendly works as the
+ # identifier for collision testing and we need friendly later on for
+ # name resolution, just calculate and use friendly.
+ # {aid.friendly: aid for aid in base_aids}
+ base_friendly = {aid.friendly: aid for aid in base_aids}
+ oem_friendly = {aid.friendly: aid for aid in oem_aids}
+
+ base_set = set(base_friendly.keys())
+ oem_set = set(oem_friendly.keys())
+
+ common = base_set & oem_set
+
+ if len(common) > 0:
+ emsg = 'Following AID Collisions detected for: \n'
+ for friendly in common:
+ base = base_friendly[friendly]
+ oem = oem_friendly[friendly]
+ emsg += (
+ 'Identifier: "%s" Friendly Name: "%s" '
+ 'found in file "%s" and "%s"' %
+ (base.identifier, base.friendly, base.found, oem.found))
+ sys.exit(emsg)
+
+ self._friendly_to_aid = oem_friendly
+ self._friendly_to_aid.update(base_friendly)
+
+ self._generate()
+
+ def _to_fs_entry(self, fs_config):
+ """Converts an FSConfig entry to an fs entry.
+
+ Prints '{ mode, user, group, caps, "path" },'.
+
+ Calls sys.exit() on error.
+
+ Args:
+ fs_config (FSConfig): The entry to convert to
+ a valid C array entry.
+ """
+
+ # Get some short names
+ mode = fs_config.mode
+ user = fs_config.user
+ group = fs_config.group
+ fname = fs_config.filename
+ caps = fs_config.caps
+ path = fs_config.path
+
+ emsg = 'Cannot convert friendly name "%s" to identifier!'
+
+ # remap friendly names to identifier names
+ if AID.is_friendly(user):
+ if user not in self._friendly_to_aid:
+ sys.exit(emsg % user)
+ user = self._friendly_to_aid[user].identifier
+
+ if AID.is_friendly(group):
+ if group not in self._friendly_to_aid:
+ sys.exit(emsg % group)
+ group = self._friendly_to_aid[group].identifier
+
+ fmt = '{ %s, %s, %s, %s, "%s" },'
+
+ expanded = fmt % (mode, user, group, caps, path)
+
+ print FSConfigGen._FILE_COMMENT % fname
+ print ' ' + expanded
+
+ @staticmethod
+ def _gen_inc():
+ """Generate the include header lines and print to stdout."""
+ for include in FSConfigGen._INCLUDES:
+ print '#include %s' % include
+
+ def _generate(self):
+ """Generates an OEM android_filesystem_config.h header file to stdout.
+
+ Args:
+ files ([FSConfig]): A list of FSConfig objects for file entries.
+ dirs ([FSConfig]): A list of FSConfig objects for directory
+ entries.
+ aids ([AIDS]): A list of AID objects for Android Id entries.
+ """
+ print FSConfigGen._GENERATED
+ print
+
+ FSConfigGen._gen_inc()
+ print
+
+ dirs = self._oem_parser.dirs
+ files = self._oem_parser.files
+ aids = self._oem_parser.aids
+
+ are_dirs = len(dirs) > 0
+ are_files = len(files) > 0
+ are_aids = len(aids) > 0
+
+ if are_aids:
+ for aid in aids:
+ # use the preserved _path value
+ print FSConfigGen._FILE_COMMENT % aid.found
+ print FSConfigGen._GENERIC_DEFINE % (aid.identifier, aid.value)
+
+ print
+
+ if not are_dirs:
+ print FSConfigGen._DEFINE_NO_DIRS + '\n'
+
+ if not are_files:
+ print FSConfigGen._DEFINE_NO_FILES + '\n'
+
+ if not are_files and not are_dirs and not are_aids:
+ return
+
+ if are_files:
+ print FSConfigGen._OPEN_FILE_STRUCT
+ for fs_config in files:
+ self._to_fs_entry(fs_config)
+
+ if not are_dirs:
+ print FSConfigGen._IFDEF_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+ print(
+ ' ' +
+ FSConfigGen._NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS_ENTRY)
+ print FSConfigGen._ENDIF
+ print FSConfigGen._CLOSE_FILE_STRUCT
+
+ if are_dirs:
+ print FSConfigGen._OPEN_DIR_STRUCT
+ for dir_entry in dirs:
+ self._to_fs_entry(dir_entry)
+
+ print FSConfigGen._CLOSE_FILE_STRUCT
+
+
+@generator('aidarray')
+class AIDArrayGen(BaseGenerator):
+ """Generates the android_id static array."""
+
+ _GENERATED = ('/*\n'
+ ' * THIS IS AN AUTOGENERATED FILE! DO NOT MODIFY!\n'
+ ' */')
+
+ _INCLUDE = '#include <private/android_filesystem_config.h>'
+
+ _STRUCT_FS_CONFIG = textwrap.dedent("""
+ struct android_id_info {
+ const char *name;
+ unsigned aid;
+ };""")
+
+ _OPEN_ID_ARRAY = 'static const struct android_id_info android_ids[] = {'
+
+ _ID_ENTRY = ' { "%s", %s },'
+
+ _CLOSE_FILE_STRUCT = '};'
+
+ _COUNT = ('#define android_id_count \\\n'
+ ' (sizeof(android_ids) / sizeof(android_ids[0]))')
+
+ def add_opts(self, opt_group):
+
+ opt_group.add_argument(
+ 'hdrfile', help='The android_filesystem_config.h'
+ 'file to parse')
+
+ def __call__(self, args):
+
+ hdr = AIDHeaderParser(args['hdrfile'])
+
+ print AIDArrayGen._GENERATED
+ print
+ print AIDArrayGen._INCLUDE
+ print
+ print AIDArrayGen._STRUCT_FS_CONFIG
+ print
+ print AIDArrayGen._OPEN_ID_ARRAY
+
+ for aid in hdr.aids:
+ print AIDArrayGen._ID_ENTRY % (aid.friendly, aid.identifier)
+
+ print AIDArrayGen._CLOSE_FILE_STRUCT
+ print
+ print AIDArrayGen._COUNT
+ print
+
+
+@generator('oemaid')
+class OEMAidGen(BaseGenerator):
+ """Generates the OEM AID_<name> value header file."""
+
+ _GENERATED = ('/*\n'
+ ' * THIS IS AN AUTOGENERATED FILE! DO NOT MODIFY!\n'
+ ' */')
+
+ _GENERIC_DEFINE = "#define %s\t%s"
+
+ _FILE_COMMENT = '// Defined in file: \"%s\"'
+
+ # Intentional trailing newline for readability.
+ _FILE_IFNDEF_DEFINE = ('#ifndef GENERATED_OEM_AIDS_H_\n'
+ '#define GENERATED_OEM_AIDS_H_\n')
+
+ _FILE_ENDIF = '#endif'
+
+ def __init__(self):
+
+ self._old_file = None
+
+ def add_opts(self, opt_group):
+
+ opt_group.add_argument(
+ 'fsconfig', nargs='+', help='The list of fsconfig files to parse.')
+
+ opt_group.add_argument(
+ '--aid-header',
+ required=True,
+ help='An android_filesystem_config.h file'
+ 'to parse AIDs and OEM Ranges from')
+
+ def __call__(self, args):
+
+ hdr_parser = AIDHeaderParser(args['aid_header'])
+
+ parser = FSConfigFileParser(args['fsconfig'], hdr_parser.oem_ranges)
+
+ print OEMAidGen._GENERATED
+
+ print OEMAidGen._FILE_IFNDEF_DEFINE
+
+ for aid in parser.aids:
+ self._print_aid(aid)
+ print
+
+ print OEMAidGen._FILE_ENDIF
+
+ def _print_aid(self, aid):
+ """Prints a valid #define AID identifier to stdout.
+
+ Args:
+ aid to print
+ """
+
+ # print the source file location of the AID
+ found_file = aid.found
+ if found_file != self._old_file:
+ print OEMAidGen._FILE_COMMENT % found_file
+ self._old_file = found_file
+
+ print OEMAidGen._GENERIC_DEFINE % (aid.identifier, aid.value)
+
+
+@generator('passwd')
+class PasswdGen(BaseGenerator):
+ """Generates the /etc/passwd file per man (5) passwd."""
+
+ _GENERATED = ('#\n# THIS IS AN AUTOGENERATED FILE! DO NOT MODIFY!\n#')
+
+ _FILE_COMMENT = '# Defined in file: \"%s\"'
+
+ def __init__(self):
+
+ self._old_file = None
+
+ def add_opts(self, opt_group):
+
+ opt_group.add_argument(
+ 'fsconfig', nargs='+', help='The list of fsconfig files to parse.')
+
+ opt_group.add_argument(
+ '--aid-header',
+ required=True,
+ help='An android_filesystem_config.h file'
+ 'to parse AIDs and OEM Ranges from')
+
+ def __call__(self, args):
+
+ hdr_parser = AIDHeaderParser(args['aid_header'])
+
+ parser = FSConfigFileParser(args['fsconfig'], hdr_parser.oem_ranges)
+
+ aids = parser.aids
+
+ # nothing to do if no aids defined
+ if len(aids) == 0:
+ return
+
+ print PasswdGen._GENERATED
+
+ for aid in aids:
+ self._print_formatted_line(aid)
+
+ def _print_formatted_line(self, aid):
+ """Prints the aid to stdout in the passwd format. Internal use only.
+
+ Colon delimited:
+ login name, friendly name
+ encrypted password (optional)
+ uid (int)
+ gid (int)
+ User name or comment field
+ home directory
+ interpreter (optional)
+
+ Args:
+ aid (AID): The aid to print.
+ """
+ if self._old_file != aid.found:
+ self._old_file = aid.found
+ print PasswdGen._FILE_COMMENT % aid.found
+
+ try:
+ logon, uid = Utils.get_login_and_uid_cleansed(aid)
+ except ValueError as exception:
+ sys.exit(exception)
+
+ print "%s::%s:%s::/:/system/bin/sh" % (logon, uid, uid)
+
+
+@generator('group')
+class GroupGen(PasswdGen):
+ """Generates the /etc/group file per man (5) group."""
+
+ # Overrides parent
+ def _print_formatted_line(self, aid):
+ """Prints the aid to stdout in the group format. Internal use only.
+
+ Formatted (per man 5 group) like:
+ group_name:password:GID:user_list
+
+ Args:
+ aid (AID): The aid to print.
+ """
+ if self._old_file != aid.found:
+ self._old_file = aid.found
+ print PasswdGen._FILE_COMMENT % aid.found
+
+ try:
+ logon, uid = Utils.get_login_and_uid_cleansed(aid)
+ except ValueError as exception:
+ sys.exit(exception)
+
+ print "%s::%s:" % (logon, uid)
+
+
+def main():
+ """Main entry point for execution."""
+
+ opt_parser = argparse.ArgumentParser(
+ description='A tool for parsing fsconfig config files and producing' +
+ 'digestable outputs.')
+ subparser = opt_parser.add_subparsers(help='generators')
+
+ gens = generator.get()
+
+ # for each gen, instantiate and add them as an option
+ for name, gen in gens.iteritems():
+
+ generator_option_parser = subparser.add_parser(name, help=gen.__doc__)
+ generator_option_parser.set_defaults(which=name)
+
+ opt_group = generator_option_parser.add_argument_group(name +
+ ' options')
+ gen.add_opts(opt_group)
+
+ args = opt_parser.parse_args()
+
+ args_as_dict = vars(args)
+ which = args_as_dict['which']
+ del args_as_dict['which']
+
+ gens[which](args_as_dict)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/fs_config/fs_config_test.cpp b/tools/fs_config/fs_config_test.cpp
new file mode 100644
index 0000000..f95a4ca
--- /dev/null
+++ b/tools/fs_config/fs_config_test.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <sys/cdefs.h>
+
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/macros.h>
+#include <android-base/strings.h>
+#include <android-base/stringprintf.h>
+#include <gtest/gtest.h>
+#include <private/android_filesystem_config.h>
+#include <private/fs_config.h>
+
+#include "android_filesystem_config_test_data.h"
+
+// must run test in the test directory
+const static char fs_config_generate_command[] = "./fs_config_generate_test";
+
+static std::string popenToString(std::string command) {
+ std::string ret;
+
+ FILE* fp = popen(command.c_str(), "r");
+ if (fp) {
+ if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = "";
+ pclose(fp);
+ }
+ return ret;
+}
+
+static void confirm(std::string&& data, const fs_path_config* config,
+ ssize_t num_config) {
+ const struct fs_path_config_from_file* pc =
+ reinterpret_cast<const fs_path_config_from_file*>(data.c_str());
+ size_t len = data.size();
+
+ ASSERT_TRUE(config != NULL);
+ ASSERT_LT(0, num_config);
+
+ while (len > 0) {
+ uint16_t host_len = pc->len;
+ if (host_len > len) break;
+
+ EXPECT_EQ(config->mode, pc->mode);
+ EXPECT_EQ(config->uid, pc->uid);
+ EXPECT_EQ(config->gid, pc->gid);
+ EXPECT_EQ(config->capabilities, pc->capabilities);
+ EXPECT_STREQ(config->prefix, pc->prefix);
+
+ EXPECT_LT(0, num_config);
+ --num_config;
+ if (num_config >= 0) ++config;
+ pc = reinterpret_cast<const fs_path_config_from_file*>(
+ reinterpret_cast<const char*>(pc) + host_len);
+ len -= host_len;
+ }
+ EXPECT_EQ(0, num_config);
+}
+
+/* See local android_filesystem_config.h for test data */
+
+TEST(fs_conf_test, dirs) {
+ confirm(popenToString(
+ android::base::StringPrintf("%s -D", fs_config_generate_command)),
+ android_device_dirs, arraysize(android_device_dirs));
+}
+
+TEST(fs_conf_test, files) {
+ confirm(popenToString(
+ android::base::StringPrintf("%s -F", fs_config_generate_command)),
+ android_device_files, arraysize(android_device_files));
+}
+
+static const char vendor_str[] = "vendor/";
+static const char vendor_alt_str[] = "system/vendor/";
+static const char oem_str[] = "oem/";
+static const char oem_alt_str[] = "system/oem/";
+static const char odm_str[] = "odm/";
+static const char odm_alt_str[] = "system/odm/";
+
+TEST(fs_conf_test, system_dirs) {
+ std::vector<fs_path_config> dirs;
+ const fs_path_config* config = android_device_dirs;
+ for (size_t num = arraysize(android_device_dirs); num; --num) {
+ if (!android::base::StartsWith(config->prefix, vendor_str) &&
+ !android::base::StartsWith(config->prefix, vendor_alt_str) &&
+ !android::base::StartsWith(config->prefix, oem_str) &&
+ !android::base::StartsWith(config->prefix, oem_alt_str) &&
+ !android::base::StartsWith(config->prefix, odm_str) &&
+ !android::base::StartsWith(config->prefix, odm_alt_str)) {
+ dirs.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -D -P -vendor,-oem,-odm", fs_config_generate_command)),
+ &dirs[0], dirs.size());
+}
+
+TEST(fs_conf_test, vendor_dirs) {
+ std::vector<fs_path_config> dirs;
+ const fs_path_config* config = android_device_dirs;
+ for (size_t num = arraysize(android_device_dirs); num; --num) {
+ if (android::base::StartsWith(config->prefix, vendor_str) ||
+ android::base::StartsWith(config->prefix, vendor_alt_str)) {
+ dirs.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -D -P vendor", fs_config_generate_command)),
+ &dirs[0], dirs.size());
+}
+
+TEST(fs_conf_test, oem_dirs) {
+ std::vector<fs_path_config> dirs;
+ const fs_path_config* config = android_device_dirs;
+ for (size_t num = arraysize(android_device_dirs); num; --num) {
+ if (android::base::StartsWith(config->prefix, oem_str) ||
+ android::base::StartsWith(config->prefix, oem_alt_str)) {
+ dirs.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -D -P oem", fs_config_generate_command)),
+ &dirs[0], dirs.size());
+}
+
+TEST(fs_conf_test, odm_dirs) {
+ std::vector<fs_path_config> dirs;
+ const fs_path_config* config = android_device_dirs;
+ for (size_t num = arraysize(android_device_dirs); num; --num) {
+ if (android::base::StartsWith(config->prefix, odm_str) ||
+ android::base::StartsWith(config->prefix, odm_alt_str)) {
+ dirs.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -D -P odm", fs_config_generate_command)),
+ &dirs[0], dirs.size());
+}
+
+TEST(fs_conf_test, system_files) {
+ std::vector<fs_path_config> files;
+ const fs_path_config* config = android_device_files;
+ for (size_t num = arraysize(android_device_files); num; --num) {
+ if (!android::base::StartsWith(config->prefix, vendor_str) &&
+ !android::base::StartsWith(config->prefix, vendor_alt_str) &&
+ !android::base::StartsWith(config->prefix, oem_str) &&
+ !android::base::StartsWith(config->prefix, oem_alt_str) &&
+ !android::base::StartsWith(config->prefix, odm_str) &&
+ !android::base::StartsWith(config->prefix, odm_alt_str)) {
+ files.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -F -P -vendor,-oem,-odm", fs_config_generate_command)),
+ &files[0], files.size());
+}
+
+TEST(fs_conf_test, vendor_files) {
+ std::vector<fs_path_config> files;
+ const fs_path_config* config = android_device_files;
+ for (size_t num = arraysize(android_device_files); num; --num) {
+ if (android::base::StartsWith(config->prefix, vendor_str) ||
+ android::base::StartsWith(config->prefix, vendor_alt_str)) {
+ files.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -F -P vendor", fs_config_generate_command)),
+ &files[0], files.size());
+}
+
+TEST(fs_conf_test, oem_files) {
+ std::vector<fs_path_config> files;
+ const fs_path_config* config = android_device_files;
+ for (size_t num = arraysize(android_device_files); num; --num) {
+ if (android::base::StartsWith(config->prefix, oem_str) ||
+ android::base::StartsWith(config->prefix, oem_alt_str)) {
+ files.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -F -P oem", fs_config_generate_command)),
+ &files[0], files.size());
+}
+
+TEST(fs_conf_test, odm_files) {
+ std::vector<fs_path_config> files;
+ const fs_path_config* config = android_device_files;
+ for (size_t num = arraysize(android_device_files); num; --num) {
+ if (android::base::StartsWith(config->prefix, odm_str) ||
+ android::base::StartsWith(config->prefix, odm_alt_str)) {
+ files.emplace_back(*config);
+ }
+ ++config;
+ }
+ confirm(popenToString(android::base::StringPrintf(
+ "%s -F -P odm", fs_config_generate_command)),
+ &files[0], files.size());
+}
diff --git a/tools/fs_config/pylintrc b/tools/fs_config/pylintrc
new file mode 100644
index 0000000..3e44870
--- /dev/null
+++ b/tools/fs_config/pylintrc
@@ -0,0 +1,5 @@
+[MESSAGES CONTROL]
+disable=fixme,design,locally-disabled,too-many-lines
+
+[VARIABLES]
+dummy-variables-rgx=_|dummy
diff --git a/tools/fs_config/test_fs_config_generator.py b/tools/fs_config/test_fs_config_generator.py
new file mode 100755
index 0000000..a49058a
--- /dev/null
+++ b/tools/fs_config/test_fs_config_generator.py
@@ -0,0 +1,313 @@
+#!/usr/bin/env python
+"""Unit test suite for the fs_config_genertor.py tool."""
+
+import tempfile
+import textwrap
+import unittest
+
+from fs_config_generator import AID
+from fs_config_generator import AIDHeaderParser
+from fs_config_generator import FSConfigFileParser
+from fs_config_generator import FSConfig
+from fs_config_generator import Utils
+
+
+# Disable protected access so we can test class internal
+# methods. Also, disable invalid-name as some of the
+# class method names are over length.
+# pylint: disable=protected-access,invalid-name
+class Tests(unittest.TestCase):
+ """Test class for unit tests"""
+
+ def test_is_overlap(self):
+ """Test overlap detection helper"""
+
+ self.assertTrue(AIDHeaderParser._is_overlap((0, 1), (1, 2)))
+
+ self.assertTrue(AIDHeaderParser._is_overlap((0, 100), (90, 200)))
+
+ self.assertTrue(AIDHeaderParser._is_overlap((20, 50), (1, 101)))
+
+ self.assertFalse(AIDHeaderParser._is_overlap((0, 100), (101, 200)))
+
+ self.assertFalse(AIDHeaderParser._is_overlap((-10, 0), (10, 20)))
+
+ def test_in_any_range(self):
+ """Test if value in range"""
+
+ self.assertFalse(Utils.in_any_range(50, [(100, 200), (1, 2), (1, 1)]))
+ self.assertFalse(Utils.in_any_range(250, [(100, 200), (1, 2), (1, 1)]))
+
+ self.assertTrue(Utils.in_any_range(100, [(100, 200), (1, 2), (1, 1)]))
+ self.assertTrue(Utils.in_any_range(200, [(100, 200), (1, 2), (1, 1)]))
+ self.assertTrue(Utils.in_any_range(150, [(100, 200)]))
+
+ def test_aid(self):
+ """Test AID class constructor"""
+
+ aid = AID('AID_FOO_BAR', '0xFF', 'myfakefile')
+ self.assertEquals(aid.identifier, 'AID_FOO_BAR')
+ self.assertEquals(aid.value, '0xFF')
+ self.assertEquals(aid.found, 'myfakefile')
+ self.assertEquals(aid.normalized_value, '255')
+ self.assertEquals(aid.friendly, 'foo_bar')
+
+ aid = AID('AID_MEDIA_EX', '1234', 'myfakefile')
+ self.assertEquals(aid.identifier, 'AID_MEDIA_EX')
+ self.assertEquals(aid.value, '1234')
+ self.assertEquals(aid.found, 'myfakefile')
+ self.assertEquals(aid.normalized_value, '1234')
+ self.assertEquals(aid.friendly, 'mediaex')
+
+ def test_aid_header_parser_good(self):
+ """Test AID Header Parser good input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_FOO 1000
+ #define AID_BAR 1001
+ #define SOMETHING "something"
+ #define AID_OEM_RESERVED_START 2900
+ #define AID_OEM_RESERVED_END 2999
+ #define AID_OEM_RESERVED_1_START 7000
+ #define AID_OEM_RESERVED_1_END 8000
+ """))
+ temp_file.flush()
+
+ parser = AIDHeaderParser(temp_file.name)
+ oem_ranges = parser.oem_ranges
+ aids = parser.aids
+
+ self.assertTrue((2900, 2999) in oem_ranges)
+ self.assertFalse((5000, 6000) in oem_ranges)
+
+ for aid in aids:
+ self.assertTrue(aid.normalized_value in ['1000', '1001'])
+ self.assertFalse(aid.normalized_value in ['1', '2', '3'])
+
+ def test_aid_header_parser_good_unordered(self):
+ """Test AID Header Parser good unordered input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_FOO 1000
+ #define AID_OEM_RESERVED_1_END 8000
+ #define AID_BAR 1001
+ #define SOMETHING "something"
+ #define AID_OEM_RESERVED_END 2999
+ #define AID_OEM_RESERVED_1_START 7000
+ #define AID_OEM_RESERVED_START 2900
+ """))
+ temp_file.flush()
+
+ parser = AIDHeaderParser(temp_file.name)
+ oem_ranges = parser.oem_ranges
+ aids = parser.aids
+
+ self.assertTrue((2900, 2999) in oem_ranges)
+ self.assertFalse((5000, 6000) in oem_ranges)
+
+ for aid in aids:
+ self.assertTrue(aid.normalized_value in ['1000', '1001'])
+ self.assertFalse(aid.normalized_value in ['1', '2', '3'])
+
+ def test_aid_header_parser_bad_aid(self):
+ """Test AID Header Parser bad aid input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_FOO "bad"
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ AIDHeaderParser(temp_file.name)
+
+ def test_aid_header_parser_bad_oem_range(self):
+ """Test AID Header Parser bad oem range input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_OEM_RESERVED_START 2900
+ #define AID_OEM_RESERVED_END 1800
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ AIDHeaderParser(temp_file.name)
+
+ def test_aid_header_parser_bad_oem_range_no_end(self):
+ """Test AID Header Parser bad oem range (no end) input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_OEM_RESERVED_START 2900
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ AIDHeaderParser(temp_file.name)
+
+ def test_aid_header_parser_bad_oem_range_no_start(self):
+ """Test AID Header Parser bad oem range (no start) input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_OEM_RESERVED_END 2900
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ AIDHeaderParser(temp_file.name)
+
+ def test_aid_header_parser_bad_oem_range_mismatch_start_end(self):
+ """Test AID Header Parser bad oem range mismatched input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_OEM_RESERVED_START 2900
+ #define AID_OEM_RESERVED_2_END 2900
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ AIDHeaderParser(temp_file.name)
+
+ def test_aid_header_parser_bad_duplicate_ranges(self):
+ """Test AID Header Parser exits cleanly on duplicate AIDs"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_FOO 100
+ #define AID_BAR 100
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ AIDHeaderParser(temp_file.name)
+
+ def test_aid_header_parser_no_bad_aids(self):
+ """Test AID Header Parser that it doesn't contain:
+ Ranges, ie things the end with "_START" or "_END"
+ AID_APP
+ AID_USER
+ For more details see:
+ - https://android-review.googlesource.com/#/c/313024
+ - https://android-review.googlesource.com/#/c/313169
+ """
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ #define AID_APP 10000 /* TODO: switch users over to AID_APP_START */
+ #define AID_APP_START 10000 /* first app user */
+ #define AID_APP_END 19999 /* last app user */
+
+ #define AID_CACHE_GID_START 20000 /* start of gids for apps to mark cached data */
+ #define AID_CACHE_GID_END 29999 /* end of gids for apps to mark cached data */
+
+ #define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
+ #define AID_SHARED_GID_END 59999 /* end of gids for apps in each user to share */
+
+ #define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
+ #define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */
+
+ #define AID_USER 100000 /* TODO: switch users over to AID_USER_OFFSET */
+ #define AID_USER_OFFSET 100000 /* offset for uid ranges for each user */
+ """))
+ temp_file.flush()
+
+ parser = AIDHeaderParser(temp_file.name)
+ aids = parser.aids
+
+ bad_aids = ['_START', '_END', 'AID_APP', 'AID_USER']
+
+ for aid in aids:
+ self.assertFalse(
+ any(bad in aid.identifier for bad in bad_aids),
+ 'Not expecting keywords "%s" in aids "%s"' %
+ (str(bad_aids), str([tmp.identifier for tmp in aids])))
+
+ def test_fs_config_file_parser_good(self):
+ """Test FSConfig Parser good input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ [/system/bin/file]
+ user: AID_FOO
+ group: AID_SYSTEM
+ mode: 0777
+ caps: BLOCK_SUSPEND
+
+ [/vendor/path/dir/]
+ user: AID_FOO
+ group: AID_SYSTEM
+ mode: 0777
+ caps: 0
+
+ [AID_OEM1]
+ # 5001 in base16
+ value: 0x1389
+ """))
+ temp_file.flush()
+
+ parser = FSConfigFileParser([temp_file.name], [(5000, 5999)])
+ files = parser.files
+ dirs = parser.dirs
+ aids = parser.aids
+
+ self.assertEquals(len(files), 1)
+ self.assertEquals(len(dirs), 1)
+ self.assertEquals(len(aids), 1)
+
+ aid = aids[0]
+ fcap = files[0]
+ dcap = dirs[0]
+
+ self.assertEqual(fcap,
+ FSConfig('0777', 'AID_FOO', 'AID_SYSTEM',
+ '(1ULL << CAP_BLOCK_SUSPEND)',
+ '/system/bin/file', temp_file.name))
+
+ self.assertEqual(dcap,
+ FSConfig('0777', 'AID_FOO', 'AID_SYSTEM', '(0)',
+ '/vendor/path/dir/', temp_file.name))
+
+ self.assertEqual(aid, AID('AID_OEM1', '0x1389', temp_file.name))
+
+ def test_fs_config_file_parser_bad(self):
+ """Test FSConfig Parser bad input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ [/system/bin/file]
+ caps: BLOCK_SUSPEND
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ FSConfigFileParser([temp_file.name], [(5000, 5999)])
+
+ def test_fs_config_file_parser_bad_aid_range(self):
+ """Test FSConfig Parser bad aid range value input file"""
+
+ with tempfile.NamedTemporaryFile() as temp_file:
+ temp_file.write(
+ textwrap.dedent("""
+ [AID_OEM1]
+ value: 25
+ """))
+ temp_file.flush()
+
+ with self.assertRaises(SystemExit):
+ FSConfigFileParser([temp_file.name], [(5000, 5999)])
diff --git a/tools/generate-enforce-rro-android-manifest.py b/tools/generate-enforce-rro-android-manifest.py
new file mode 100755
index 0000000..68331cf
--- /dev/null
+++ b/tools/generate-enforce-rro-android-manifest.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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.
+"""
+Utility to generate the Android manifest file of runtime resource overlay
+package for source module.
+"""
+from xml.dom.minidom import parseString
+import argparse
+import os
+import sys
+
+ANDROID_MANIFEST_TEMPLATE="""<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="%s.auto_generated_rro__"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="%s" android:priority="0" android:isStatic="true"/>
+</manifest>
+"""
+
+
+def get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '-u', '--use-package-name', action='store_true',
+ help='Indicate that --package-info is a package name.')
+ parser.add_argument(
+ '-p', '--package-info', required=True,
+ help='Manifest package name or manifest file path of source module.')
+ parser.add_argument(
+ '-o', '--output', required=True,
+ help='Output manifest file path.')
+ return parser.parse_args()
+
+
+def main(argv):
+ args = get_args()
+
+ package_name = args.package_info
+ if not args.use_package_name:
+ with open(args.package_info) as f:
+ data = f.read()
+ f.close()
+ dom = parseString(data)
+ package_name = dom.documentElement.getAttribute('package')
+
+ with open(args.output, 'w+') as f:
+ f.write(ANDROID_MANIFEST_TEMPLATE % (package_name, package_name))
+ f.close()
+
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/tools/generate-notice-files.py b/tools/generate-notice-files.py
index 5b13bf5..adbf7c2 100755
--- a/tools/generate-notice-files.py
+++ b/tools/generate-notice-files.py
@@ -14,14 +14,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
-Usage: generate-notice-files [plain text output file] [html output file] [file title] [directory of notices]
+Usage: generate-notice-files --text-output [plain text output file] \
+ --html-output [html output file] \
+ --xml-output [xml output file] \
+ -t [file title] -s [directory of notices]
Generate the Android notice files, including both text and html files.
-h to display this usage message and exit.
"""
from collections import defaultdict
-import getopt
+import argparse
import hashlib
import itertools
import os
@@ -38,26 +41,6 @@
"<": "<",
}
-try:
- opts, args = getopt.getopt(sys.argv[1:], "h")
-except getopt.GetoptError, err:
- print str(err)
- print __doc__
- sys.exit(2)
-
-for o, a in opts:
- if o == "-h":
- print __doc__
- sys.exit(2)
- else:
- print >> sys.stderr, "unhandled option %s" % (o,)
-
-if len(args) != 4:
- print """need exactly four arguments, the two output files, the file title
- and the directory containing notices, not %d""" % (len(args),)
- print __doc__
- sys.exit(1)
-
def hexify(s):
return ("%02x"*len(s)) % tuple(map(ord, s))
@@ -163,27 +146,123 @@
print >> output_file, open(value[0]).read()
output_file.close()
-def main(args):
- txt_output_file = args[0]
- html_output_file = args[1]
- file_title = args[2]
+def combine_notice_files_xml(files_with_same_hash, input_dir, output_filename):
+ """Combine notice files in FILE_HASH and output a XML version to OUTPUT_FILENAME."""
+
+ SRC_DIR_STRIP_RE = re.compile(input_dir + "(/.*).txt")
+
+ # Set up a filename to row id table (anchors inside tables don't work in
+ # most browsers, but href's to table row ids do)
+ id_table = {}
+ for file_key in files_with_same_hash.keys():
+ for filename in files_with_same_hash[file_key]:
+ id_table[filename] = file_key
+
+ # Open the output file, and output the header pieces
+ output_file = open(output_filename, "wb")
+
+ print >> output_file, '<?xml version="1.0" encoding="utf-8"?>'
+ print >> output_file, "<licenses>"
+
+ # Flatten the list of lists into a single list of filenames
+ sorted_filenames = sorted(id_table.keys())
+
+ # Print out a nice table of contents
+ for filename in sorted_filenames:
+ stripped_filename = SRC_DIR_STRIP_RE.sub(r"\1", filename)
+ print >> output_file, '<file-name contentId="%s">%s</file-name>' % (id_table.get(filename), stripped_filename)
+
+ print >> output_file
+ print >> output_file
+
+ processed_file_keys = []
+ # Output the individual notice file lists
+ for filename in sorted_filenames:
+ file_key = id_table.get(filename)
+ if file_key in processed_file_keys:
+ continue
+ processed_file_keys.append(file_key)
+
+ print >> output_file, '<file-content contentId="%s"><![CDATA[%s]]></file-content>' % (file_key, html_escape(open(filename).read()))
+ print >> output_file
+
+ # Finish off the file output
+ print >> output_file, "</licenses>"
+ output_file.close()
+
+def get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--text-output', required=True,
+ help='The text output file path.')
+ parser.add_argument(
+ '--html-output',
+ help='The html output file path.')
+ parser.add_argument(
+ '--xml-output',
+ help='The xml output file path.')
+ parser.add_argument(
+ '-t', '--title', required=True,
+ help='The file title.')
+ parser.add_argument(
+ '-s', '--source-dir', required=True,
+ help='The directory containing notices.')
+ parser.add_argument(
+ '-i', '--included-subdirs', action='append',
+ help='The sub directories which should be included.')
+ parser.add_argument(
+ '-e', '--excluded-subdirs', action='append',
+ help='The sub directories which should be excluded.')
+ return parser.parse_args()
+
+def main(argv):
+ args = get_args()
+
+ txt_output_file = args.text_output
+ html_output_file = args.html_output
+ xml_output_file = args.xml_output
+ file_title = args.title
+ included_subdirs = []
+ excluded_subdirs = []
+ if args.included_subdirs is not None:
+ included_subdirs = args.included_subdirs
+ if args.excluded_subdirs is not None:
+ excluded_subdirs = args.excluded_subdirs
# Find all the notice files and md5 them
- input_dir = os.path.normpath(args[3])
+ input_dir = os.path.normpath(args.source_dir)
files_with_same_hash = defaultdict(list)
for root, dir, files in os.walk(input_dir):
for file in files:
- if file.endswith(".txt"):
+ matched = True
+ if len(included_subdirs) > 0:
+ matched = False
+ for subdir in included_subdirs:
+ if root.startswith(input_dir + '/' + subdir):
+ matched = True
+ break
+ elif len(excluded_subdirs) > 0:
+ for subdir in excluded_subdirs:
+ if root.startswith(input_dir + '/' + subdir):
+ matched = False
+ break
+ if matched and file.endswith(".txt"):
filename = os.path.join(root, file)
file_md5sum = md5sum(filename)
files_with_same_hash[file_md5sum].append(filename)
filesets = [sorted(files_with_same_hash[md5]) for md5 in sorted(files_with_same_hash.keys())]
- print "Combining NOTICE files into HTML"
- combine_notice_files_html(filesets, input_dir, html_output_file)
print "Combining NOTICE files into text"
combine_notice_files_text(filesets, input_dir, txt_output_file, file_title)
+ if html_output_file is not None:
+ print "Combining NOTICE files into HTML"
+ combine_notice_files_html(filesets, input_dir, html_output_file)
+
+ if xml_output_file is not None:
+ print "Combining NOTICE files into XML"
+ combine_notice_files_xml(files_with_same_hash, input_dir, xml_output_file)
+
if __name__ == "__main__":
- main(args)
+ main(sys.argv)
diff --git a/tools/ijar/Android.bp b/tools/ijar/Android.bp
new file mode 100644
index 0000000..a244a2d
--- /dev/null
+++ b/tools/ijar/Android.bp
@@ -0,0 +1,18 @@
+// Copyright 2015 The Android Open Source Project
+//
+// The rest of files in this directory comes from
+// https://github.com/bazelbuild/bazel/tree/master/third_party/ijar
+
+cc_binary_host {
+ srcs: [
+ "classfile.cc",
+ "ijar.cc",
+ "zip.cc",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ host_ldlibs: ["-lz"],
+ name: "ijar",
+}
diff --git a/tools/ijar/Android.mk b/tools/ijar/Android.mk
deleted file mode 100644
index 8b2a02c..0000000
--- a/tools/ijar/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2015 The Android Open Source Project
-#
-# The rest of files in this directory comes from
-# https://github.com/bazelbuild/bazel/tree/master/third_party/ijar
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_CPP_EXTENSION := .cc
-LOCAL_SRC_FILES := classfile.cc ijar.cc zip.cc
-LOCAL_CFLAGS += -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libz-host
-LOCAL_MODULE := ijar
-# libc++ is not supported for TARGET_BUILD_APPS builds
-LOCAL_CXX_STL := libstdc++
-include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/ijar/classfile.cc b/tools/ijar/classfile.cc
index e0cf42e..d33e0db 100644
--- a/tools/ijar/classfile.cc
+++ b/tools/ijar/classfile.cc
@@ -123,7 +123,7 @@
// See sec.4.4 of JVM spec.
struct Constant {
- Constant(u1 tag) :
+ explicit Constant(u1 tag) :
slot_(0),
tag_(tag) {}
@@ -180,7 +180,7 @@
// See sec.4.4.1 of JVM spec.
struct Constant_Class : Constant
{
- Constant_Class(u2 name_index) :
+ explicit Constant_Class(u2 name_index) :
Constant(CONSTANT_Class),
name_index_(name_index) {}
@@ -231,7 +231,7 @@
// See sec.4.4.3 of JVM spec.
struct Constant_String : Constant
{
- Constant_String(u2 string_index) :
+ explicit Constant_String(u2 string_index) :
Constant(CONSTANT_String),
string_index_(string_index) {}
@@ -360,7 +360,7 @@
// See sec.4.4.9 of JVM spec.
struct Constant_MethodType : Constant
{
- Constant_MethodType(u2 descriptor_index) :
+ explicit Constant_MethodType(u2 descriptor_index) :
Constant(CONSTANT_MethodType),
descriptor_index_(descriptor_index) {}
diff --git a/tools/ijar/zip.cc b/tools/ijar/zip.cc
index ca5f396..3aa06db 100644
--- a/tools/ijar/zip.cc
+++ b/tools/ijar/zip.cc
@@ -846,6 +846,7 @@
memcpy(entry->file_name, filename, file_name_length_);
entry->extra_field_length = 0;
entry->extra_field = (const u1 *)"";
+ entry->crc32 = 0;
// Output the ZIP local_file_header:
put_u4le(q, LOCAL_FILE_HEADER_SIGNATURE);
diff --git a/tools/libhost/Android.bp b/tools/libhost/Android.bp
new file mode 100644
index 0000000..e5a5ecf
--- /dev/null
+++ b/tools/libhost/Android.bp
@@ -0,0 +1,20 @@
+cc_library_host_static {
+
+ srcs: ["CopyFile.c"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ name: "libhost",
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+ stl: "none",
+
+}
diff --git a/libs/host/CopyFile.c b/tools/libhost/CopyFile.c
similarity index 100%
rename from libs/host/CopyFile.c
rename to tools/libhost/CopyFile.c
diff --git a/libs/host/include/host/CopyFile.h b/tools/libhost/include/host/CopyFile.h
similarity index 100%
rename from libs/host/include/host/CopyFile.h
rename to tools/libhost/include/host/CopyFile.h
diff --git a/tools/makeparallel/Makefile b/tools/makeparallel/Makefile
index 4e12b10..82a4abf 100644
--- a/tools/makeparallel/Makefile
+++ b/tools/makeparallel/Makefile
@@ -65,8 +65,9 @@
makeparallel_test: $(MAKEPARALLEL)
@EXPECTED="-j1234" $(MAKEPARALLEL_TEST) -j1234
@EXPECTED="-j123" $(MAKEPARALLEL_TEST) -j123
- @EXPECTED="-j1" $(MAKEPARALLEL_TEST) -j1
- @EXPECTED="-j1" $(MAKEPARALLEL_TEST)
+ @EXPECTED="" $(MAKEPARALLEL_TEST) -j1
+ @EXPECTED="-j$$(($$(nproc) + 2))" $(MAKEPARALLEL_TEST) -j
+ @EXPECTED="" $(MAKEPARALLEL_TEST)
@EXPECTED="-j1234" $(MAKEPARALLEL_NINJA_TEST) -j1234
@EXPECTED="-j123" $(MAKEPARALLEL_NINJA_TEST) -j123
@@ -87,8 +88,6 @@
@EXPECTED="-j1234 -k0" $(MAKEPARALLEL_NINJA_TEST) -j1234 -k
@EXPECTED="-j1234 -k0" $(MAKEPARALLEL_NINJA_TEST) -kt -j1234
- @EXPECTED="-j1" $(MAKEPARALLEL_TEST) A=-j1234
- @EXPECTED="-j1" $(MAKEPARALLEL_TEST) A\ -j1234=-j1234
- @EXPECTED="-j1234" $(MAKEPARALLEL_TEST) A\ -j1234=-j1234 -j1234
+ @EXPECTED="" $(MAKEPARALLEL_TEST) A=-j1234
@EXPECTED="-j1234 args" ARGS="args" $(MAKEPARALLEL_TEST) -j1234
diff --git a/tools/makeparallel/makeparallel.cpp b/tools/makeparallel/makeparallel.cpp
index 3c39846..66babdf 100644
--- a/tools/makeparallel/makeparallel.cpp
+++ b/tools/makeparallel/makeparallel.cpp
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -316,33 +317,83 @@
}
}
- std::string jarg = "-j" + std::to_string(tokens + 1);
+ std::string jarg;
+ if (parallel) {
+ if (tokens == 0) {
+ if (ninja) {
+ // ninja is parallel by default
+ jarg = "";
+ } else {
+ // make -j with no argument, guess a reasonable parallelism like ninja does
+ jarg = "-j" + std::to_string(sysconf(_SC_NPROCESSORS_ONLN) + 2);
+ }
+ } else {
+ jarg = "-j" + std::to_string(tokens + 1);
+ }
+ }
+
if (ninja) {
if (!parallel) {
// ninja is parallel by default, pass -j1 to disable parallelism if make wasn't parallel
args.push_back(strdup("-j1"));
- } else if (tokens > 0) {
- args.push_back(strdup(jarg.c_str()));
+ } else {
+ if (jarg != "") {
+ args.push_back(strdup(jarg.c_str()));
+ }
}
if (keep_going) {
args.push_back(strdup("-k0"));
}
} else {
- args.push_back(strdup(jarg.c_str()));
+ if (jarg != "") {
+ args.push_back(strdup(jarg.c_str()));
+ }
}
args.insert(args.end(), &argv[2], &argv[argc]);
args.push_back(nullptr);
- pid_t pid = fork();
+ static pid_t pid;
+
+ // Set up signal handlers to forward SIGTERM to child.
+ // Assume that all other signals are sent to the entire process group,
+ // and that we'll wait for our child to exit instead of handling them.
+ struct sigaction action = {};
+ action.sa_flags = SA_RESTART;
+ action.sa_handler = [](int signal) {
+ if (signal == SIGTERM && pid > 0) {
+ kill(pid, signal);
+ }
+ };
+
+ int ret = 0;
+ if (!ret) ret = sigaction(SIGHUP, &action, NULL);
+ if (!ret) ret = sigaction(SIGINT, &action, NULL);
+ if (!ret) ret = sigaction(SIGQUIT, &action, NULL);
+ if (!ret) ret = sigaction(SIGTERM, &action, NULL);
+ if (!ret) ret = sigaction(SIGALRM, &action, NULL);
+ if (ret < 0) {
+ error(errno, errno, "sigaction failed");
+ }
+
+ pid = fork();
if (pid < 0) {
error(errno, errno, "fork failed");
} else if (pid == 0) {
// child
unsetenv("MAKEFLAGS");
unsetenv("MAKELEVEL");
+
+ // make 3.81 sets the stack ulimit to unlimited, which may cause problems
+ // for child processes
+ struct rlimit rlim{};
+ if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur == RLIM_INFINITY) {
+ rlim.rlim_cur = 8*1024*1024;
+ setrlimit(RLIMIT_STACK, &rlim);
+ }
+
int ret = execvp(path, args.data());
if (ret < 0) {
error(errno, errno, "exec %s failed", path);
@@ -351,9 +402,10 @@
}
// parent
+
siginfo_t status = {};
int exit_status = 0;
- int ret = waitid(P_PID, pid, &status, WEXITED);
+ ret = waitid(P_PID, pid, &status, WEXITED);
if (ret < 0) {
error(errno, errno, "waitpid failed");
} else if (status.si_code == CLD_EXITED) {
diff --git a/tools/post_process_props.py b/tools/post_process_props.py
index 9dcaadf..295f8f6 100755
--- a/tools/post_process_props.py
+++ b/tools/post_process_props.py
@@ -19,10 +19,9 @@
# Usage: post_process_props.py file.prop [blacklist_key, ...]
# Blacklisted keys are removed from the property file, if present
-# See PROP_NAME_MAX and PROP_VALUE_MAX system_properties.h.
-# The constants in system_properties.h includes the termination NUL,
-# so we decrease the values by 1 here.
-PROP_NAME_MAX = 31
+# See PROP_VALUE_MAX in system_properties.h.
+# The constant in system_properties.h includes the terminating NUL,
+# so we decrease the value by 1 here.
PROP_VALUE_MAX = 91
# Put the modifications that you need to make into the /system/build.prop into this
@@ -59,11 +58,6 @@
buildprops = prop.to_dict()
for key, value in buildprops.iteritems():
# Check build properties' length.
- if len(key) > PROP_NAME_MAX:
- check_pass = False
- sys.stderr.write("error: %s cannot exceed %d bytes: " %
- (key, PROP_NAME_MAX))
- sys.stderr.write("%s (%d)\n" % (key, len(key)))
if len(value) > PROP_VALUE_MAX:
check_pass = False
sys.stderr.write("error: %s cannot exceed %d bytes: " %
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 5a0a411..1d8090a 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -41,135 +41,187 @@
--is_signing
Skip building & adding the images for "userdata" and "cache" if we
are signing the target files.
-
- --verity_signer_path
- Specify the signer path to build verity metadata.
"""
+from __future__ import print_function
+
import sys
if sys.hexversion < 0x02070000:
- print >> sys.stderr, "Python 2.7 or newer is required."
+ print("Python 2.7 or newer is required.", file=sys.stderr)
sys.exit(1)
import datetime
import errno
import os
+import shlex
import shutil
+import subprocess
import tempfile
import zipfile
import build_image
import common
+import rangelib
import sparse_img
OPTIONS = common.OPTIONS
OPTIONS.add_missing = False
OPTIONS.rebuild_recovery = False
+OPTIONS.replace_recovery_patch_files_list = []
OPTIONS.replace_verity_public_key = False
OPTIONS.replace_verity_private_key = False
OPTIONS.is_signing = False
-OPTIONS.verity_signer_path = None
+
+
+class OutputFile(object):
+ def __init__(self, output_zip, input_dir, prefix, name):
+ self._output_zip = output_zip
+ self.input_name = os.path.join(input_dir, prefix, name)
+
+ if self._output_zip:
+ self._zip_name = os.path.join(prefix, name)
+
+ root, suffix = os.path.splitext(name)
+ self.name = common.MakeTempFile(prefix=root + '-', suffix=suffix)
+ else:
+ self.name = self.input_name
+
+ def Write(self):
+ if self._output_zip:
+ common.ZipWrite(self._output_zip, self.name, self._zip_name)
+
def GetCareMap(which, imgname):
"""Generate care_map of system (or vendor) partition"""
assert which in ("system", "vendor")
- _, blk_device = common.GetTypeAndDevice("/" + which, OPTIONS.info_dict)
simg = sparse_img.SparseImage(imgname)
care_map_list = []
- care_map_list.append(blk_device)
- care_map_list.append(simg.care_map.to_string_raw())
+ care_map_list.append(which)
+
+ care_map_ranges = simg.care_map
+ key = which + "_adjusted_partition_size"
+ adjusted_blocks = OPTIONS.info_dict.get(key)
+ if adjusted_blocks:
+ assert adjusted_blocks > 0, "blocks should be positive for " + which
+ care_map_ranges = care_map_ranges.intersect(rangelib.RangeSet(
+ "0-%d" % (adjusted_blocks,)))
+
+ care_map_list.append(care_map_ranges.to_string_raw())
return care_map_list
def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
"""Turn the contents of SYSTEM into a system image and store it in
- output_zip."""
+ output_zip. Returns the name of the system image file."""
- prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system.img")
- if os.path.exists(prebuilt_path):
- print "system.img already exists in %s, no need to rebuild..." % (prefix,)
- return prebuilt_path
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "system.img")
+ if os.path.exists(img.input_name):
+ print("system.img already exists in %s, no need to rebuild..." % (prefix,))
+ return img.input_name
def output_sink(fn, data):
ofile = open(os.path.join(OPTIONS.input_tmp, "SYSTEM", fn), "w")
ofile.write(data)
ofile.close()
+ arc_name = "SYSTEM/" + fn
+ if arc_name in output_zip.namelist():
+ OPTIONS.replace_recovery_patch_files_list.append(arc_name)
+ else:
+ common.ZipWrite(output_zip, ofile.name, arc_name)
+
if OPTIONS.rebuild_recovery:
- print "Building new recovery patch"
+ print("Building new recovery patch")
common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
boot_img, info_dict=OPTIONS.info_dict)
- block_list = common.MakeTempFile(prefix="system-blocklist-", suffix=".map")
- imgname = BuildSystem(OPTIONS.input_tmp, OPTIONS.info_dict,
- block_list=block_list)
- common.ZipWrite(output_zip, imgname, prefix + "system.img")
- common.ZipWrite(output_zip, block_list, prefix + "system.map")
- return imgname
+ block_list = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "system.map")
+ CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system", img,
+ block_list=block_list)
-
-def BuildSystem(input_dir, info_dict, block_list=None):
- """Build the (sparse) system image and return the name of a temp
- file containing it."""
- return CreateImage(input_dir, info_dict, "system", block_list=block_list)
+ return img.name
def AddSystemOther(output_zip, prefix="IMAGES/"):
"""Turn the contents of SYSTEM_OTHER into a system_other image
and store it in output_zip."""
- prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system_other.img")
- if os.path.exists(prebuilt_path):
- print "system_other.img already exists in %s, no need to rebuild..." % (prefix,)
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "system_other.img")
+ if os.path.exists(img.input_name):
+ print("system_other.img already exists in %s, no need to rebuild..." % (
+ prefix,))
return
- imgname = BuildSystemOther(OPTIONS.input_tmp, OPTIONS.info_dict)
- common.ZipWrite(output_zip, imgname, prefix + "system_other.img")
-
-def BuildSystemOther(input_dir, info_dict):
- """Build the (sparse) system_other image and return the name of a temp
- file containing it."""
- return CreateImage(input_dir, info_dict, "system_other", block_list=None)
+ CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system_other", img)
def AddVendor(output_zip, prefix="IMAGES/"):
"""Turn the contents of VENDOR into a vendor image and store in it
output_zip."""
- prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "vendor.img")
- if os.path.exists(prebuilt_path):
- print "vendor.img already exists in %s, no need to rebuild..." % (prefix,)
- return prebuilt_path
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "vendor.img")
+ if os.path.exists(img.input_name):
+ print("vendor.img already exists in %s, no need to rebuild..." % (prefix,))
+ return img.input_name
- block_list = common.MakeTempFile(prefix="vendor-blocklist-", suffix=".map")
- imgname = BuildVendor(OPTIONS.input_tmp, OPTIONS.info_dict,
- block_list=block_list)
- common.ZipWrite(output_zip, imgname, prefix + "vendor.img")
- common.ZipWrite(output_zip, block_list, prefix + "vendor.map")
- return imgname
+ block_list = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "vendor.map")
+ CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "vendor", img,
+ block_list=block_list)
+ return img.name
-def BuildVendor(input_dir, info_dict, block_list=None):
- """Build the (sparse) vendor image and return the name of a temp
- file containing it."""
- return CreateImage(input_dir, info_dict, "vendor", block_list=block_list)
+def AddDtbo(output_zip, prefix="IMAGES/"):
+ """Adds the DTBO image.
+
+ Uses the image under prefix if it already exists. Otherwise looks for the
+ image under PREBUILT_IMAGES/, signs it as needed, and returns the image name.
+ """
+
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "dtbo.img")
+ if os.path.exists(img.input_name):
+ print("dtbo.img already exists in %s, no need to rebuild..." % (prefix,))
+ return img.input_name
+
+ dtbo_prebuilt_path = os.path.join(
+ OPTIONS.input_tmp, "PREBUILT_IMAGES", "dtbo.img")
+ assert os.path.exists(dtbo_prebuilt_path)
+ shutil.copy(dtbo_prebuilt_path, img.name)
+
+ # AVB-sign the image as needed.
+ if OPTIONS.info_dict.get("board_avb_enable") == "true":
+ avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
+ part_size = OPTIONS.info_dict["dtbo_size"]
+ # The AVB hash footer will be replaced if already present.
+ cmd = [avbtool, "add_hash_footer", "--image", img.name,
+ "--partition_size", str(part_size), "--partition_name", "dtbo"]
+ cmd.extend(shlex.split(OPTIONS.info_dict["avb_signing_args"]))
+ args = OPTIONS.info_dict.get("board_avb_dtbo_add_hash_footer_args")
+ if args and args.strip():
+ cmd.extend(shlex.split(args))
+ p = common.Run(cmd, stdout=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, \
+ "avbtool add_hash_footer of %s failed" % (img.name,)
+
+ img.Write()
+ return img.name
-def CreateImage(input_dir, info_dict, what, block_list=None):
- print "creating " + what + ".img..."
-
- img = common.MakeTempFile(prefix=what + "-", suffix=".img")
+def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
+ print("creating " + what + ".img...")
# The name of the directory it is making an image out of matters to
# mkyaffs2image. It wants "system" but we have a directory named
# "SYSTEM", so create a symlink.
+ temp_dir = tempfile.mkdtemp()
+ OPTIONS.tempfiles.append(temp_dir)
try:
os.symlink(os.path.join(input_dir, what.upper()),
- os.path.join(input_dir, what))
+ os.path.join(temp_dir, what))
except OSError as e:
# bogus error on my mac version?
# File "./build/tools/releasetools/img_from_target_files"
@@ -204,13 +256,28 @@
if fs_config:
image_props["fs_config"] = fs_config
if block_list:
- image_props["block_list"] = block_list
+ image_props["block_list"] = block_list.name
- succ = build_image.BuildImage(os.path.join(input_dir, what),
- image_props, img)
+ succ = build_image.BuildImage(os.path.join(temp_dir, what),
+ image_props, output_file.name)
assert succ, "build " + what + ".img image failed"
- return img
+ output_file.Write()
+ if block_list:
+ block_list.Write()
+
+ # Set the 'adjusted_partition_size' that excludes the verity blocks of the
+ # given image. When avb is enabled, this size is the max image size returned
+ # by the avb tool.
+ is_verity_partition = "verity_block_device" in image_props
+ verity_supported = (image_props.get("verity") == "true" or
+ image_props.get("board_avb_enable") == "true")
+ is_avb_enable = image_props.get("avb_hashtree_enable") == "true"
+ if verity_supported and (is_verity_partition or is_avb_enable):
+ adjusted_blocks_value = image_props.get("partition_size")
+ if adjusted_blocks_value:
+ adjusted_blocks_key = what + "_adjusted_partition_size"
+ info_dict[adjusted_blocks_key] = int(adjusted_blocks_value)/4096 - 1
def AddUserdata(output_zip, prefix="IMAGES/"):
@@ -222,19 +289,18 @@
in OPTIONS.info_dict.
"""
- prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "userdata.img")
- if os.path.exists(prebuilt_path):
- print "userdata.img already exists in %s, no need to rebuild..." % (prefix,)
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "userdata.img")
+ if os.path.exists(img.input_name):
+ print("userdata.img already exists in %s, no need to rebuild..." % (
+ prefix,))
return
+ # Skip userdata.img if no size.
image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict, "data")
- # We only allow yaffs to have a 0/missing partition_size.
- # Extfs, f2fs must have a size. Skip userdata.img if no size.
- if (not image_props.get("fs_type", "").startswith("yaffs") and
- not image_props.get("partition_size")):
+ if not image_props.get("partition_size"):
return
- print "creating userdata.img..."
+ print("creating userdata.img...")
# Use a fixed timestamp (01/01/2009) when packaging the image.
# Bug: 24377993
@@ -247,6 +313,7 @@
# empty dir named "data", or a symlink to the DATA dir,
# and build the image from that.
temp_dir = tempfile.mkdtemp()
+ OPTIONS.tempfiles.append(temp_dir)
user_dir = os.path.join(temp_dir, "data")
empty = (OPTIONS.info_dict.get("userdata_img_with_data") != "true")
if empty:
@@ -257,8 +324,6 @@
os.symlink(os.path.join(OPTIONS.input_tmp, "DATA"),
user_dir)
- img = tempfile.NamedTemporaryFile()
-
fstab = OPTIONS.info_dict["fstab"]
if fstab:
image_props["fs_type"] = fstab["/data"].fs_type
@@ -266,17 +331,69 @@
assert succ, "build userdata.img image failed"
common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
- common.ZipWrite(output_zip, img.name, prefix + "userdata.img")
- img.close()
- shutil.rmtree(temp_dir)
+ img.Write()
+
+
+def AddVBMeta(output_zip, boot_img_path, system_img_path, vendor_img_path,
+ dtbo_img_path, prefix="IMAGES/"):
+ """Create a VBMeta image and store it in output_zip."""
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "vbmeta.img")
+ avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
+ cmd = [avbtool, "make_vbmeta_image",
+ "--output", img.name,
+ "--include_descriptors_from_image", boot_img_path,
+ "--include_descriptors_from_image", system_img_path]
+ if vendor_img_path is not None:
+ cmd.extend(["--include_descriptors_from_image", vendor_img_path])
+ if dtbo_img_path is not None:
+ cmd.extend(["--include_descriptors_from_image", dtbo_img_path])
+ if OPTIONS.info_dict.get("system_root_image") == "true":
+ cmd.extend(["--setup_rootfs_from_kernel", system_img_path])
+ cmd.extend(shlex.split(OPTIONS.info_dict["avb_signing_args"]))
+ args = OPTIONS.info_dict.get("board_avb_make_vbmeta_image_args")
+ if args and args.strip():
+ cmd.extend(shlex.split(args))
+ p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, "avbtool make_vbmeta_image failed"
+ img.Write()
+
+
+def AddPartitionTable(output_zip, prefix="IMAGES/"):
+ """Create a partition table image and store it in output_zip."""
+
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "partition-table.img")
+ bpt = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "partition-table.bpt")
+
+ # use BPTTOOL from environ, or "bpttool" if empty or not set.
+ bpttool = os.getenv("BPTTOOL") or "bpttool"
+ cmd = [bpttool, "make_table", "--output_json", bpt.name,
+ "--output_gpt", img.name]
+ input_files_str = OPTIONS.info_dict["board_bpt_input_files"]
+ input_files = input_files_str.split(" ")
+ for i in input_files:
+ cmd.extend(["--input", i])
+ disk_size = OPTIONS.info_dict.get("board_bpt_disk_size")
+ if disk_size:
+ cmd.extend(["--disk_size", disk_size])
+ args = OPTIONS.info_dict.get("board_bpt_make_table_args")
+ if args:
+ cmd.extend(shlex.split(args))
+
+ p = common.Run(cmd, stdout=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, "bpttool make_table failed"
+
+ img.Write()
+ bpt.Write()
def AddCache(output_zip, prefix="IMAGES/"):
"""Create an empty cache image and store it in output_zip."""
- prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "cache.img")
- if os.path.exists(prebuilt_path):
- print "cache.img already exists in %s, no need to rebuild..." % (prefix,)
+ img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "cache.img")
+ if os.path.exists(img.input_name):
+ print("cache.img already exists in %s, no need to rebuild..." % (prefix,))
return
image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict, "cache")
@@ -284,7 +401,7 @@
if "fs_type" not in image_props:
return
- print "creating cache.img..."
+ print("creating cache.img...")
# Use a fixed timestamp (01/01/2009) when packaging the image.
# Bug: 24377993
@@ -296,9 +413,9 @@
# mkyaffs2image. So we create a temp dir, and within it we create an
# empty dir named "cache", and build the image from that.
temp_dir = tempfile.mkdtemp()
+ OPTIONS.tempfiles.append(temp_dir)
user_dir = os.path.join(temp_dir, "cache")
os.mkdir(user_dir)
- img = tempfile.NamedTemporaryFile()
fstab = OPTIONS.info_dict["fstab"]
if fstab:
@@ -307,60 +424,86 @@
assert succ, "build cache.img image failed"
common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
- common.ZipWrite(output_zip, img.name, prefix + "cache.img")
- img.close()
- os.rmdir(user_dir)
- os.rmdir(temp_dir)
+ img.Write()
+
+
+def ReplaceRecoveryPatchFiles(zip_filename):
+ """Update the related files under SYSTEM/ after rebuilding recovery."""
+
+ cmd = ["zip", "-d", zip_filename] + OPTIONS.replace_recovery_patch_files_list
+ p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ p.communicate()
+
+ output_zip = zipfile.ZipFile(zip_filename, "a",
+ compression=zipfile.ZIP_DEFLATED,
+ allowZip64=True)
+ for item in OPTIONS.replace_recovery_patch_files_list:
+ file_path = os.path.join(OPTIONS.input_tmp, item)
+ assert os.path.exists(file_path)
+ common.ZipWrite(output_zip, file_path, arcname=item)
+ common.ZipClose(output_zip)
def AddImagesToTargetFiles(filename):
- OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)
+ if os.path.isdir(filename):
+ OPTIONS.input_tmp = os.path.abspath(filename)
+ input_zip = None
+ else:
+ OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)
if not OPTIONS.add_missing:
- for n in input_zip.namelist():
- if n.startswith("IMAGES/"):
- print "target_files appears to already contain images."
- sys.exit(1)
+ if os.path.isdir(os.path.join(OPTIONS.input_tmp, "IMAGES")):
+ print("target_files appears to already contain images.")
+ sys.exit(1)
- try:
- input_zip.getinfo("VENDOR/")
- has_vendor = True
- except KeyError:
- has_vendor = False
+ has_vendor = os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR"))
+ has_system_other = os.path.isdir(os.path.join(OPTIONS.input_tmp,
+ "SYSTEM_OTHER"))
- has_system_other = "SYSTEM_OTHER/" in input_zip.namelist()
+ if input_zip:
+ OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)
- OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)
-
- common.ZipClose(input_zip)
- output_zip = zipfile.ZipFile(filename, "a",
- compression=zipfile.ZIP_DEFLATED)
+ common.ZipClose(input_zip)
+ output_zip = zipfile.ZipFile(filename, "a",
+ compression=zipfile.ZIP_DEFLATED,
+ allowZip64=True)
+ else:
+ OPTIONS.info_dict = common.LoadInfoDict(filename, filename)
+ output_zip = None
+ images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
+ if not os.path.isdir(images_dir):
+ os.makedirs(images_dir)
+ images_dir = None
has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")
def banner(s):
- print "\n\n++++ " + s + " ++++\n\n"
+ print("\n\n++++ " + s + " ++++\n\n")
- banner("boot")
prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
boot_image = None
if os.path.exists(prebuilt_path):
- print "boot.img already exists in IMAGES/, no need to rebuild..."
+ banner("boot")
+ print("boot.img already exists in IMAGES/, no need to rebuild...")
if OPTIONS.rebuild_recovery:
boot_image = common.GetBootableImage(
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
else:
+ banner("boot")
boot_image = common.GetBootableImage(
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
if boot_image:
- boot_image.AddToZip(output_zip)
+ if output_zip:
+ boot_image.AddToZip(output_zip)
+ else:
+ boot_image.WriteToDir(OPTIONS.input_tmp)
recovery_image = None
if has_recovery:
banner("recovery")
prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
if os.path.exists(prebuilt_path):
- print "recovery.img already exists in IMAGES/, no need to rebuild..."
+ print("recovery.img already exists in IMAGES/, no need to rebuild...")
if OPTIONS.rebuild_recovery:
recovery_image = common.GetBootableImage(
"IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp,
@@ -369,7 +512,10 @@
recovery_image = common.GetBootableImage(
"IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
if recovery_image:
- recovery_image.AddToZip(output_zip)
+ if output_zip:
+ recovery_image.AddToZip(output_zip)
+ else:
+ recovery_image.WriteToDir(OPTIONS.input_tmp)
banner("recovery (two-step image)")
# The special recovery.img for two-step package use.
@@ -377,15 +523,18 @@
"IMAGES/recovery-two-step.img", "recovery-two-step.img",
OPTIONS.input_tmp, "RECOVERY", two_step_image=True)
if recovery_two_step_image:
- recovery_two_step_image.AddToZip(output_zip)
+ if output_zip:
+ recovery_two_step_image.AddToZip(output_zip)
+ else:
+ recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
banner("system")
- system_imgname = AddSystem(output_zip, recovery_img=recovery_image,
- boot_img=boot_image)
- vendor_imgname = None
+ system_img_path = AddSystem(
+ output_zip, recovery_img=recovery_image, boot_img=boot_image)
+ vendor_img_path = None
if has_vendor:
banner("vendor")
- vendor_imgname = AddVendor(output_zip)
+ vendor_img_path = AddVendor(output_zip)
if has_system_other:
banner("system_other")
AddSystemOther(output_zip)
@@ -395,8 +544,25 @@
banner("cache")
AddCache(output_zip)
- # For devices using A/B update, copy over images from RADIO/ to IMAGES/ and
- # make sure we have all the needed images ready under IMAGES/.
+ if OPTIONS.info_dict.get("board_bpt_enable") == "true":
+ banner("partition-table")
+ AddPartitionTable(output_zip)
+
+ dtbo_img_path = None
+ if OPTIONS.info_dict.get("has_dtbo") == "true":
+ banner("dtbo")
+ dtbo_img_path = AddDtbo(output_zip)
+
+ if OPTIONS.info_dict.get("board_avb_enable") == "true":
+ banner("vbmeta")
+ boot_contents = boot_image.WriteToTemp()
+ AddVBMeta(output_zip, boot_contents.name, system_img_path,
+ vendor_img_path, dtbo_img_path)
+
+ # For devices using A/B update, copy over images from RADIO/ and/or
+ # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
+ # images ready under IMAGES/. All images should have '.img' as extension.
+ banner("radio")
ab_partitions = os.path.join(OPTIONS.input_tmp, "META", "ab_partitions.txt")
if os.path.exists(ab_partitions):
with open(ab_partitions, 'r') as f:
@@ -405,30 +571,63 @@
# partitions (if present), then write this file to target_files package.
care_map_list = []
for line in lines:
- if line.strip() == "system" and OPTIONS.info_dict.get(
- "system_verity_block_device", None) is not None:
- assert os.path.exists(system_imgname)
- care_map_list += GetCareMap("system", system_imgname)
- if line.strip() == "vendor" and OPTIONS.info_dict.get(
- "vendor_verity_block_device", None) is not None:
- assert os.path.exists(vendor_imgname)
- care_map_list += GetCareMap("vendor", vendor_imgname)
+ if line.strip() == "system" and (
+ "system_verity_block_device" in OPTIONS.info_dict or
+ OPTIONS.info_dict.get("system_avb_hashtree_enable") == "true"):
+ assert os.path.exists(system_img_path)
+ care_map_list += GetCareMap("system", system_img_path)
+ if line.strip() == "vendor" and (
+ "vendor_verity_block_device" in OPTIONS.info_dict or
+ OPTIONS.info_dict.get("vendor_avb_hashtree_enable") == "true"):
+ assert os.path.exists(vendor_img_path)
+ care_map_list += GetCareMap("vendor", vendor_img_path)
img_name = line.strip() + ".img"
- img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
- if os.path.exists(img_radio_path):
- common.ZipWrite(output_zip, img_radio_path,
- os.path.join("IMAGES", img_name))
+ prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
+ if os.path.exists(prebuilt_path):
+ print("%s already exists, no need to overwrite..." % (img_name,))
+ continue
- # Zip spec says: All slashes MUST be forward slashes.
- img_path = 'IMAGES/' + img_name
- assert img_path in output_zip.namelist(), "cannot find " + img_name
+ img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
+ img_vendor_dir = os.path.join(
+ OPTIONS.input_tmp, "VENDOR_IMAGES")
+ if os.path.exists(img_radio_path):
+ if output_zip:
+ common.ZipWrite(output_zip, img_radio_path,
+ os.path.join("IMAGES", img_name))
+ else:
+ shutil.copy(img_radio_path, prebuilt_path)
+ else:
+ for root, _, files in os.walk(img_vendor_dir):
+ if img_name in files:
+ if output_zip:
+ common.ZipWrite(output_zip, os.path.join(root, img_name),
+ os.path.join("IMAGES", img_name))
+ else:
+ shutil.copy(os.path.join(root, img_name), prebuilt_path)
+ break
+
+ if output_zip:
+ # Zip spec says: All slashes MUST be forward slashes.
+ img_path = 'IMAGES/' + img_name
+ assert img_path in output_zip.namelist(), "cannot find " + img_name
+ else:
+ img_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
+ assert os.path.exists(img_path), "cannot find " + img_name
if care_map_list:
file_path = "META/care_map.txt"
- common.ZipWriteStr(output_zip, file_path, '\n'.join(care_map_list))
+ if output_zip:
+ common.ZipWriteStr(output_zip, file_path, '\n'.join(care_map_list))
+ else:
+ with open(os.path.join(OPTIONS.input_tmp, file_path), 'w') as fp:
+ fp.write('\n'.join(care_map_list))
- common.ZipClose(output_zip)
+ if output_zip:
+ common.ZipClose(output_zip)
+ if OPTIONS.replace_recovery_patch_files_list:
+ ReplaceRecoveryPatchFiles(output_zip.filename)
+
def main(argv):
def option_handler(o, a):
@@ -442,8 +641,6 @@
OPTIONS.replace_verity_public_key = (True, a)
elif o == "--is_signing":
OPTIONS.is_signing = True
- elif o == "--verity_signer_path":
- OPTIONS.verity_signer_path = a
else:
return False
return True
@@ -453,8 +650,7 @@
extra_long_opts=["add_missing", "rebuild_recovery",
"replace_verity_public_key=",
"replace_verity_private_key=",
- "is_signing",
- "verity_signer_path="],
+ "is_signing"],
extra_option_handler=option_handler)
@@ -463,16 +659,14 @@
sys.exit(1)
AddImagesToTargetFiles(args[0])
- print "done."
+ print("done.")
if __name__ == '__main__':
try:
common.CloseInheritedPipes()
main(sys.argv[1:])
except common.ExternalError as e:
- print
- print " ERROR: %s" % (e,)
- print
+ print("\n ERROR: %s\n" % (e,))
sys.exit(1)
finally:
common.Cleanup()
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index cc06a42..b8123c0 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -14,8 +14,6 @@
from __future__ import print_function
-from collections import deque, OrderedDict
-from hashlib import sha1
import array
import common
import functools
@@ -23,81 +21,79 @@
import itertools
import multiprocessing
import os
+import os.path
import re
import subprocess
+import sys
import threading
-import time
-import tempfile
+from collections import deque, OrderedDict
+from hashlib import sha1
from rangelib import RangeSet
__all__ = ["EmptyImage", "DataImage", "BlockImageDiff"]
-def compute_patch(src, tgt, imgdiff=False):
- srcfd, srcfile = tempfile.mkstemp(prefix="src-")
- tgtfd, tgtfile = tempfile.mkstemp(prefix="tgt-")
- patchfd, patchfile = tempfile.mkstemp(prefix="patch-")
- os.close(patchfd)
+def compute_patch(srcfile, tgtfile, imgdiff=False):
+ patchfile = common.MakeTempFile(prefix='patch-')
- try:
- with os.fdopen(srcfd, "wb") as f_src:
- for p in src:
- f_src.write(p)
+ cmd = ['imgdiff', '-z'] if imgdiff else ['bsdiff']
+ cmd.extend([srcfile, tgtfile, patchfile])
- with os.fdopen(tgtfd, "wb") as f_tgt:
- for p in tgt:
- f_tgt.write(p)
- try:
- os.unlink(patchfile)
- except OSError:
- pass
- if imgdiff:
- p = subprocess.call(["imgdiff", "-z", srcfile, tgtfile, patchfile],
- stdout=open("/dev/null", "a"),
- stderr=subprocess.STDOUT)
- else:
- p = subprocess.call(["bsdiff", srcfile, tgtfile, patchfile])
+ # Don't dump the bsdiff/imgdiff commands, which are not useful for the case
+ # here, since they contain temp filenames only.
+ p = common.Run(cmd, verbose=False, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output, _ = p.communicate()
- if p:
- raise ValueError("diff failed: " + str(p))
+ if p.returncode != 0:
+ raise ValueError(output)
- with open(patchfile, "rb") as f:
- return f.read()
- finally:
- try:
- os.unlink(srcfile)
- os.unlink(tgtfile)
- os.unlink(patchfile)
- except OSError:
- pass
+ with open(patchfile, 'rb') as f:
+ return f.read()
class Image(object):
+ def RangeSha1(self, ranges):
+ raise NotImplementedError
+
def ReadRangeSet(self, ranges):
raise NotImplementedError
def TotalSha1(self, include_clobbered_blocks=False):
raise NotImplementedError
+ def WriteRangeDataToFd(self, ranges, fd):
+ raise NotImplementedError
+
class EmptyImage(Image):
"""A zero-length image."""
- blocksize = 4096
- care_map = RangeSet()
- clobbered_blocks = RangeSet()
- extended = RangeSet()
- total_blocks = 0
- file_map = {}
+
+ def __init__(self):
+ self.blocksize = 4096
+ self.care_map = RangeSet()
+ self.clobbered_blocks = RangeSet()
+ self.extended = RangeSet()
+ self.total_blocks = 0
+ self.file_map = {}
+
+ def RangeSha1(self, ranges):
+ return sha1().hexdigest()
+
def ReadRangeSet(self, ranges):
return ()
+
def TotalSha1(self, include_clobbered_blocks=False):
# EmptyImage always carries empty clobbered_blocks, so
# include_clobbered_blocks can be ignored.
assert self.clobbered_blocks.size() == 0
return sha1().hexdigest()
+ def WriteRangeDataToFd(self, ranges, fd):
+ raise ValueError("Can't write data from EmptyImage to file")
+
class DataImage(Image):
"""An image wrapped around a single string of data."""
@@ -160,23 +156,39 @@
if clobbered_blocks:
self.file_map["__COPY"] = RangeSet(data=clobbered_blocks)
+ def _GetRangeData(self, ranges):
+ for s, e in ranges:
+ yield self.data[s*self.blocksize:e*self.blocksize]
+
+ def RangeSha1(self, ranges):
+ h = sha1()
+ for data in self._GetRangeData(ranges):
+ h.update(data)
+ return h.hexdigest()
+
def ReadRangeSet(self, ranges):
- return [self.data[s*self.blocksize:e*self.blocksize] for (s, e) in ranges]
+ return [self._GetRangeData(ranges)]
def TotalSha1(self, include_clobbered_blocks=False):
if not include_clobbered_blocks:
- ranges = self.care_map.subtract(self.clobbered_blocks)
- return sha1(self.ReadRangeSet(ranges)).hexdigest()
+ return self.RangeSha1(self.care_map.subtract(self.clobbered_blocks))
else:
return sha1(self.data).hexdigest()
+ def WriteRangeDataToFd(self, ranges, fd):
+ for data in self._GetRangeData(ranges):
+ fd.write(data)
+
class Transfer(object):
- def __init__(self, tgt_name, src_name, tgt_ranges, src_ranges, style, by_id):
+ def __init__(self, tgt_name, src_name, tgt_ranges, src_ranges, tgt_sha1,
+ src_sha1, style, by_id):
self.tgt_name = tgt_name
self.src_name = src_name
self.tgt_ranges = tgt_ranges
self.src_ranges = src_ranges
+ self.tgt_sha1 = tgt_sha1
+ self.src_sha1 = src_sha1
self.style = style
self.intact = (getattr(tgt_ranges, "monotonic", False) and
getattr(src_ranges, "monotonic", False))
@@ -251,6 +263,9 @@
# Implementations are free to break up the data into list/tuple
# elements in any way that is convenient.
#
+# RangeSha1(): a function that returns (as a hex string) the SHA-1
+# hash of all the data in the specified range.
+#
# TotalSha1(): a function that returns (as a hex string) the SHA-1
# hash of all the data in the image (ie, all the blocks in the
# care_map minus clobbered_blocks, or including the clobbered
@@ -277,7 +292,7 @@
self.touched_src_sha1 = None
self.disable_imgdiff = disable_imgdiff
- assert version in (1, 2, 3, 4)
+ assert version in (3, 4)
self.tgt = tgt
if src is None:
@@ -316,14 +331,11 @@
self.FindVertexSequence()
# Fix up the ordering dependencies that the sequence didn't
# satisfy.
- if self.version == 1:
- self.RemoveBackwardEdges()
- else:
- self.ReverseBackwardEdges()
- self.ImproveVertexSequence()
+ self.ReverseBackwardEdges()
+ self.ImproveVertexSequence()
# Ensure the runtime stash size is under the limit.
- if self.version >= 2 and common.OPTIONS.cache_size is not None:
+ if common.OPTIONS.cache_size is not None:
self.ReviseStashSize()
# Double-check our work.
@@ -332,15 +344,6 @@
self.ComputePatches(prefix)
self.WriteTransfers(prefix)
- def HashBlocks(self, source, ranges): # pylint: disable=no-self-use
- data = source.ReadRangeSet(ranges)
- ctx = sha1()
-
- for p in data:
- ctx.update(p)
-
- return ctx.hexdigest()
-
def WriteTransfers(self, prefix):
def WriteSplitTransfers(out, style, target_blocks):
"""Limit the size of operand in command 'new' and 'zero' to 1024 blocks.
@@ -348,7 +351,7 @@
This prevents the target size of one command from being too large; and
might help to avoid fsync errors on some devices."""
- assert (style == "new" or style == "zero")
+ assert style == "new" or style == "zero"
blocks_limit = 1024
total = 0
while target_blocks:
@@ -359,42 +362,26 @@
return total
out = []
-
total = 0
+ # In BBOTA v3+, it uses the hash of the stashed blocks as the stash slot
+ # id. 'stashes' records the map from 'hash' to the ref count. The stash
+ # will be freed only if the count decrements to zero.
stashes = {}
stashed_blocks = 0
max_stashed_blocks = 0
- free_stash_ids = []
- next_stash_id = 0
-
for xf in self.transfers:
- if self.version < 2:
- assert not xf.stash_before
- assert not xf.use_stash
-
- for s, sr in xf.stash_before:
- assert s not in stashes
- if free_stash_ids:
- sid = heapq.heappop(free_stash_ids)
+ for _, sr in xf.stash_before:
+ sh = self.src.RangeSha1(sr)
+ if sh in stashes:
+ stashes[sh] += 1
else:
- sid = next_stash_id
- next_stash_id += 1
- stashes[s] = sid
- if self.version == 2:
+ stashes[sh] = 1
stashed_blocks += sr.size()
- out.append("stash %d %s\n" % (sid, sr.to_string_raw()))
- else:
- sh = self.HashBlocks(self.src, sr)
- if sh in stashes:
- stashes[sh] += 1
- else:
- stashes[sh] = 1
- stashed_blocks += sr.size()
- self.touched_src_ranges = self.touched_src_ranges.union(sr)
- out.append("stash %s %s\n" % (sh, sr.to_string_raw()))
+ self.touched_src_ranges = self.touched_src_ranges.union(sr)
+ out.append("stash %s %s\n" % (sh, sr.to_string_raw()))
if stashed_blocks > max_stashed_blocks:
max_stashed_blocks = stashed_blocks
@@ -402,75 +389,47 @@
free_string = []
free_size = 0
- if self.version == 1:
- src_str = xf.src_ranges.to_string_raw() if xf.src_ranges else ""
- elif self.version >= 2:
+ # <# blocks> <src ranges>
+ # OR
+ # <# blocks> <src ranges> <src locs> <stash refs...>
+ # OR
+ # <# blocks> - <stash refs...>
- # <# blocks> <src ranges>
- # OR
- # <# blocks> <src ranges> <src locs> <stash refs...>
- # OR
- # <# blocks> - <stash refs...>
+ size = xf.src_ranges.size()
+ src_str = [str(size)]
- size = xf.src_ranges.size()
- src_str = [str(size)]
+ unstashed_src_ranges = xf.src_ranges
+ mapped_stashes = []
+ for _, sr in xf.use_stash:
+ unstashed_src_ranges = unstashed_src_ranges.subtract(sr)
+ sh = self.src.RangeSha1(sr)
+ sr = xf.src_ranges.map_within(sr)
+ mapped_stashes.append(sr)
+ assert sh in stashes
+ src_str.append("%s:%s" % (sh, sr.to_string_raw()))
+ stashes[sh] -= 1
+ if stashes[sh] == 0:
+ free_string.append("free %s\n" % (sh,))
+ free_size += sr.size()
+ stashes.pop(sh)
- unstashed_src_ranges = xf.src_ranges
- mapped_stashes = []
- for s, sr in xf.use_stash:
- sid = stashes.pop(s)
- unstashed_src_ranges = unstashed_src_ranges.subtract(sr)
- sh = self.HashBlocks(self.src, sr)
- sr = xf.src_ranges.map_within(sr)
- mapped_stashes.append(sr)
- if self.version == 2:
- src_str.append("%d:%s" % (sid, sr.to_string_raw()))
- # A stash will be used only once. We need to free the stash
- # immediately after the use, instead of waiting for the automatic
- # clean-up at the end. Because otherwise it may take up extra space
- # and lead to OTA failures.
- # Bug: 23119955
- free_string.append("free %d\n" % (sid,))
- free_size += sr.size()
- else:
- assert sh in stashes
- src_str.append("%s:%s" % (sh, sr.to_string_raw()))
- stashes[sh] -= 1
- if stashes[sh] == 0:
- free_size += sr.size()
- free_string.append("free %s\n" % (sh))
- stashes.pop(sh)
- heapq.heappush(free_stash_ids, sid)
-
- if unstashed_src_ranges:
- src_str.insert(1, unstashed_src_ranges.to_string_raw())
- if xf.use_stash:
- mapped_unstashed = xf.src_ranges.map_within(unstashed_src_ranges)
- src_str.insert(2, mapped_unstashed.to_string_raw())
- mapped_stashes.append(mapped_unstashed)
- self.AssertPartition(RangeSet(data=(0, size)), mapped_stashes)
- else:
- src_str.insert(1, "-")
+ if unstashed_src_ranges:
+ src_str.insert(1, unstashed_src_ranges.to_string_raw())
+ if xf.use_stash:
+ mapped_unstashed = xf.src_ranges.map_within(unstashed_src_ranges)
+ src_str.insert(2, mapped_unstashed.to_string_raw())
+ mapped_stashes.append(mapped_unstashed)
self.AssertPartition(RangeSet(data=(0, size)), mapped_stashes)
+ else:
+ src_str.insert(1, "-")
+ self.AssertPartition(RangeSet(data=(0, size)), mapped_stashes)
- src_str = " ".join(src_str)
+ src_str = " ".join(src_str)
- # all versions:
+ # version 3+:
# zero <rangeset>
# new <rangeset>
# erase <rangeset>
- #
- # version 1:
- # bsdiff patchstart patchlen <src rangeset> <tgt rangeset>
- # imgdiff patchstart patchlen <src rangeset> <tgt rangeset>
- # move <src rangeset> <tgt rangeset>
- #
- # version 2:
- # bsdiff patchstart patchlen <tgt rangeset> <src_str>
- # imgdiff patchstart patchlen <tgt rangeset> <src_str>
- # move <tgt rangeset> <src_str>
- #
- # version 3:
# bsdiff patchstart patchlen srchash tgthash <tgt rangeset> <src_str>
# imgdiff patchstart patchlen srchash tgthash <tgt rangeset> <src_str>
# move hash <tgt rangeset> <src_str>
@@ -485,41 +444,6 @@
assert xf.tgt_ranges
assert xf.src_ranges.size() == tgt_size
if xf.src_ranges != xf.tgt_ranges:
- if self.version == 1:
- out.append("%s %s %s\n" % (
- xf.style,
- xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw()))
- elif self.version == 2:
- out.append("%s %s %s\n" % (
- xf.style,
- xf.tgt_ranges.to_string_raw(), src_str))
- elif self.version >= 3:
- # take into account automatic stashing of overlapping blocks
- if xf.src_ranges.overlaps(xf.tgt_ranges):
- temp_stash_usage = stashed_blocks + xf.src_ranges.size()
- if temp_stash_usage > max_stashed_blocks:
- max_stashed_blocks = temp_stash_usage
-
- self.touched_src_ranges = self.touched_src_ranges.union(
- xf.src_ranges)
-
- out.append("%s %s %s %s\n" % (
- xf.style,
- self.HashBlocks(self.tgt, xf.tgt_ranges),
- xf.tgt_ranges.to_string_raw(), src_str))
- total += tgt_size
- elif xf.style in ("bsdiff", "imgdiff"):
- assert xf.tgt_ranges
- assert xf.src_ranges
- if self.version == 1:
- out.append("%s %d %d %s %s\n" % (
- xf.style, xf.patch_start, xf.patch_len,
- xf.src_ranges.to_string_raw(), xf.tgt_ranges.to_string_raw()))
- elif self.version == 2:
- out.append("%s %d %d %s %s\n" % (
- xf.style, xf.patch_start, xf.patch_len,
- xf.tgt_ranges.to_string_raw(), src_str))
- elif self.version >= 3:
# take into account automatic stashing of overlapping blocks
if xf.src_ranges.overlaps(xf.tgt_ranges):
temp_stash_usage = stashed_blocks + xf.src_ranges.size()
@@ -529,12 +453,28 @@
self.touched_src_ranges = self.touched_src_ranges.union(
xf.src_ranges)
- out.append("%s %d %d %s %s %s %s\n" % (
+ out.append("%s %s %s %s\n" % (
xf.style,
- xf.patch_start, xf.patch_len,
- self.HashBlocks(self.src, xf.src_ranges),
- self.HashBlocks(self.tgt, xf.tgt_ranges),
+ xf.tgt_sha1,
xf.tgt_ranges.to_string_raw(), src_str))
+ total += tgt_size
+ elif xf.style in ("bsdiff", "imgdiff"):
+ assert xf.tgt_ranges
+ assert xf.src_ranges
+ # take into account automatic stashing of overlapping blocks
+ if xf.src_ranges.overlaps(xf.tgt_ranges):
+ temp_stash_usage = stashed_blocks + xf.src_ranges.size()
+ if temp_stash_usage > max_stashed_blocks:
+ max_stashed_blocks = temp_stash_usage
+
+ self.touched_src_ranges = self.touched_src_ranges.union(xf.src_ranges)
+
+ out.append("%s %d %d %s %s %s %s\n" % (
+ xf.style,
+ xf.patch_start, xf.patch_len,
+ xf.src_sha1,
+ xf.tgt_sha1,
+ xf.tgt_ranges.to_string_raw(), src_str))
total += tgt_size
elif xf.style == "zero":
assert xf.tgt_ranges
@@ -548,7 +488,7 @@
out.append("".join(free_string))
stashed_blocks -= free_size
- if self.version >= 2 and common.OPTIONS.cache_size is not None:
+ if common.OPTIONS.cache_size is not None:
# Sanity check: abort if we're going to need more stash space than
# the allowed size (cache_size * threshold). There are two purposes
# of having a threshold here. a) Part of the cache may have been
@@ -557,15 +497,13 @@
cache_size = common.OPTIONS.cache_size
stash_threshold = common.OPTIONS.stash_threshold
max_allowed = cache_size * stash_threshold
- assert max_stashed_blocks * self.tgt.blocksize < max_allowed, \
+ assert max_stashed_blocks * self.tgt.blocksize <= max_allowed, \
'Stash size %d (%d * %d) exceeds the limit %d (%d * %.2f)' % (
max_stashed_blocks * self.tgt.blocksize, max_stashed_blocks,
self.tgt.blocksize, max_allowed, cache_size,
stash_threshold)
- if self.version >= 3:
- self.touched_src_sha1 = self.HashBlocks(
- self.src, self.touched_src_ranges)
+ self.touched_src_sha1 = self.src.RangeSha1(self.touched_src_ranges)
# Zero out extended blocks as a workaround for bug 20881595.
if self.tgt.extended:
@@ -593,43 +531,40 @@
out.insert(0, "%d\n" % (self.version,)) # format version number
out.insert(1, "%d\n" % (total,))
- if self.version >= 2:
- # version 2 only: after the total block count, we give the number
- # of stash slots needed, and the maximum size needed (in blocks)
- out.insert(2, str(next_stash_id) + "\n")
- out.insert(3, str(max_stashed_blocks) + "\n")
+ # v3+: the number of stash slots is unused.
+ out.insert(2, "0\n")
+ out.insert(3, str(max_stashed_blocks) + "\n")
with open(prefix + ".transfer.list", "wb") as f:
for i in out:
f.write(i)
- if self.version >= 2:
- self._max_stashed_size = max_stashed_blocks * self.tgt.blocksize
- OPTIONS = common.OPTIONS
- if OPTIONS.cache_size is not None:
- max_allowed = OPTIONS.cache_size * OPTIONS.stash_threshold
- print("max stashed blocks: %d (%d bytes), "
- "limit: %d bytes (%.2f%%)\n" % (
- max_stashed_blocks, self._max_stashed_size, max_allowed,
- self._max_stashed_size * 100.0 / max_allowed))
- else:
- print("max stashed blocks: %d (%d bytes), limit: <unknown>\n" % (
- max_stashed_blocks, self._max_stashed_size))
+ self._max_stashed_size = max_stashed_blocks * self.tgt.blocksize
+ OPTIONS = common.OPTIONS
+ if OPTIONS.cache_size is not None:
+ max_allowed = OPTIONS.cache_size * OPTIONS.stash_threshold
+ print("max stashed blocks: %d (%d bytes), "
+ "limit: %d bytes (%.2f%%)\n" % (
+ max_stashed_blocks, self._max_stashed_size, max_allowed,
+ self._max_stashed_size * 100.0 / max_allowed))
+ else:
+ print("max stashed blocks: %d (%d bytes), limit: <unknown>\n" % (
+ max_stashed_blocks, self._max_stashed_size))
def ReviseStashSize(self):
print("Revising stash size...")
- stashes = {}
+ stash_map = {}
# Create the map between a stash and its def/use points. For example, for a
- # given stash of (idx, sr), stashes[idx] = (sr, def_cmd, use_cmd).
+ # given stash of (raw_id, sr), stash_map[raw_id] = (sr, def_cmd, use_cmd).
for xf in self.transfers:
# Command xf defines (stores) all the stashes in stash_before.
- for idx, sr in xf.stash_before:
- stashes[idx] = (sr, xf)
+ for stash_raw_id, sr in xf.stash_before:
+ stash_map[stash_raw_id] = (sr, xf)
# Record all the stashes command xf uses.
- for idx, _ in xf.use_stash:
- stashes[idx] += (xf,)
+ for stash_raw_id, _ in xf.use_stash:
+ stash_map[stash_raw_id] += (xf,)
# Compute the maximum blocks available for stash based on /cache size and
# the threshold.
@@ -637,6 +572,8 @@
stash_threshold = common.OPTIONS.stash_threshold
max_allowed = cache_size * stash_threshold / self.tgt.blocksize
+ # See the comments for 'stashes' in WriteTransfers().
+ stashes = {}
stashed_blocks = 0
new_blocks = 0
@@ -648,23 +585,30 @@
replaced_cmds = []
# xf.stash_before generates explicit stash commands.
- for idx, sr in xf.stash_before:
- if stashed_blocks + sr.size() > max_allowed:
+ for stash_raw_id, sr in xf.stash_before:
+ # Check the post-command stashed_blocks.
+ stashed_blocks_after = stashed_blocks
+ sh = self.src.RangeSha1(sr)
+ if sh not in stashes:
+ stashed_blocks_after += sr.size()
+
+ if stashed_blocks_after > max_allowed:
# We cannot stash this one for a later command. Find out the command
# that will use this stash and replace the command with "new".
- use_cmd = stashes[idx][2]
+ use_cmd = stash_map[stash_raw_id][2]
replaced_cmds.append(use_cmd)
print("%10d %9s %s" % (sr.size(), "explicit", use_cmd))
else:
- stashed_blocks += sr.size()
-
- # xf.use_stash generates free commands.
- for _, sr in xf.use_stash:
- stashed_blocks -= sr.size()
+ # Update the stashes map.
+ if sh in stashes:
+ stashes[sh] += 1
+ else:
+ stashes[sh] = 1
+ stashed_blocks = stashed_blocks_after
# "move" and "diff" may introduce implicit stashes in BBOTA v3. Prior to
# ComputePatches(), they both have the style of "diff".
- if xf.style == "diff" and self.version >= 3:
+ if xf.style == "diff":
assert xf.tgt_ranges and xf.src_ranges
if xf.src_ranges.overlaps(xf.tgt_ranges):
if stashed_blocks + xf.src_ranges.size() > max_allowed:
@@ -675,26 +619,36 @@
for cmd in replaced_cmds:
# It no longer uses any commands in "use_stash". Remove the def points
# for all those stashes.
- for idx, sr in cmd.use_stash:
- def_cmd = stashes[idx][1]
- assert (idx, sr) in def_cmd.stash_before
- def_cmd.stash_before.remove((idx, sr))
+ for stash_raw_id, sr in cmd.use_stash:
+ def_cmd = stash_map[stash_raw_id][1]
+ assert (stash_raw_id, sr) in def_cmd.stash_before
+ def_cmd.stash_before.remove((stash_raw_id, sr))
# Add up blocks that violates space limit and print total number to
# screen later.
new_blocks += cmd.tgt_ranges.size()
cmd.ConvertToNew()
+ # xf.use_stash may generate free commands.
+ for _, sr in xf.use_stash:
+ sh = self.src.RangeSha1(sr)
+ assert sh in stashes
+ stashes[sh] -= 1
+ if stashes[sh] == 0:
+ stashed_blocks -= sr.size()
+ stashes.pop(sh)
+
num_of_bytes = new_blocks * self.tgt.blocksize
print(" Total %d blocks (%d bytes) are packed as new blocks due to "
"insufficient cache size." % (new_blocks, num_of_bytes))
+ return new_blocks
def ComputePatches(self, prefix):
print("Reticulating splines...")
- diff_q = []
+ diff_queue = []
patch_num = 0
with open(prefix + ".new.dat", "wb") as new_f:
- for xf in self.transfers:
+ for index, xf in enumerate(self.transfers):
if xf.style == "zero":
tgt_size = xf.tgt_ranges.size() * self.tgt.blocksize
print("%10d %10d (%6.2f%%) %7s %s %s" % (
@@ -702,17 +656,13 @@
str(xf.tgt_ranges)))
elif xf.style == "new":
- for piece in self.tgt.ReadRangeSet(xf.tgt_ranges):
- new_f.write(piece)
+ self.tgt.WriteRangeDataToFd(xf.tgt_ranges, new_f)
tgt_size = xf.tgt_ranges.size() * self.tgt.blocksize
print("%10d %10d (%6.2f%%) %7s %s %s" % (
tgt_size, tgt_size, 100.0, xf.style,
xf.tgt_name, str(xf.tgt_ranges)))
elif xf.style == "diff":
- src = self.src.ReadRangeSet(xf.src_ranges)
- tgt = self.tgt.ReadRangeSet(xf.tgt_ranges)
-
# We can't compare src and tgt directly because they may have
# the same content but be broken up into blocks differently, eg:
#
@@ -721,20 +671,11 @@
# We want those to compare equal, ideally without having to
# actually concatenate the strings (these may be tens of
# megabytes).
-
- src_sha1 = sha1()
- for p in src:
- src_sha1.update(p)
- tgt_sha1 = sha1()
- tgt_size = 0
- for p in tgt:
- tgt_sha1.update(p)
- tgt_size += len(p)
-
- if src_sha1.digest() == tgt_sha1.digest():
+ if xf.src_sha1 == xf.tgt_sha1:
# These are identical; we don't need to generate a patch,
# just issue copy commands on the device.
xf.style = "move"
+ tgt_size = xf.tgt_ranges.size() * self.tgt.blocksize
if xf.src_ranges != xf.tgt_ranges:
print("%10d %10d (%6.2f%%) %7s %s %s (from %s)" % (
tgt_size, tgt_size, 100.0, xf.style,
@@ -761,38 +702,74 @@
xf.tgt_name.split(".")[-1].lower()
in ("apk", "jar", "zip"))
xf.style = "imgdiff" if imgdiff else "bsdiff"
- diff_q.append((tgt_size, src, tgt, xf, patch_num))
+ diff_queue.append((index, imgdiff, patch_num))
patch_num += 1
else:
assert False, "unknown style " + xf.style
- if diff_q:
+ if diff_queue:
if self.threads > 1:
print("Computing patches (using %d threads)..." % (self.threads,))
else:
print("Computing patches...")
- diff_q.sort()
- patches = [None] * patch_num
+ diff_total = len(diff_queue)
+ patches = [None] * diff_total
+ error_messages = []
+ if sys.stdout.isatty():
+ global diff_done
+ diff_done = 0
- # TODO: Rewrite with multiprocessing.ThreadPool?
+ # Using multiprocessing doesn't give additional benefits, due to the
+ # pattern of the code. The diffing work is done by subprocess.call, which
+ # already runs in a separate process (not affected much by the GIL -
+ # Global Interpreter Lock). Using multiprocess also requires either a)
+ # writing the diff input files in the main process before forking, or b)
+ # reopening the image file (SparseImage) in the worker processes. Doing
+ # neither of them further improves the performance.
lock = threading.Lock()
def diff_worker():
while True:
with lock:
- if not diff_q:
+ if not diff_queue:
return
- tgt_size, src, tgt, xf, patchnum = diff_q.pop()
- patch = compute_patch(src, tgt, imgdiff=(xf.style == "imgdiff"))
- size = len(patch)
+ xf_index, imgdiff, patch_index = diff_queue.pop()
+
+ xf = self.transfers[xf_index]
+ src_ranges = xf.src_ranges
+ tgt_ranges = xf.tgt_ranges
+
+ # Needs lock since WriteRangeDataToFd() is stateful (calling seek).
with lock:
- patches[patchnum] = (patch, xf)
- print("%10d %10d (%6.2f%%) %7s %s %s %s" % (
- size, tgt_size, size * 100.0 / tgt_size, xf.style,
- xf.tgt_name if xf.tgt_name == xf.src_name else (
- xf.tgt_name + " (from " + xf.src_name + ")"),
- str(xf.tgt_ranges), str(xf.src_ranges)))
+ src_file = common.MakeTempFile(prefix="src-")
+ with open(src_file, "wb") as fd:
+ self.src.WriteRangeDataToFd(src_ranges, fd)
+
+ tgt_file = common.MakeTempFile(prefix="tgt-")
+ with open(tgt_file, "wb") as fd:
+ self.tgt.WriteRangeDataToFd(tgt_ranges, fd)
+
+ try:
+ patch = compute_patch(src_file, tgt_file, imgdiff)
+ except ValueError as e:
+ with lock:
+ error_messages.append(
+ "Failed to generate %s for %s: tgt=%s, src=%s:\n%s" % (
+ "imgdiff" if imgdiff else "bsdiff",
+ xf.tgt_name if xf.tgt_name == xf.src_name else
+ xf.tgt_name + " (from " + xf.src_name + ")",
+ xf.tgt_ranges, xf.src_ranges, e.message))
+
+ with lock:
+ patches[patch_index] = (xf_index, patch)
+ if sys.stdout.isatty():
+ global diff_done
+ diff_done += 1
+ progress = diff_done * 100 / diff_total
+ # '\033[K' is to clear to EOL.
+ print(' [%d%%] %s\033[K' % (progress, xf.tgt_name), end='\r')
+ sys.stdout.flush()
threads = [threading.Thread(target=diff_worker)
for _ in range(self.threads)]
@@ -800,16 +777,33 @@
th.start()
while threads:
threads.pop().join()
+
+ if sys.stdout.isatty():
+ print('\n')
+
+ if error_messages:
+ print('\n'.join(error_messages))
+ sys.exit(1)
else:
patches = []
- p = 0
- with open(prefix + ".patch.dat", "wb") as patch_f:
- for patch, xf in patches:
- xf.patch_start = p
+ offset = 0
+ with open(prefix + ".patch.dat", "wb") as patch_fd:
+ for index, patch in patches:
+ xf = self.transfers[index]
xf.patch_len = len(patch)
- patch_f.write(patch)
- p += len(patch)
+ xf.patch_start = offset
+ offset += xf.patch_len
+ patch_fd.write(patch)
+
+ if common.OPTIONS.verbose:
+ tgt_size = xf.tgt_ranges.size() * self.tgt.blocksize
+ print("%10d %10d (%6.2f%%) %7s %s %s %s" % (
+ xf.patch_len, tgt_size, xf.patch_len * 100.0 / tgt_size,
+ xf.style,
+ xf.tgt_name if xf.tgt_name == xf.src_name else (
+ xf.tgt_name + " (from " + xf.src_name + ")"),
+ xf.tgt_ranges, xf.src_ranges))
def AssertSequenceGood(self):
# Simulate the sequences of transfers we will output, and check that:
@@ -824,9 +818,8 @@
# Check that the input blocks for this transfer haven't yet been touched.
x = xf.src_ranges
- if self.version >= 2:
- for _, sr in xf.use_stash:
- x = x.subtract(sr)
+ for _, sr in xf.use_stash:
+ x = x.subtract(sr)
for s, e in x:
# Source image could be larger. Don't check the blocks that are in the
@@ -926,10 +919,21 @@
lost_source))
def ReverseBackwardEdges(self):
+ """Reverse unsatisfying edges and compute pairs of stashed blocks.
+
+ For each transfer, make sure it properly stashes the blocks it touches and
+ will be used by later transfers. It uses pairs of (stash_raw_id, range) to
+ record the blocks to be stashed. 'stash_raw_id' is an id that uniquely
+ identifies each pair. Note that for the same range (e.g. RangeSet("1-5")),
+ it is possible to have multiple pairs with different 'stash_raw_id's. Each
+ 'stash_raw_id' will be consumed by one transfer. In BBOTA v3+, identical
+ blocks will be written to the same stash slot in WriteTransfers().
+ """
+
print("Reversing backward edges...")
in_order = 0
out_of_order = 0
- stashes = 0
+ stash_raw_id = 0
stash_size = 0
for xf in self.transfers:
@@ -947,9 +951,9 @@
overlap = xf.src_ranges.intersect(u.tgt_ranges)
assert overlap
- u.stash_before.append((stashes, overlap))
- xf.use_stash.append((stashes, overlap))
- stashes += 1
+ u.stash_before.append((stash_raw_id, overlap))
+ xf.use_stash.append((stash_raw_id, overlap))
+ stash_raw_id += 1
stash_size += overlap.size()
# reverse the edge direction; now xf must go after u
@@ -1146,7 +1150,9 @@
# Change nothing for small files.
if (tgt_ranges.size() <= max_blocks_per_transfer and
src_ranges.size() <= max_blocks_per_transfer):
- Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
+ Transfer(tgt_name, src_name, tgt_ranges, src_ranges,
+ self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
+ style, by_id)
return
while (tgt_ranges.size() > max_blocks_per_transfer and
@@ -1156,8 +1162,9 @@
tgt_first = tgt_ranges.first(max_blocks_per_transfer)
src_first = src_ranges.first(max_blocks_per_transfer)
- Transfer(tgt_split_name, src_split_name, tgt_first, src_first, style,
- by_id)
+ Transfer(tgt_split_name, src_split_name, tgt_first, src_first,
+ self.tgt.RangeSha1(tgt_first), self.src.RangeSha1(src_first),
+ style, by_id)
tgt_ranges = tgt_ranges.subtract(tgt_first)
src_ranges = src_ranges.subtract(src_first)
@@ -1169,8 +1176,9 @@
assert tgt_ranges.size() and src_ranges.size()
tgt_split_name = "%s-%d" % (tgt_name, pieces)
src_split_name = "%s-%d" % (src_name, pieces)
- Transfer(tgt_split_name, src_split_name, tgt_ranges, src_ranges, style,
- by_id)
+ Transfer(tgt_split_name, src_split_name, tgt_ranges, src_ranges,
+ self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
+ style, by_id)
def AddTransfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id,
split=False):
@@ -1179,7 +1187,9 @@
# We specialize diff transfers only (which covers bsdiff/imgdiff/move);
# otherwise add the Transfer() as is.
if style != "diff" or not split:
- Transfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
+ Transfer(tgt_name, src_name, tgt_ranges, src_ranges,
+ self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
+ style, by_id)
return
# Handle .odex files specially to analyze the block-wise difference. If
@@ -1260,7 +1270,7 @@
elif tgt_fn in self.src.file_map:
# Look for an exact pathname match in the source.
AddTransfer(tgt_fn, tgt_fn, tgt_ranges, self.src.file_map[tgt_fn],
- "diff", self.transfers, self.version >= 3)
+ "diff", self.transfers, True)
continue
b = os.path.basename(tgt_fn)
@@ -1268,7 +1278,7 @@
# Look for an exact basename match in the source.
src_fn = self.src_basenames[b]
AddTransfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
- "diff", self.transfers, self.version >= 3)
+ "diff", self.transfers, True)
continue
b = re.sub("[0-9]+", "#", b)
@@ -1279,7 +1289,7 @@
# that get bumped.)
src_fn = self.src_numpatterns[b]
AddTransfer(tgt_fn, src_fn, tgt_ranges, self.src.file_map[src_fn],
- "diff", self.transfers, self.version >= 3)
+ "diff", self.transfers, True)
continue
AddTransfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index cd61246..de75a6b 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -15,9 +15,9 @@
# limitations under the License.
"""
-Build image output_image_file from input_directory and properties_file.
+Build image output_image_file from input_directory, properties_file, and target_out_dir
-Usage: build_image input_directory properties_file output_image_file
+Usage: build_image input_directory properties_file output_image_file target_out_dir
"""
import os
@@ -25,8 +25,8 @@
import re
import subprocess
import sys
-import commands
import common
+import shlex
import shutil
import sparse_img
import tempfile
@@ -51,29 +51,24 @@
return (output, p.returncode)
def GetVerityFECSize(partition_size):
- cmd = "fec -s %d" % partition_size
- status, output = commands.getstatusoutput(cmd)
- if status:
- print output
+ cmd = ["fec", "-s", str(partition_size)]
+ output, exit_code = RunCommand(cmd)
+ if exit_code != 0:
return False, 0
return True, int(output)
def GetVerityTreeSize(partition_size):
- cmd = "build_verity_tree -s %d"
- cmd %= partition_size
- status, output = commands.getstatusoutput(cmd)
- if status:
- print output
+ cmd = ["build_verity_tree", "-s", str(partition_size)]
+ output, exit_code = RunCommand(cmd)
+ if exit_code != 0:
return False, 0
return True, int(output)
def GetVerityMetadataSize(partition_size):
- cmd = "system/extras/verity/build_verity_metadata.py size %d"
- cmd %= partition_size
-
- status, output = commands.getstatusoutput(cmd)
- if status:
- print output
+ cmd = ["system/extras/verity/build_verity_metadata.py", "size",
+ str(partition_size)]
+ output, exit_code = RunCommand(cmd)
+ if exit_code != 0:
return False, 0
return True, int(output)
@@ -102,6 +97,53 @@
simg = sparse_img.SparseImage(image_file, mode="r+b", build_map=False)
simg.AppendFillChunk(0, blocks)
+def AVBCalcMaxImageSize(avbtool, footer_type, partition_size, additional_args):
+ """Calculates max image size for a given partition size.
+
+ Args:
+ avbtool: String with path to avbtool.
+ footer_type: 'hash' or 'hashtree' for generating footer.
+ partition_size: The size of the partition in question.
+ additional_args: Additional arguments to pass to 'avbtool
+ add_hashtree_image'.
+ Returns:
+ The maximum image size or 0 if an error occurred.
+ """
+ cmdline = "%s add_%s_footer " % (avbtool, footer_type)
+ cmdline += "--partition_size %d " % partition_size
+ cmdline += "--calc_max_image_size "
+ cmdline += additional_args
+ (output, exit_code) = RunCommand(shlex.split(cmdline))
+ if exit_code != 0:
+ return 0
+ else:
+ return int(output)
+
+def AVBAddFooter(image_path, avbtool, footer_type, partition_size,
+ partition_name, signing_args, additional_args):
+ """Adds dm-verity hashtree and AVB metadata to an image.
+
+ Args:
+ image_path: Path to image to modify.
+ avbtool: String with path to avbtool.
+ footer_type: 'hash' or 'hashtree' for generating footer.
+ partition_size: The size of the partition in question.
+ partition_name: The name of the partition - will be embedded in metadata.
+ signing_args: Arguments for signing the image.
+ additional_args: Additional arguments to pass to 'avbtool
+ add_hashtree_image'.
+ Returns:
+ True if the operation succeeded.
+ """
+ cmdline = "%s add_%s_footer " % (avbtool, footer_type)
+ cmdline += "--partition_size %d " % partition_size
+ cmdline += "--partition_name %s " % partition_name
+ cmdline += "--image %s " % image_path
+ cmdline += signing_args + " "
+ cmdline += additional_args
+ (_, exit_code) = RunCommand(shlex.split(cmdline))
+ return exit_code == 0
+
def AdjustPartitionSizeForVerity(partition_size, fec_supported):
"""Modifies the provided partition size to account for the verity metadata.
@@ -145,21 +187,19 @@
def BuildVerityFEC(sparse_image_path, verity_path, verity_fec_path,
padding_size):
- cmd = "fec -e -p %d %s %s %s" % (padding_size, sparse_image_path,
- verity_path, verity_fec_path)
- print cmd
- status, output = commands.getstatusoutput(cmd)
- if status:
+ cmd = ["fec", "-e", "-p", str(padding_size), sparse_image_path,
+ verity_path, verity_fec_path]
+ output, exit_code = RunCommand(cmd)
+ if exit_code != 0:
print "Could not build FEC data! Error: %s" % output
return False
return True
def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict):
- cmd = "build_verity_tree -A %s %s %s" % (
- FIXED_SALT, sparse_image_path, verity_image_path)
- print cmd
- status, output = commands.getstatusoutput(cmd)
- if status:
+ cmd = ["build_verity_tree", "-A", FIXED_SALT, sparse_image_path,
+ verity_image_path]
+ output, exit_code = RunCommand(cmd)
+ if exit_code != 0:
print "Could not build verity tree! Error: %s" % output
return False
root, salt = output.split()
@@ -169,16 +209,13 @@
def BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
block_device, signer_path, key, signer_args):
- cmd_template = (
- "system/extras/verity/build_verity_metadata.py build " +
- "%s %s %s %s %s %s %s")
- cmd = cmd_template % (image_size, verity_metadata_path, root_hash, salt,
- block_device, signer_path, key)
+ cmd = ["system/extras/verity/build_verity_metadata.py", "build",
+ str(image_size), verity_metadata_path, root_hash, salt, block_device,
+ signer_path, key]
if signer_args:
- cmd += " --signer_args=\"%s\"" % (' '.join(signer_args),)
- print cmd
- status, output = commands.getstatusoutput(cmd)
- if status:
+ cmd.append("--signer_args=\"%s\"" % (' '.join(signer_args),))
+ output, exit_code = RunCommand(cmd)
+ if exit_code != 0:
print "Could not build verity metadata! Error: %s" % output
return False
return True
@@ -192,22 +229,19 @@
Returns:
True on success, False on failure.
"""
- cmd = "append2simg %s %s"
- cmd %= (sparse_image_path, unsparse_image_path)
- print cmd
- status, output = commands.getstatusoutput(cmd)
- if status:
+ cmd = ["append2simg", sparse_image_path, unsparse_image_path]
+ output, exit_code = RunCommand(cmd)
+ if exit_code != 0:
print "%s: %s" % (error_message, output)
return False
return True
def Append(target, file_to_append, error_message):
- cmd = 'cat %s >> %s' % (file_to_append, target)
- print cmd
- status, output = commands.getstatusoutput(cmd)
- if status:
- print "%s: %s" % (error_message, output)
- return False
+ print "appending %s to %s" % (file_to_append, target)
+ with open(target, "a") as out_file:
+ with open(file_to_append, "r") as input_file:
+ for line in input_file:
+ out_file.write(line)
return True
def BuildVerifiedImage(data_image_path, verity_image_path,
@@ -378,8 +412,27 @@
prop_dict["original_partition_size"] = str(partition_size)
prop_dict["verity_size"] = str(verity_size)
+ # Adjust partition size for AVB hash footer or AVB hashtree footer.
+ avb_footer_type = ''
+ if prop_dict.get("avb_hash_enable") == "true":
+ avb_footer_type = 'hash'
+ elif prop_dict.get("avb_hashtree_enable") == "true":
+ avb_footer_type = 'hashtree'
+
+ if avb_footer_type:
+ avbtool = prop_dict.get("avb_avbtool")
+ partition_size = int(prop_dict.get("partition_size"))
+ # avb_add_hash_footer_args or avb_add_hashtree_footer_args.
+ additional_args = prop_dict["avb_add_" + avb_footer_type + "_footer_args"]
+ max_image_size = AVBCalcMaxImageSize(avbtool, avb_footer_type, partition_size,
+ additional_args)
+ if max_image_size == 0:
+ return False
+ prop_dict["partition_size"] = str(max_image_size)
+ prop_dict["original_partition_size"] = str(partition_size)
+
if fs_type.startswith("ext"):
- build_command = ["mkuserimg.sh"]
+ build_command = [prop_dict["ext_mkuserimg"]]
if "extfs_sparse_flag" in prop_dict:
build_command.append(prop_dict["extfs_sparse_flag"])
run_fsck = True
@@ -404,6 +457,10 @@
build_command.extend(["-L", prop_dict["mount_point"]])
if "extfs_inode_count" in prop_dict:
build_command.extend(["-i", prop_dict["extfs_inode_count"]])
+ if "flash_erase_block_size" in prop_dict:
+ build_command.extend(["-e", prop_dict["flash_erase_block_size"]])
+ if "flash_logical_block_size" in prop_dict:
+ build_command.extend(["-o", prop_dict["flash_logical_block_size"]])
if "selinux_fc" in prop_dict:
build_command.append(prop_dict["selinux_fc"])
elif fs_type.startswith("squash"):
@@ -432,14 +489,8 @@
build_command = ["mkf2fsuserimg.sh"]
build_command.extend([out_file, prop_dict["partition_size"]])
else:
- build_command = ["mkyaffs2image", "-f"]
- if prop_dict.get("mkyaffs2_extra_flags", None):
- build_command.extend(prop_dict["mkyaffs2_extra_flags"].split())
- build_command.append(in_dir)
- build_command.append(out_file)
- if "selinux_fc" in prop_dict:
- build_command.append(prop_dict["selinux_fc"])
- build_command.append(prop_dict["mount_point"])
+ print("Error: unknown filesystem type '%s'" % (fs_type))
+ return False
if in_dir != origin_in:
# Construct a staging directory of the root file system.
@@ -519,6 +570,18 @@
if not MakeVerityEnabledImage(out_file, verity_fec_supported, prop_dict):
return False
+ # Add AVB HASH or HASHTREE footer (metadata).
+ if avb_footer_type:
+ avbtool = prop_dict.get("avb_avbtool")
+ original_partition_size = int(prop_dict.get("original_partition_size"))
+ partition_name = prop_dict["partition_name"]
+ signing_args = prop_dict["avb_signing_args"]
+ # avb_add_hash_footer_args or avb_add_hashtree_footer_args
+ additional_args = prop_dict["avb_add_" + avb_footer_type + "_footer_args"]
+ if not AVBAddFooter(out_file, avbtool, avb_footer_type, original_partition_size,
+ partition_name, signing_args, additional_args):
+ return False
+
if run_fsck and prop_dict.get("skip_fsck") != "true":
success, unsparse_image = UnsparseImage(out_file, replace=False)
if not success:
@@ -554,13 +617,16 @@
common_props = (
"extfs_sparse_flag",
"squashfs_sparse_flag",
- "mkyaffs2_extra_flags",
"selinux_fc",
"skip_fsck",
+ "ext_mkuserimg",
"verity",
"verity_key",
"verity_signer_cmd",
- "verity_fec"
+ "verity_fec",
+ "board_avb_enable",
+ "avb_signing_args",
+ "avb_avbtool"
)
for p in common_props:
copy_prop(p, p)
@@ -584,6 +650,9 @@
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_avb_hashtree_enable", "avb_hashtree_enable")
+ copy_prop("system_avb_add_hashtree_footer_args",
+ "avb_add_hashtree_footer_args")
copy_prop("system_extfs_inode_count", "extfs_inode_count")
elif mount_point == "system_other":
# We inherit the selinux policies of /system since we contain some of its files.
@@ -598,12 +667,17 @@
copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
copy_prop("system_squashfs_block_size", "squashfs_block_size")
copy_prop("system_base_fs_file", "base_fs_file")
+ copy_prop("system_avb_hashtree_enable", "avb_hashtree_enable")
+ copy_prop("system_avb_add_hashtree_footer_args",
+ "avb_add_hashtree_footer_args")
copy_prop("system_extfs_inode_count", "extfs_inode_count")
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")
elif mount_point == "cache":
copy_prop("cache_fs_type", "fs_type")
copy_prop("cache_size", "partition_size")
@@ -618,6 +692,9 @@
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_avb_hashtree_enable", "avb_hashtree_enable")
+ copy_prop("vendor_avb_add_hashtree_footer_args",
+ "avb_add_hashtree_footer_args")
copy_prop("vendor_extfs_inode_count", "extfs_inode_count")
elif mount_point == "oem":
copy_prop("fs_type", "fs_type")
@@ -625,7 +702,7 @@
copy_prop("oem_journal_size", "journal_size")
copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
copy_prop("oem_extfs_inode_count", "extfs_inode_count")
-
+ d["partition_name"] = mount_point
return d
diff --git a/tools/releasetools/check_ota_package_signature.py b/tools/releasetools/check_ota_package_signature.py
new file mode 100755
index 0000000..548b619
--- /dev/null
+++ b/tools/releasetools/check_ota_package_signature.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# 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.
+
+"""
+Verify a given OTA package with the specifed certificate.
+"""
+
+from __future__ import print_function
+
+import argparse
+import common
+import re
+import subprocess
+import sys
+
+from hashlib import sha1
+from hashlib import sha256
+
+
+def cert_uses_sha256(cert):
+ """Check if the cert uses SHA-256 hashing algorithm."""
+
+ cmd = ['openssl', 'x509', '-text', '-noout', '-in', cert]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ cert_dump, _ = p1.communicate()
+
+ algorithm = re.search(r'Signature Algorithm: ([a-zA-Z0-9]+)', cert_dump)
+ assert algorithm, "Failed to identify the signature algorithm."
+
+ assert not algorithm.group(1).startswith('ecdsa'), (
+ 'This script doesn\'t support verifying ECDSA signed package yet.')
+
+ return algorithm.group(1).startswith('sha256')
+
+
+def verify_package(cert, package):
+ """Verify the given package with the certificate.
+
+ (Comments from bootable/recovery/verifier.cpp:)
+
+ An archive with a whole-file signature will end in six bytes:
+
+ (2-byte signature start) $ff $ff (2-byte comment size)
+
+ (As far as the ZIP format is concerned, these are part of the
+ archive comment.) We start by reading this footer, this tells
+ us how far back from the end we have to start reading to find
+ the whole comment.
+ """
+
+ print('Package: %s' % (package,))
+ print('Certificate: %s' % (cert,))
+
+ # Read in the package.
+ with open(package) as package_file:
+ package_bytes = package_file.read()
+
+ length = len(package_bytes)
+ assert length >= 6, "Not big enough to contain footer."
+
+ footer = [ord(x) for x in package_bytes[-6:]]
+ assert footer[2] == 0xff and footer[3] == 0xff, "Footer is wrong."
+
+ signature_start_from_end = (footer[1] << 8) + footer[0]
+ assert signature_start_from_end > 6, "Signature start is in the footer."
+
+ signature_start = length - signature_start_from_end
+
+ # Determine how much of the file is covered by the signature. This is
+ # everything except the signature data and length, which includes all of the
+ # EOCD except for the comment length field (2 bytes) and the comment data.
+ comment_len = (footer[5] << 8) + footer[4]
+ signed_len = length - comment_len - 2
+
+ print('Package length: %d' % (length,))
+ print('Comment length: %d' % (comment_len,))
+ print('Signed data length: %d' % (signed_len,))
+ print('Signature start: %d' % (signature_start,))
+
+ use_sha256 = cert_uses_sha256(cert)
+ print('Use SHA-256: %s' % (use_sha256,))
+
+ if use_sha256:
+ h = sha256()
+ else:
+ h = sha1()
+ h.update(package_bytes[:signed_len])
+ package_digest = h.hexdigest().lower()
+
+ print('Digest: %s\n' % (package_digest,))
+
+ # Get the signature from the input package.
+ signature = package_bytes[signature_start:-6]
+ sig_file = common.MakeTempFile(prefix='sig-')
+ with open(sig_file, 'wb') as f:
+ f.write(signature)
+
+ # Parse the signature and get the hash.
+ cmd = ['openssl', 'asn1parse', '-inform', 'DER', '-in', sig_file]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ sig, _ = p1.communicate()
+ assert p1.returncode == 0, "Failed to parse the signature."
+
+ digest_line = sig.strip().split('\n')[-1]
+ digest_string = digest_line.split(':')[3]
+ digest_file = common.MakeTempFile(prefix='digest-')
+ with open(digest_file, 'wb') as f:
+ f.write(digest_string.decode('hex'))
+
+ # Verify the digest by outputing the decrypted result in ASN.1 structure.
+ decrypted_file = common.MakeTempFile(prefix='decrypted-')
+ cmd = ['openssl', 'rsautl', '-verify', '-certin', '-inkey', cert,
+ '-in', digest_file, '-out', decrypted_file]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ p1.communicate()
+ assert p1.returncode == 0, "Failed to run openssl rsautl -verify."
+
+ # Parse the output ASN.1 structure.
+ cmd = ['openssl', 'asn1parse', '-inform', 'DER', '-in', decrypted_file]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ decrypted_output, _ = p1.communicate()
+ assert p1.returncode == 0, "Failed to parse the output."
+
+ digest_line = decrypted_output.strip().split('\n')[-1]
+ digest_string = digest_line.split(':')[3].lower()
+
+ # Verify that the two digest strings match.
+ assert package_digest == digest_string, "Verification failed."
+
+ # Verified successfully upon reaching here.
+ print('VERIFIED\n')
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('certificate', help='The certificate to be used.')
+ parser.add_argument('package', help='The OTA package to be verified.')
+ args = parser.parse_args()
+
+ verify_package(args.certificate, args.package)
+
+
+if __name__ == '__main__':
+ try:
+ main()
+ except AssertionError as err:
+ print('\n ERROR: %s\n' % (err,))
+ sys.exit(1)
diff --git a/tools/releasetools/check_target_files_signatures.py b/tools/releasetools/check_target_files_signatures.py
index 3048488..f9aa4fa 100755
--- a/tools/releasetools/check_target_files_signatures.py
+++ b/tools/releasetools/check_target_files_signatures.py
@@ -235,7 +235,7 @@
self.certmap = None
def LoadZipFile(self, filename):
- d, z = common.UnzipTemp(filename, '*.apk')
+ d, z = common.UnzipTemp(filename, ['*.apk'])
try:
self.apks = {}
self.apks_by_basename = {}
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index c4bf893..652fadf 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import print_function
+
import copy
import errno
import getopt
@@ -105,11 +107,16 @@
pass
-def Run(args, **kwargs):
- """Create and return a subprocess.Popen object, printing the command
- line on the terminal if -v was specified."""
- if OPTIONS.verbose:
- print " running: ", " ".join(args)
+def Run(args, verbose=None, **kwargs):
+ """Create and return a subprocess.Popen object.
+
+ Caller can specify if the command line should be printed. The global
+ OPTIONS.verbose will be used if not specified.
+ """
+ if verbose is None:
+ verbose = OPTIONS.verbose
+ if verbose:
+ print(" running: ", " ".join(args))
return subprocess.Popen(args, **kwargs)
@@ -144,41 +151,14 @@
except IOError as e:
if e.errno == errno.ENOENT:
raise KeyError(fn)
- d = {}
+
try:
d = LoadDictionaryFromLines(read_helper("META/misc_info.txt").split("\n"))
except KeyError:
- # ok if misc_info.txt doesn't exist
- pass
+ raise ValueError("can't find META/misc_info.txt in input target-files")
- # backwards compatibility: These values used to be in their own
- # files. Look for them, in case we're processing an old
- # target_files zip.
-
- if "mkyaffs2_extra_flags" not in d:
- try:
- d["mkyaffs2_extra_flags"] = read_helper(
- "META/mkyaffs2-extra-flags.txt").strip()
- except KeyError:
- # ok if flags don't exist
- pass
-
- if "recovery_api_version" not in d:
- try:
- d["recovery_api_version"] = read_helper(
- "META/recovery-api-version.txt").strip()
- except KeyError:
- raise ValueError("can't find recovery API version in input target-files")
-
- if "tool_extensions" not in d:
- try:
- d["tool_extensions"] = read_helper("META/tool-extensions.txt").strip()
- except KeyError:
- # ok if extensions don't exist
- pass
-
- if "fstab_version" not in d:
- d["fstab_version"] = "1"
+ assert "recovery_api_version" in d
+ assert "fstab_version" in d
# A few properties are stored as links to the files in the out/ directory.
# It works fine with the build system. However, they are no longer available
@@ -216,8 +196,8 @@
if os.path.exists(system_base_fs_file):
d["system_base_fs_file"] = system_base_fs_file
else:
- print "Warning: failed to find system base fs file: %s" % (
- system_base_fs_file,)
+ print("Warning: failed to find system base fs file: %s" % (
+ system_base_fs_file,))
del d["system_base_fs_file"]
if "vendor_base_fs_file" in d:
@@ -226,8 +206,8 @@
if os.path.exists(vendor_base_fs_file):
d["vendor_base_fs_file"] = vendor_base_fs_file
else:
- print "Warning: failed to find vendor base fs file: %s" % (
- vendor_base_fs_file,)
+ print("Warning: failed to find vendor base fs file: %s" % (
+ vendor_base_fs_file,))
del d["vendor_base_fs_file"]
try:
@@ -274,14 +254,16 @@
d["build.prop"] = LoadBuildProp(read_helper)
return d
+
def LoadBuildProp(read_helper):
try:
data = read_helper("SYSTEM/build.prop")
except KeyError:
- print "Warning: could not find SYSTEM/build.prop in %s" % zip
+ print("Warning: could not find SYSTEM/build.prop in %s" % (zip,))
data = ""
return LoadDictionaryFromLines(data.split("\n"))
+
def LoadDictionaryFromLines(lines):
d = {}
for line in lines:
@@ -293,98 +275,61 @@
d[name] = value
return d
+
def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path,
system_root_image=False):
class Partition(object):
- def __init__(self, mount_point, fs_type, device, length, device2, context):
+ def __init__(self, mount_point, fs_type, device, length, context):
self.mount_point = mount_point
self.fs_type = fs_type
self.device = device
self.length = length
- self.device2 = device2
self.context = context
try:
data = read_helper(recovery_fstab_path)
except KeyError:
- print "Warning: could not find {}".format(recovery_fstab_path)
+ print("Warning: could not find {}".format(recovery_fstab_path))
data = ""
- if fstab_version == 1:
- d = {}
- for line in data.split("\n"):
- line = line.strip()
- if not line or line.startswith("#"):
- continue
- pieces = line.split()
- if not 3 <= len(pieces) <= 4:
- raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
- options = None
- if len(pieces) >= 4:
- if pieces[3].startswith("/"):
- device2 = pieces[3]
- if len(pieces) >= 5:
- options = pieces[4]
- else:
- device2 = None
- options = pieces[3]
+ assert fstab_version == 2
+
+ d = {}
+ for line in data.split("\n"):
+ line = line.strip()
+ if not line or line.startswith("#"):
+ continue
+
+ # <src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
+ pieces = line.split()
+ if len(pieces) != 5:
+ raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
+
+ # Ignore entries that are managed by vold.
+ options = pieces[4]
+ if "voldmanaged=" in options:
+ continue
+
+ # It's a good line, parse it.
+ length = 0
+ options = options.split(",")
+ for i in options:
+ if i.startswith("length="):
+ length = int(i[7:])
else:
- device2 = None
-
- mount_point = pieces[0]
- length = 0
- if options:
- options = options.split(",")
- for i in options:
- if i.startswith("length="):
- length = int(i[7:])
- else:
- print "%s: unknown option \"%s\"" % (mount_point, i)
-
- d[mount_point] = Partition(mount_point=mount_point, fs_type=pieces[1],
- device=pieces[2], length=length,
- device2=device2)
-
- elif fstab_version == 2:
- d = {}
- for line in data.split("\n"):
- line = line.strip()
- if not line or line.startswith("#"):
- continue
- # <src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
- pieces = line.split()
- if len(pieces) != 5:
- raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
-
- # Ignore entries that are managed by vold
- options = pieces[4]
- if "voldmanaged=" in options:
+ # Ignore all unknown options in the unified fstab.
continue
- # It's a good line, parse it
- length = 0
- options = options.split(",")
- for i in options:
- if i.startswith("length="):
- length = int(i[7:])
- else:
- # Ignore all unknown options in the unified fstab
- continue
+ mount_flags = pieces[3]
+ # Honor the SELinux context if present.
+ context = None
+ for i in mount_flags.split(","):
+ if i.startswith("context="):
+ context = i
- mount_flags = pieces[3]
- # Honor the SELinux context if present.
- context = None
- for i in mount_flags.split(","):
- if i.startswith("context="):
- context = i
-
- mount_point = pieces[1]
- d[mount_point] = Partition(mount_point=mount_point, fs_type=pieces[2],
- device=pieces[0], length=length,
- device2=None, context=context)
-
- else:
- raise ValueError("Unknown fstab_version: \"%d\"" % (fstab_version,))
+ mount_point = pieces[1]
+ d[mount_point] = Partition(mount_point=mount_point, fs_type=pieces[2],
+ device=pieces[0], length=length, context=context)
# / is used for the system mount point when the root directory is included in
# system. Other areas assume system is always at "/system" so point /system
@@ -397,7 +342,7 @@
def DumpInfoDict(d):
for k, v in sorted(d.items()):
- print "%-25s = (%s) %s" % (k, type(v).__name__, v)
+ print("%-25s = (%s) %s" % (k, type(v).__name__, v))
def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None,
@@ -534,6 +479,21 @@
img_unsigned.close()
img_keyblock.close()
+ # AVB: if enabled, calculate and add hash to boot.img.
+ if info_dict.get("board_avb_enable", None) == "true":
+ avbtool = os.getenv('AVBTOOL') or info_dict["avb_avbtool"]
+ part_size = info_dict["boot_size"]
+ cmd = [avbtool, "add_hash_footer", "--image", img.name,
+ "--partition_size", str(part_size), "--partition_name", "boot"]
+ cmd.extend(shlex.split(info_dict["avb_signing_args"]))
+ args = info_dict.get("board_avb_boot_add_hash_footer_args")
+ if args and args.strip():
+ cmd.extend(shlex.split(args))
+ p = Run(cmd, stdout=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, "avbtool add_hash_footer of %s failed" % (
+ os.path.basename(OPTIONS.input_tmp))
+
img.seek(os.SEEK_SET, 0)
data = img.read()
@@ -554,15 +514,15 @@
prebuilt_path = os.path.join(unpack_dir, "BOOTABLE_IMAGES", prebuilt_name)
if os.path.exists(prebuilt_path):
- print "using prebuilt %s from BOOTABLE_IMAGES..." % (prebuilt_name,)
+ print("using prebuilt %s from BOOTABLE_IMAGES..." % (prebuilt_name,))
return File.FromLocalFile(name, prebuilt_path)
prebuilt_path = os.path.join(unpack_dir, "IMAGES", prebuilt_name)
if os.path.exists(prebuilt_path):
- print "using prebuilt %s from IMAGES..." % (prebuilt_name,)
+ print("using prebuilt %s from IMAGES..." % (prebuilt_name,))
return File.FromLocalFile(name, prebuilt_path)
- print "building image from target_files %s..." % (tree_subdir,)
+ print("building image from target_files %s..." % (tree_subdir,))
if info_dict is None:
info_dict = OPTIONS.info_dict
@@ -599,7 +559,7 @@
def unzip_to_dir(filename, dirname):
cmd = ["unzip", "-o", "-q", filename, "-d", dirname]
if pattern is not None:
- cmd.append(pattern)
+ cmd.extend(pattern)
p = Run(cmd, stdout=subprocess.PIPE)
p.communicate()
if p.returncode != 0:
@@ -775,21 +735,15 @@
if not fs_type or not limit:
return
- if fs_type == "yaffs2":
- # image size should be increased by 1/64th to account for the
- # spare area (64 bytes per 2k page)
- limit = limit / 2048 * (2048+64)
size = len(data)
pct = float(size) * 100.0 / limit
msg = "%s size (%d) is %.2f%% of limit (%d)" % (target, size, pct, limit)
if pct >= 99.0:
raise ExternalError(msg)
elif pct >= 95.0:
- print
- print " WARNING: ", msg
- print
+ print("\n WARNING: %s\n" % (msg,))
elif OPTIONS.verbose:
- print " ", msg
+ print(" ", msg)
def ReadApkCerts(tf_zip):
@@ -838,8 +792,8 @@
"""
def Usage(docstring):
- print docstring.rstrip("\n")
- print COMMON_DOCSTRING
+ print(docstring.rstrip("\n"))
+ print(COMMON_DOCSTRING)
def ParseOptions(argv,
@@ -864,7 +818,7 @@
list(extra_long_opts))
except getopt.GetoptError as err:
Usage(docstring)
- print "**", str(err), "**"
+ print("**", str(err), "**")
sys.exit(2)
for o, a in opts:
@@ -913,7 +867,7 @@
return args
-def MakeTempFile(prefix=None, suffix=None):
+def MakeTempFile(prefix='tmp', suffix=''):
"""Make a temp file and add it to the list of things to be deleted
when Cleanup() is called. Return the filename."""
fd, fn = tempfile.mkstemp(prefix=prefix, suffix=suffix)
@@ -962,7 +916,7 @@
current[i] = ""
if not first:
- print "key file %s still missing some passwords." % (self.pwfile,)
+ print("key file %s still missing some passwords." % (self.pwfile,))
answer = raw_input("try to edit again? [y]> ").strip()
if answer and answer[0] not in 'yY':
raise RuntimeError("key passwords unavailable")
@@ -1022,13 +976,13 @@
continue
m = re.match(r"^\[\[\[\s*(.*?)\s*\]\]\]\s*(\S+)$", line)
if not m:
- print "failed to parse password file: ", line
+ print("failed to parse password file: ", line)
else:
result[m.group(2)] = m.group(1)
f.close()
except IOError as e:
if e.errno != errno.ENOENT:
- print "error reading password file: ", str(e)
+ print("error reading password file: ", str(e))
return result
@@ -1149,10 +1103,10 @@
if x == ".py":
f = b
info = imp.find_module(f, [d])
- print "loaded device-specific extensions from", path
+ print("loaded device-specific extensions from", path)
self.module = imp.load_module("device_specific", *info)
except ImportError:
- print "unable to load device-specific module; assuming none"
+ print("unable to load device-specific module; assuming none")
def _DoCall(self, function_name, *args, **kwargs):
"""Call the named function in the device-specific module, passing
@@ -1212,10 +1166,11 @@
return self._DoCall("VerifyOTA_Assertions")
class File(object):
- def __init__(self, name, data):
+ def __init__(self, name, data, compress_size = None):
self.name = name
self.data = data
self.size = len(data)
+ self.compress_size = compress_size or self.size
self.sha1 = sha1(data).hexdigest()
@classmethod
@@ -1231,6 +1186,10 @@
t.flush()
return t
+ def WriteToDir(self, d):
+ with open(os.path.join(d, self.name), "wb") as fp:
+ fp.write(self.data)
+
def AddToZip(self, z, compression=None):
ZipWriteStr(z, self.name, self.data, compress_type=compression)
@@ -1286,7 +1245,7 @@
th.start()
th.join(timeout=300) # 5 mins
if th.is_alive():
- print "WARNING: diff command timed out"
+ print("WARNING: diff command timed out")
p.terminate()
th.join(5)
if th.is_alive():
@@ -1294,8 +1253,8 @@
th.join()
if err or p.returncode != 0:
- print "WARNING: failure running %s:\n%s\n" % (
- diff_program, "".join(err))
+ print("WARNING: failure running %s:\n%s\n" % (
+ diff_program, "".join(err)))
self.patch = None
return None, None, None
diff = ptemp.read()
@@ -1317,7 +1276,7 @@
def ComputeDifferences(diffs):
"""Call ComputePatch on all the Difference objects in 'diffs'."""
- print len(diffs), "diffs to compute"
+ print(len(diffs), "diffs to compute")
# Do the largest files first, to try and reduce the long-pole effect.
by_size = [(i.tf.size, i) for i in diffs]
@@ -1343,13 +1302,13 @@
else:
name = "%s (%s)" % (tf.name, sf.name)
if patch is None:
- print "patching failed! %s" % (name,)
+ print("patching failed! %s" % (name,))
else:
- print "%8.2f sec %8d / %8d bytes (%6.2f%%) %s" % (
- dur, len(patch), tf.size, 100.0 * len(patch) / tf.size, name)
+ print("%8.2f sec %8d / %8d bytes (%6.2f%%) %s" % (
+ dur, len(patch), tf.size, 100.0 * len(patch) / tf.size, name))
lock.release()
except Exception as e:
- print e
+ print(e)
raise
# start worker threads; wait for them all to finish.
@@ -1376,6 +1335,7 @@
version = max(
int(i) for i in
OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+ assert version >= 3
self.version = version
b = blockimgdiff.BlockImageDiff(tgt, src, threads=OPTIONS.worker_threads,
@@ -1440,7 +1400,7 @@
# incremental OTA
else:
- if touched_blocks_only and self.version >= 3:
+ if touched_blocks_only:
ranges = self.touched_src_ranges
expected_sha1 = self.touched_src_sha1
else:
@@ -1452,23 +1412,12 @@
return
ranges_str = ranges.to_string_raw()
- if self.version >= 4:
- script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
- 'block_image_verify("%s", '
- 'package_extract_file("%s.transfer.list"), '
- '"%s.new.dat", "%s.patch.dat")) then') % (
- self.device, ranges_str, expected_sha1,
- self.device, partition, partition, partition))
- elif self.version == 3:
- script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
- 'block_image_verify("%s", '
- 'package_extract_file("%s.transfer.list"), '
- '"%s.new.dat", "%s.patch.dat")) then') % (
- self.device, ranges_str, expected_sha1,
- self.device, partition, partition, partition))
- else:
- script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' % (
- self.device, ranges_str, self.src.TotalSha1()))
+ script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
+ 'block_image_verify("%s", '
+ 'package_extract_file("%s.transfer.list"), '
+ '"%s.new.dat", "%s.patch.dat")) then') % (
+ self.device, ranges_str, expected_sha1,
+ self.device, partition, partition, partition))
script.Print('Verified %s image...' % (partition,))
script.AppendExtra('else')
@@ -1600,8 +1549,6 @@
# map recovery.fstab's fs_types to mount/format "partition types"
PARTITION_TYPES = {
- "yaffs2": "MTD",
- "mtd": "MTD",
"ext4": "EMMC",
"emmc": "EMMC",
"f2fs": "EMMC",
@@ -1730,6 +1677,6 @@
if found:
break
- print "putting script in", sh_location
+ print("putting script in", sh_location)
output_sink(sh_location, sh)
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 73131a6..0c44faf 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -172,7 +172,7 @@
self.script.append("set_progress(%f);" % (frac,))
def PatchCheck(self, filename, *sha1):
- """Check that the given file (or MTD reference) has one of the
+ """Check that the given file has one of the
given *sha1 hashes, checking the version saved in cache if the
file does not match."""
self.script.append(
@@ -182,7 +182,7 @@
common.ErrorCode.BAD_PATCH_FILE, filename))
def Verify(self, filename):
- """Check that the given file (or MTD reference) has one of the
+ """Check that the given file has one of the
given hashes (encoded in the filename)."""
self.script.append(
'apply_patch_check("{filename}") && '
@@ -191,7 +191,7 @@
filename=filename))
def FileCheck(self, filename, *sha1):
- """Check that the given file (or MTD reference) has one of the
+ """Check that the given file has one of the
given *sha1 hashes."""
self.script.append('assert(sha1_check(read_file("%s")' % (filename,) +
"".join([', "%s"' % (i,) for i in sha1]) +
@@ -230,11 +230,6 @@
p.mount_point, mount_flags))
self.mounts.add(p.mount_point)
- def UnpackPackageDir(self, src, dst):
- """Unpack a given directory from the OTA package into the given
- destination directory."""
- self.script.append('package_extract_dir("%s", "%s");' % (src, dst))
-
def Comment(self, comment):
"""Write a comment into the update script."""
self.script.append("")
@@ -277,36 +272,6 @@
self.script.append('wipe_block_device("%s", %s);' % (device, size))
- def DeleteFiles(self, file_list):
- """Delete all files in file_list."""
- if not file_list:
- return
- cmd = "delete(" + ",\0".join(['"%s"' % (i,) for i in file_list]) + ");"
- self.script.append(self.WordWrap(cmd))
-
- def DeleteFilesIfNotMatching(self, file_list):
- """Delete the file in file_list if not matching the checksum."""
- if not file_list:
- return
- for name, sha1 in file_list:
- cmd = ('sha1_check(read_file("{name}"), "{sha1}") || '
- 'delete("{name}");'.format(name=name, sha1=sha1))
- self.script.append(self.WordWrap(cmd))
-
- def RenameFile(self, srcfile, tgtfile):
- """Moves a file from one location to another."""
- if self.info.get("update_rename_support", False):
- self.script.append('rename("%s", "%s");' % (srcfile, tgtfile))
- else:
- raise ValueError("Rename not supported by update binary")
-
- def SkipNextActionIfTargetExists(self, tgtfile, tgtsha1):
- """Prepend an action with an apply_patch_check in order to
- skip the action if the file exists. Used when a patch
- is later renamed."""
- cmd = ('sha1_check(read_file("%s"), %s) ||' % (tgtfile, tgtsha1))
- self.script.append(self.WordWrap(cmd))
-
def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs):
"""Apply binary patches (in *patchpairs) to the given srcfile to
produce tgtfile (which may be "-" to indicate overwriting the
@@ -331,11 +296,7 @@
p = fstab[mount_point]
partition_type = common.PARTITION_TYPES[p.fs_type]
args = {'device': p.device, 'fn': fn}
- if partition_type == "MTD":
- self.script.append(
- 'write_raw_image(package_extract_file("%(fn)s"), "%(device)s");'
- % args)
- elif partition_type == "EMMC":
+ if partition_type == "EMMC":
if mapfn:
args["map"] = mapfn
self.script.append(
@@ -347,48 +308,6 @@
raise ValueError(
"don't know how to write \"%s\" partitions" % p.fs_type)
- def SetPermissions(self, fn, uid, gid, mode, selabel, capabilities):
- """Set file ownership and permissions."""
- if not self.info.get("use_set_metadata", False):
- self.script.append('set_perm(%d, %d, 0%o, "%s");' % (uid, gid, mode, fn))
- else:
- if capabilities is None:
- capabilities = "0x0"
- cmd = 'set_metadata("%s", "uid", %d, "gid", %d, "mode", 0%o, ' \
- '"capabilities", %s' % (fn, uid, gid, mode, capabilities)
- if selabel is not None:
- cmd += ', "selabel", "%s"' % selabel
- cmd += ');'
- self.script.append(cmd)
-
- def SetPermissionsRecursive(self, fn, uid, gid, dmode, fmode, selabel,
- capabilities):
- """Recursively set path ownership and permissions."""
- if not self.info.get("use_set_metadata", False):
- self.script.append('set_perm_recursive(%d, %d, 0%o, 0%o, "%s");'
- % (uid, gid, dmode, fmode, fn))
- else:
- if capabilities is None:
- capabilities = "0x0"
- cmd = 'set_metadata_recursive("%s", "uid", %d, "gid", %d, ' \
- '"dmode", 0%o, "fmode", 0%o, "capabilities", %s' \
- % (fn, uid, gid, dmode, fmode, capabilities)
- if selabel is not None:
- cmd += ', "selabel", "%s"' % selabel
- cmd += ');'
- self.script.append(cmd)
-
- def MakeSymlinks(self, symlink_list):
- """Create symlinks, given a list of (dest, link) pairs."""
- by_dest = {}
- for d, l in symlink_list:
- by_dest.setdefault(d, []).append(l)
-
- for dest, links in sorted(by_dest.iteritems()):
- cmd = ('symlink("%s", ' % (dest,) +
- ",\0".join(['"' + i + '"' for i in sorted(links)]) + ");")
- self.script.append(self.WordWrap(cmd))
-
def AppendExtra(self, extra):
"""Append text verbatim to the output script."""
self.script.append(extra)
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index 84e0e63..4422b53 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -26,10 +26,12 @@
"""
+from __future__ import print_function
+
import sys
if sys.hexversion < 0x02070000:
- print >> sys.stderr, "Python 2.7 or newer is required."
+ print("Python 2.7 or newer is required.", file=sys.stderr)
sys.exit(1)
import os
@@ -69,70 +71,30 @@
common.Usage(__doc__)
sys.exit(1)
- OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
+ OPTIONS.input_tmp, input_zip = common.UnzipTemp(
+ args[0], ["IMAGES/*", "OTA/*"])
output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
CopyInfo(output_zip)
try:
- done = False
images_path = os.path.join(OPTIONS.input_tmp, "IMAGES")
- if os.path.exists(images_path):
- # If this is a new target-files, it already contains the images,
- # and all we have to do is copy them to the output zip.
- images = os.listdir(images_path)
- if images:
- for image in images:
- if bootable_only and image not in ("boot.img", "recovery.img"):
- continue
- if not image.endswith(".img"):
- continue
- if image == "recovery-two-step.img":
- continue
- common.ZipWrite(
- output_zip, os.path.join(images_path, image), image)
- done = True
-
- if not done:
- # We have an old target-files that doesn't already contain the
- # images, so build them.
- import add_img_to_target_files
-
- OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)
-
- boot_image = common.GetBootableImage(
- "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
- if boot_image:
- boot_image.AddToZip(output_zip)
-
- if OPTIONS.info_dict.get("no_recovery") != "true":
- recovery_image = common.GetBootableImage(
- "recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
- if recovery_image:
- recovery_image.AddToZip(output_zip)
-
- def banner(s):
- print "\n\n++++ " + s + " ++++\n\n"
-
- if not bootable_only:
- banner("AddSystem")
- add_img_to_target_files.AddSystem(output_zip, prefix="")
- try:
- input_zip.getinfo("VENDOR/")
- banner("AddVendor")
- add_img_to_target_files.AddVendor(output_zip, prefix="")
- except KeyError:
- pass # no vendor partition for this device
- banner("AddUserdata")
- add_img_to_target_files.AddUserdata(output_zip, prefix="")
- banner("AddCache")
- add_img_to_target_files.AddCache(output_zip, prefix="")
+ # A target-files zip must contain the images since Lollipop.
+ assert os.path.exists(images_path)
+ for image in sorted(os.listdir(images_path)):
+ if bootable_only and image not in ("boot.img", "recovery.img"):
+ continue
+ if not image.endswith(".img"):
+ continue
+ if image == "recovery-two-step.img":
+ continue
+ common.ZipWrite(output_zip, os.path.join(images_path, image), image)
finally:
- print "cleaning up..."
+ print("cleaning up...")
common.ZipClose(output_zip)
shutil.rmtree(OPTIONS.input_tmp)
- print "done."
+ print("done.")
if __name__ == '__main__':
@@ -140,7 +102,5 @@
common.CloseInheritedPipes()
main(sys.argv[1:])
except common.ExternalError as e:
- print
- print " ERROR: %s" % (e,)
- print
+ print("\n ERROR: %s\n" % (e,))
sys.exit(1)
diff --git a/tools/releasetools/make_recovery_patch.py b/tools/releasetools/make_recovery_patch.py
index 08d1450..7c6007e 100755
--- a/tools/releasetools/make_recovery_patch.py
+++ b/tools/releasetools/make_recovery_patch.py
@@ -14,10 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import print_function
+
import sys
if sys.hexversion < 0x02070000:
- print >> sys.stderr, "Python 2.7 or newer is required."
+ print("Python 2.7 or newer is required.", file=sys.stderr)
sys.exit(1)
import os
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 199e700..1c8fe65 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -55,7 +55,6 @@
properties on the OEM partition of the intended device.
Multiple expected values can be used by providing multiple files.
-
--oem_no_mount
For devices with OEM-specific properties but without an OEM partition,
do not mount the OEM partition in the updater-script. This should be
@@ -66,11 +65,6 @@
Generate an OTA package that will wipe the user data partition
when installed.
- -n (--no_prereq)
- Omit the timestamp prereq check normally included at the top of
- the build scripts (used for developer OTA packages which
- legitimately need to go back and forth).
-
--downgrade
Intentionally generate an incremental OTA that updates from a newer
build to an older one (based on timestamp comparison). "post-timestamp"
@@ -94,18 +88,16 @@
-e (--extra_script) <file>
Insert the contents of file at the end of the update script.
- -a (--aslr_mode) <on|off>
- Specify whether to turn on ASLR for the package (on by default).
-
-2 (--two_step)
Generate a 'two-step' OTA package, where recovery is updated
first, so that any changes made to the system partition are done
using the new recovery (new kernel, etc.).
--block
- Generate a block-based OTA if possible. Will fall back to a
- file-based OTA if the target_files is older and doesn't support
- block-based OTAs.
+ Generate a block-based OTA for non-A/B device. We have deprecated the
+ support for file-based OTA since O. Block-based OTA will be used by
+ default for all non-A/B devices. Keeping this flag here to not break
+ existing callers.
-b (--binary) <file>
Use the given binary as the update-binary in the output package,
@@ -140,14 +132,17 @@
Specify the arguments needed for payload signer.
"""
+from __future__ import print_function
+
import sys
if sys.hexversion < 0x02070000:
- print >> sys.stderr, "Python 2.7 or newer is required."
+ print("Python 2.7 or newer is required.", file=sys.stderr)
sys.exit(1)
+import copy
import multiprocessing
-import os
+import os.path
import subprocess
import shlex
import tempfile
@@ -161,21 +156,17 @@
OPTIONS.package_key = None
OPTIONS.incremental_source = None
OPTIONS.verify = False
-OPTIONS.require_verbatim = set()
-OPTIONS.prohibit_verbatim = set(("system/build.prop",))
OPTIONS.patch_threshold = 0.95
OPTIONS.wipe_user_data = False
-OPTIONS.omit_prereq = False
OPTIONS.downgrade = False
OPTIONS.timestamp = False
OPTIONS.extra_script = None
-OPTIONS.aslr_mode = True
OPTIONS.worker_threads = multiprocessing.cpu_count() // 2
if OPTIONS.worker_threads == 0:
OPTIONS.worker_threads = 1
OPTIONS.two_step = False
OPTIONS.no_signing = False
-OPTIONS.block_based = False
+OPTIONS.block_based = True
OPTIONS.updater_binary = None
OPTIONS.oem_source = None
OPTIONS.oem_no_mount = False
@@ -189,278 +180,15 @@
OPTIONS.log_diff = None
OPTIONS.payload_signer = None
OPTIONS.payload_signer_args = []
+OPTIONS.extracted_input = None
+OPTIONS.key_passwords = []
-def MostPopularKey(d, default):
- """Given a dict, return the key corresponding to the largest
- value. Returns 'default' if the dict is empty."""
- x = [(v, k) for (k, v) in d.iteritems()]
- if not x:
- return default
- x.sort()
- return x[-1][1]
-
-
-def IsSymlink(info):
- """Return true if the zipfile.ZipInfo object passed in represents a
- symlink."""
- return (info.external_attr >> 16) & 0o770000 == 0o120000
-
-def IsRegular(info):
- """Return true if the zipfile.ZipInfo object passed in represents a
- regular file."""
- return (info.external_attr >> 16) & 0o770000 == 0o100000
-
-def ClosestFileMatch(src, tgtfiles, existing):
- """Returns the closest file match between a source file and list
- of potential matches. The exact filename match is preferred,
- then the sha1 is searched for, and finally a file with the same
- basename is evaluated. Rename support in the updater-binary is
- required for the latter checks to be used."""
-
- result = tgtfiles.get("path:" + src.name)
- if result is not None:
- return result
-
- if not OPTIONS.target_info_dict.get("update_rename_support", False):
- return None
-
- if src.size < 1000:
- return None
-
- result = tgtfiles.get("sha1:" + src.sha1)
- if result is not None and existing.get(result.name) is None:
- return result
- result = tgtfiles.get("file:" + src.name.split("/")[-1])
- if result is not None and existing.get(result.name) is None:
- return result
- return None
-
-class ItemSet(object):
- def __init__(self, partition, fs_config):
- self.partition = partition
- self.fs_config = fs_config
- self.ITEMS = {}
-
- def Get(self, name, is_dir=False):
- if name not in self.ITEMS:
- self.ITEMS[name] = Item(self, name, is_dir=is_dir)
- return self.ITEMS[name]
-
- def GetMetadata(self, input_zip):
- # The target_files contains a record of what the uid,
- # gid, and mode are supposed to be.
- output = input_zip.read(self.fs_config)
-
- for line in output.split("\n"):
- if not line:
- continue
- columns = line.split()
- name, uid, gid, mode = columns[:4]
- selabel = None
- capabilities = None
-
- # After the first 4 columns, there are a series of key=value
- # pairs. Extract out the fields we care about.
- for element in columns[4:]:
- key, value = element.split("=")
- if key == "selabel":
- selabel = value
- if key == "capabilities":
- capabilities = value
-
- i = self.ITEMS.get(name, None)
- if i is not None:
- i.uid = int(uid)
- i.gid = int(gid)
- i.mode = int(mode, 8)
- i.selabel = selabel
- i.capabilities = capabilities
- if i.is_dir:
- i.children.sort(key=lambda i: i.name)
-
- # Set metadata for the files generated by this script. For full recovery
- # image at system/etc/recovery.img, it will be taken care by fs_config.
- i = self.ITEMS.get("system/recovery-from-boot.p", None)
- if i:
- i.uid, i.gid, i.mode, i.selabel, i.capabilities = 0, 0, 0o644, None, None
- i = self.ITEMS.get("system/etc/install-recovery.sh", None)
- if i:
- i.uid, i.gid, i.mode, i.selabel, i.capabilities = 0, 0, 0o544, None, None
-
-
-class Item(object):
- """Items represent the metadata (user, group, mode) of files and
- directories in the system image."""
- def __init__(self, itemset, name, is_dir=False):
- self.itemset = itemset
- self.name = name
- self.uid = None
- self.gid = None
- self.mode = None
- self.selabel = None
- self.capabilities = None
- self.is_dir = is_dir
- self.descendants = None
- self.best_subtree = None
-
- if name:
- self.parent = itemset.Get(os.path.dirname(name), is_dir=True)
- self.parent.children.append(self)
- else:
- self.parent = None
- if self.is_dir:
- self.children = []
-
- def Dump(self, indent=0):
- if self.uid is not None:
- print "%s%s %d %d %o" % (
- " " * indent, self.name, self.uid, self.gid, self.mode)
- else:
- print "%s%s %s %s %s" % (
- " " * indent, self.name, self.uid, self.gid, self.mode)
- if self.is_dir:
- print "%s%s" % (" "*indent, self.descendants)
- print "%s%s" % (" "*indent, self.best_subtree)
- for i in self.children:
- i.Dump(indent=indent+1)
-
- def CountChildMetadata(self):
- """Count up the (uid, gid, mode, selabel, capabilities) tuples for
- all children and determine the best strategy for using set_perm_recursive
- and set_perm to correctly chown/chmod all the files to their desired
- values. Recursively calls itself for all descendants.
-
- Returns a dict of {(uid, gid, dmode, fmode, selabel, capabilities): count}
- counting up all descendants of this node. (dmode or fmode may be None.)
- Also sets the best_subtree of each directory Item to the (uid, gid, dmode,
- fmode, selabel, capabilities) tuple that will match the most descendants of
- that Item.
- """
-
- assert self.is_dir
- key = (self.uid, self.gid, self.mode, None, self.selabel,
- self.capabilities)
- self.descendants = {key: 1}
- d = self.descendants
- for i in self.children:
- if i.is_dir:
- for k, v in i.CountChildMetadata().iteritems():
- d[k] = d.get(k, 0) + v
- else:
- k = (i.uid, i.gid, None, i.mode, i.selabel, i.capabilities)
- d[k] = d.get(k, 0) + 1
-
- # Find the (uid, gid, dmode, fmode, selabel, capabilities)
- # tuple that matches the most descendants.
-
- # First, find the (uid, gid) pair that matches the most
- # descendants.
- ug = {}
- for (uid, gid, _, _, _, _), count in d.iteritems():
- ug[(uid, gid)] = ug.get((uid, gid), 0) + count
- ug = MostPopularKey(ug, (0, 0))
-
- # Now find the dmode, fmode, selabel, and capabilities that match
- # the most descendants with that (uid, gid), and choose those.
- best_dmode = (0, 0o755)
- best_fmode = (0, 0o644)
- best_selabel = (0, None)
- best_capabilities = (0, None)
- for k, count in d.iteritems():
- if k[:2] != ug:
- continue
- if k[2] is not None and count >= best_dmode[0]:
- best_dmode = (count, k[2])
- if k[3] is not None and count >= best_fmode[0]:
- best_fmode = (count, k[3])
- if k[4] is not None and count >= best_selabel[0]:
- best_selabel = (count, k[4])
- if k[5] is not None and count >= best_capabilities[0]:
- best_capabilities = (count, k[5])
- self.best_subtree = ug + (
- best_dmode[1], best_fmode[1], best_selabel[1], best_capabilities[1])
-
- return d
-
- def SetPermissions(self, script):
- """Append set_perm/set_perm_recursive commands to 'script' to
- set all permissions, users, and groups for the tree of files
- rooted at 'self'."""
-
- self.CountChildMetadata()
-
- def recurse(item, current):
- # current is the (uid, gid, dmode, fmode, selabel, capabilities) tuple
- # that the current item (and all its children) have already been set to.
- # We only need to issue set_perm/set_perm_recursive commands if we're
- # supposed to be something different.
- if item.is_dir:
- if current != item.best_subtree:
- script.SetPermissionsRecursive("/"+item.name, *item.best_subtree)
- current = item.best_subtree
-
- if item.uid != current[0] or item.gid != current[1] or \
- item.mode != current[2] or item.selabel != current[4] or \
- item.capabilities != current[5]:
- script.SetPermissions("/"+item.name, item.uid, item.gid,
- item.mode, item.selabel, item.capabilities)
-
- for i in item.children:
- recurse(i, current)
- else:
- if item.uid != current[0] or item.gid != current[1] or \
- item.mode != current[3] or item.selabel != current[4] or \
- item.capabilities != current[5]:
- script.SetPermissions("/"+item.name, item.uid, item.gid,
- item.mode, item.selabel, item.capabilities)
-
- recurse(self, (-1, -1, -1, -1, None, None))
-
-
-def CopyPartitionFiles(itemset, input_zip, output_zip=None, substitute=None):
- """Copies files for the partition in the input zip to the output
- zip. Populates the Item class with their metadata, and returns a
- list of symlinks. output_zip may be None, in which case the copy is
- skipped (but the other side effects still happen). substitute is an
- optional dict of {output filename: contents} to be output instead of
- certain input files.
- """
-
- symlinks = []
-
- partition = itemset.partition
-
- for info in input_zip.infolist():
- prefix = partition.upper() + "/"
- if info.filename.startswith(prefix):
- basefilename = info.filename[len(prefix):]
- if IsSymlink(info):
- symlinks.append((input_zip.read(info.filename),
- "/" + partition + "/" + basefilename))
- else:
- import copy
- info2 = copy.copy(info)
- fn = info2.filename = partition + "/" + basefilename
- if substitute and fn in substitute and substitute[fn] is None:
- continue
- if output_zip is not None:
- if substitute and fn in substitute:
- data = substitute[fn]
- else:
- data = input_zip.read(info.filename)
- common.ZipWriteStr(output_zip, info2, data)
- if fn.endswith("/"):
- itemset.Get(fn[:-1], is_dir=True)
- else:
- itemset.Get(fn)
-
- symlinks.sort()
- return symlinks
+METADATA_NAME = 'META-INF/com/android/metadata'
+UNZIP_PATTERN = ['IMAGES/*', 'META/*']
def SignOutput(temp_zip_name, output_zip_name):
- key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
- pw = key_passwords[OPTIONS.package_key]
+ pw = OPTIONS.key_passwords[OPTIONS.package_key]
common.SignFile(temp_zip_name, output_zip_name, OPTIONS.package_key, pw,
whole_file=True)
@@ -491,7 +219,7 @@
oem_dicts = None
if OPTIONS.oem_source is None:
raise common.ExternalError("OEM source required for this build")
- if not OPTIONS.oem_no_mount:
+ if not OPTIONS.oem_no_mount and script:
script.Mount("/oem", recovery_mount_options)
oem_dicts = []
for oem_file in OPTIONS.oem_source:
@@ -524,11 +252,11 @@
OPTIONS.input_tmp, "RECOVERY")
common.ZipWriteStr(
output_zip, recovery_two_step_img_name, recovery_two_step_img.data)
- print "two-step package: using %s in stage 1/3" % (
- recovery_two_step_img_name,)
+ print("two-step package: using %s in stage 1/3" % (
+ recovery_two_step_img_name,))
script.WriteRawImage("/boot", recovery_two_step_img_name)
else:
- print "two-step package: using recovery.img in stage 1/3"
+ print("two-step package: using recovery.img in stage 1/3")
# The "recovery.img" entry has been written into package earlier.
script.WriteRawImage("/boot", "recovery.img")
@@ -538,6 +266,7 @@
return ("SYSTEM/recovery-from-boot.p" in namelist or
"SYSTEM/etc/recovery.img" in namelist)
+
def HasVendorPartition(target_files_zip):
try:
target_files_zip.getinfo("VENDOR/")
@@ -545,6 +274,7 @@
except KeyError:
return False
+
def GetOemProperty(name, oem_props, oem_dict, info_dict):
if oem_props is not None and name in oem_props:
return oem_dict[name]
@@ -561,36 +291,21 @@
GetBuildProp("ro.build.thumbprint", info_dict))
-def GetImage(which, tmpdir, info_dict):
- # Return an image object (suitable for passing to BlockImageDiff)
- # for the 'which' partition (most be "system" or "vendor"). If a
- # prebuilt image and file map are found in tmpdir they are used,
- # otherwise they are reconstructed from the individual files.
+def GetImage(which, tmpdir):
+ """Returns an image object suitable for passing to BlockImageDiff.
+
+ 'which' partition must be "system" or "vendor". A prebuilt image and file
+ map must already exist in tmpdir.
+ """
assert which in ("system", "vendor")
path = os.path.join(tmpdir, "IMAGES", which + ".img")
mappath = os.path.join(tmpdir, "IMAGES", which + ".map")
- if os.path.exists(path) and os.path.exists(mappath):
- print "using %s.img from target-files" % (which,)
- # This is a 'new' target-files, which already has the image in it.
- else:
- print "building %s.img from target-files" % (which,)
-
- # This is an 'old' target-files, which does not contain images
- # already built. Build them.
-
- mappath = tempfile.mkstemp()[1]
- OPTIONS.tempfiles.append(mappath)
-
- import add_img_to_target_files
- if which == "system":
- path = add_img_to_target_files.BuildSystem(
- tmpdir, info_dict, block_list=mappath)
- elif which == "vendor":
- path = add_img_to_target_files.BuildVendor(
- tmpdir, info_dict, block_list=mappath)
+ # The image and map files must have been created prior to calling
+ # ota_from_target_files.py (since LMP).
+ assert os.path.exists(path) and os.path.exists(mappath)
# Bug: http://b/20939131
# In ext4 filesystems, block 0 might be changed even being mounted
@@ -601,6 +316,59 @@
return sparse_img.SparseImage(path, mappath, clobbered_blocks)
+def AddCompatibilityArchive(target_zip, output_zip, system_included=True,
+ vendor_included=True):
+ """Adds compatibility info from target files into the output zip.
+
+ Metadata used for on-device compatibility verification is retrieved from
+ target_zip then added to compatibility.zip which is added to the output_zip
+ archive.
+
+ Compatibility archive should only be included for devices with a vendor
+ partition as checking provides value when system and vendor are independently
+ versioned.
+
+ Args:
+ target_zip: Zip file containing the source files to be included for OTA.
+ output_zip: Zip file that will be sent for OTA.
+ system_included: If True, the system image will be updated and therefore
+ its metadata should be included.
+ vendor_included: If True, the vendor image will be updated and therefore
+ its metadata should be included.
+ """
+
+ # Determine what metadata we need. Files are names relative to META/.
+ compatibility_files = []
+ vendor_metadata = ("vendor_manifest.xml", "vendor_matrix.xml")
+ system_metadata = ("system_manifest.xml", "system_matrix.xml")
+ if vendor_included:
+ compatibility_files += vendor_metadata
+ if system_included:
+ compatibility_files += system_metadata
+
+ # Create new archive.
+ compatibility_archive = tempfile.NamedTemporaryFile()
+ compatibility_archive_zip = zipfile.ZipFile(compatibility_archive, "w",
+ compression=zipfile.ZIP_DEFLATED)
+
+ # Add metadata.
+ for file_name in compatibility_files:
+ target_file_name = "META/" + file_name
+
+ if target_file_name in target_zip.namelist():
+ data = target_zip.read(target_file_name)
+ common.ZipWriteStr(compatibility_archive_zip, file_name, data)
+
+ # Ensure files are written before we copy into output_zip.
+ compatibility_archive_zip.close()
+
+ # Only add the archive if we have any compatibility info.
+ if compatibility_archive_zip.namelist():
+ common.ZipWrite(output_zip, compatibility_archive.name,
+ arcname="compatibility.zip",
+ compress_type=zipfile.ZIP_STORED)
+
+
def WriteFullOTAPackage(input_zip, output_zip):
# TODO: how to determine this? We don't know what version it will
# be installed on top of. For now, we expect the API just won't
@@ -608,15 +376,16 @@
# in the target build.
script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)
- oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
+ oem_props = OPTIONS.info_dict.get("oem_fingerprint_properties")
oem_dicts = None
if oem_props:
oem_dicts = _LoadOemDicts(script, recovery_mount_options)
+ target_fp = CalculateFingerprint(oem_props, oem_dicts and oem_dicts[0],
+ OPTIONS.info_dict)
metadata = {
- "post-build": CalculateFingerprint(oem_props, oem_dicts and oem_dicts[0],
- OPTIONS.info_dict),
+ "post-build": target_fp,
"pre-device": GetOemProperty("ro.product.device", oem_props,
oem_dicts and oem_dicts[0],
OPTIONS.info_dict),
@@ -632,15 +401,13 @@
metadata=metadata,
info_dict=OPTIONS.info_dict)
- has_recovery_patch = HasRecoveryPatch(input_zip)
- block_based = OPTIONS.block_based and has_recovery_patch
+ assert HasRecoveryPatch(input_zip)
- metadata["ota-type"] = "BLOCK" if block_based else "FILE"
+ metadata["ota-type"] = "BLOCK"
- if not OPTIONS.omit_prereq:
- ts = GetBuildProp("ro.build.date.utc", OPTIONS.info_dict)
- ts_text = GetBuildProp("ro.build.date", OPTIONS.info_dict)
- script.AssertOlderBuild(ts, ts_text)
+ ts = GetBuildProp("ro.build.date.utc", OPTIONS.info_dict)
+ ts_text = GetBuildProp("ro.build.date", OPTIONS.info_dict)
+ script.AssertOlderBuild(ts, ts_text)
AppendAssertions(script, OPTIONS.info_dict, oem_dicts)
device_specific.FullOTA_Assertions()
@@ -692,8 +459,7 @@
script.Comment("Stage 3/3")
# Dump fingerprints
- script.Print("Target: %s" % CalculateFingerprint(
- oem_props, oem_dicts and oem_dicts[0], OPTIONS.info_dict))
+ script.Print("Target: %s" % target_fp)
device_specific.FullOTA_InstallBegin()
@@ -711,61 +477,27 @@
recovery_mount_options = OPTIONS.info_dict.get("recovery_mount_options")
- system_items = ItemSet("system", "META/filesystem_config.txt")
script.ShowProgress(system_progress, 0)
- if block_based:
- # Full OTA is done as an "incremental" against an empty source
- # image. This has the effect of writing new data from the package
- # to the entire partition, but lets us reuse the updater code that
- # writes incrementals to do it.
- system_tgt = GetImage("system", OPTIONS.input_tmp, OPTIONS.info_dict)
- system_tgt.ResetFileMap()
- system_diff = common.BlockDifference("system", system_tgt, src=None)
- system_diff.WriteScript(script, output_zip)
- else:
- script.FormatPartition("/system")
- script.Mount("/system", recovery_mount_options)
- if not has_recovery_patch:
- script.UnpackPackageDir("recovery", "/system")
- script.UnpackPackageDir("system", "/system")
-
- symlinks = CopyPartitionFiles(system_items, input_zip, output_zip)
- script.MakeSymlinks(symlinks)
+ # Full OTA is done as an "incremental" against an empty source image. This
+ # has the effect of writing new data from the package to the entire
+ # partition, but lets us reuse the updater code that writes incrementals to
+ # do it.
+ system_tgt = GetImage("system", OPTIONS.input_tmp)
+ system_tgt.ResetFileMap()
+ system_diff = common.BlockDifference("system", system_tgt, src=None)
+ system_diff.WriteScript(script, output_zip)
boot_img = common.GetBootableImage(
"boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
- if not block_based:
- def output_sink(fn, data):
- common.ZipWriteStr(output_zip, "recovery/" + fn, data)
- system_items.Get("system/" + fn)
-
- common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink,
- recovery_img, boot_img)
-
- system_items.GetMetadata(input_zip)
- system_items.Get("system").SetPermissions(script)
-
if HasVendorPartition(input_zip):
- vendor_items = ItemSet("vendor", "META/vendor_filesystem_config.txt")
script.ShowProgress(0.1, 0)
- if block_based:
- vendor_tgt = GetImage("vendor", OPTIONS.input_tmp, OPTIONS.info_dict)
- vendor_tgt.ResetFileMap()
- vendor_diff = common.BlockDifference("vendor", vendor_tgt)
- vendor_diff.WriteScript(script, output_zip)
- else:
- script.FormatPartition("/vendor")
- script.Mount("/vendor", recovery_mount_options)
- script.UnpackPackageDir("vendor", "/vendor")
-
- symlinks = CopyPartitionFiles(vendor_items, input_zip, output_zip)
- script.MakeSymlinks(symlinks)
-
- vendor_items.GetMetadata(input_zip)
- vendor_items.Get("vendor").SetPermissions(script)
+ vendor_tgt = GetImage("vendor", OPTIONS.input_tmp)
+ vendor_tgt.ResetFileMap()
+ vendor_diff = common.BlockDifference("vendor", vendor_tgt)
+ vendor_diff.WriteScript(script, output_zip)
common.CheckSize(boot_img.data, "boot.img", OPTIONS.info_dict)
common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
@@ -813,23 +545,9 @@
def WriteMetadata(metadata, output_zip):
- common.ZipWriteStr(output_zip, "META-INF/com/android/metadata",
- "".join(["%s=%s\n" % kv
- for kv in sorted(metadata.iteritems())]))
-
-
-def LoadPartitionFiles(z, partition):
- """Load all the files from the given partition in a given target-files
- ZipFile, and return a dict of {filename: File object}."""
- out = {}
- prefix = partition.upper() + "/"
- for info in z.infolist():
- if info.filename.startswith(prefix) and not IsSymlink(info):
- basefilename = info.filename[len(prefix):]
- fn = partition + "/" + basefilename
- data = z.read(info.filename)
- out[fn] = common.File(fn, data)
- return out
+ value = "".join(["%s=%s\n" % kv for kv in sorted(metadata.iteritems())])
+ common.ZipWriteStr(output_zip, METADATA_NAME, value,
+ compress_type=zipfile.ZIP_STORED)
def GetBuildProp(prop, info_dict):
@@ -840,18 +558,6 @@
raise common.ExternalError("couldn't find %s in build.prop" % (prop,))
-def AddToKnownPaths(filename, known_paths):
- if filename[-1] == "/":
- return
- dirs = filename.split("/")[:-1]
- while len(dirs) > 0:
- path = "/".join(dirs)
- if path in known_paths:
- break
- known_paths.add(path)
- dirs.pop()
-
-
def HandleDowngradeMetadata(metadata):
# Only incremental OTAs are allowed to reach here.
assert OPTIONS.incremental_source is not None
@@ -880,14 +586,12 @@
def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
- # TODO(tbao): We should factor out the common parts between
- # WriteBlockIncrementalOTAPackage() and WriteIncrementalOTAPackage().
source_version = OPTIONS.source_info_dict["recovery_api_version"]
target_version = OPTIONS.target_info_dict["recovery_api_version"]
if source_version == 0:
- print ("WARNING: generating edify script for a source that "
- "can't install it.")
+ print("WARNING: generating edify script for a source that "
+ "can't install it.")
script = edify_generator.EdifyGenerator(
source_version, OPTIONS.target_info_dict,
fstab=OPTIONS.source_info_dict["fstab"])
@@ -897,7 +601,7 @@
source_oem_props = OPTIONS.source_info_dict.get("oem_fingerprint_properties")
target_oem_props = OPTIONS.target_info_dict.get("oem_fingerprint_properties")
oem_dicts = None
- if source_oem_props or target_oem_props:
+ if source_oem_props and target_oem_props:
oem_dicts = _LoadOemDicts(script, recovery_mount_options)
metadata = {
@@ -941,8 +645,8 @@
target_recovery = common.GetBootableImage(
"/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")
- system_src = GetImage("system", OPTIONS.source_tmp, OPTIONS.source_info_dict)
- system_tgt = GetImage("system", OPTIONS.target_tmp, OPTIONS.target_info_dict)
+ system_src = GetImage("system", OPTIONS.source_tmp)
+ system_tgt = GetImage("system", OPTIONS.target_tmp)
blockimgdiff_version = 1
if OPTIONS.info_dict:
@@ -969,10 +673,8 @@
if HasVendorPartition(target_zip):
if not HasVendorPartition(source_zip):
raise RuntimeError("can't generate incremental that adds /vendor")
- vendor_src = GetImage("vendor", OPTIONS.source_tmp,
- OPTIONS.source_info_dict)
- vendor_tgt = GetImage("vendor", OPTIONS.target_tmp,
- OPTIONS.target_info_dict)
+ vendor_src = GetImage("vendor", OPTIONS.source_tmp)
+ vendor_tgt = GetImage("vendor", OPTIONS.target_tmp)
# Check first block of vendor partition for remount R/W only if
# disk type is ext4
@@ -1089,8 +791,8 @@
else:
include_full_boot = False
- print "boot target: %d source: %d diff: %d" % (
- target_boot.size, source_boot.size, len(d))
+ print("boot target: %d source: %d diff: %d" % (
+ target_boot.size, source_boot.size, len(d)))
common.ZipWriteStr(output_zip, "patch/boot.img.p", d)
@@ -1136,19 +838,19 @@
if OPTIONS.two_step:
common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
script.WriteRawImage("/boot", "boot.img")
- print "writing full boot image (forced by two-step mode)"
+ print("writing full boot image (forced by two-step mode)")
if not OPTIONS.two_step:
if updating_boot:
if include_full_boot:
- print "boot image changed; including full."
+ print("boot image changed; including full.")
script.Print("Installing boot image...")
script.WriteRawImage("/boot", "boot.img")
else:
# Produce the boot image by applying a patch to the current
# contents of the boot partition, and write it back to the
# partition.
- print "boot image changed; including patch."
+ print("boot image changed; including patch.")
script.Print("Patching boot image...")
script.ShowProgress(0.1, 10)
script.ApplyPatch("%s:%s:%d:%s:%d:%s"
@@ -1159,7 +861,7 @@
target_boot.size, target_boot.sha1,
source_boot.sha1, "patch/boot.img.p")
else:
- print "boot image unchanged; skipping."
+ print("boot image unchanged; skipping.")
# Do device-specific installation (eg, write radio image).
device_specific.IncrementalOTA_InstallEnd()
@@ -1242,13 +944,13 @@
recovery_type, recovery_device, recovery_img.size, recovery_img.sha1))
script.AppendExtra("")
- system_tgt = GetImage("system", OPTIONS.input_tmp, OPTIONS.info_dict)
+ system_tgt = GetImage("system", OPTIONS.input_tmp)
system_tgt.ResetFileMap()
system_diff = common.BlockDifference("system", system_tgt, src=None)
system_diff.WriteStrictVerifyScript(script)
if HasVendorPartition(input_zip):
- vendor_tgt = GetImage("vendor", OPTIONS.input_tmp, OPTIONS.info_dict)
+ vendor_tgt = GetImage("vendor", OPTIONS.input_tmp)
vendor_tgt.ResetFileMap()
vendor_diff = common.BlockDifference("vendor", vendor_tgt, src=None)
vendor_diff.WriteStrictVerifyScript(script)
@@ -1266,22 +968,71 @@
source_file=None):
"""Generate an Android OTA package that has A/B update payload."""
- # Setup signing keys.
- if OPTIONS.package_key is None:
- OPTIONS.package_key = OPTIONS.info_dict.get(
- "default_system_dev_certificate",
- "build/target/product/security/testkey")
+ def ComputeStreamingMetadata(zip_file, reserve_space=False,
+ expected_length=None):
+ """Compute the streaming metadata for a given zip.
+
+ When 'reserve_space' is True, we reserve extra space for the offset and
+ length of the metadata entry itself, although we don't know the final
+ values until the package gets signed. This function will be called again
+ after signing. We then write the actual values and pad the string to the
+ length we set earlier. Note that we can't use the actual length of the
+ metadata entry in the second run. Otherwise the offsets for other entries
+ will be changing again.
+ """
+
+ def ComputeEntryOffsetSize(name):
+ """Compute the zip entry offset and size."""
+ info = zip_file.getinfo(name)
+ offset = info.header_offset + len(info.FileHeader())
+ size = info.file_size
+ return '%s:%d:%d' % (os.path.basename(name), offset, size)
+
+ # payload.bin and payload_properties.txt must exist.
+ offsets = [ComputeEntryOffsetSize('payload.bin'),
+ ComputeEntryOffsetSize('payload_properties.txt')]
+
+ # care_map.txt is available only if dm-verity is enabled.
+ if 'care_map.txt' in zip_file.namelist():
+ offsets.append(ComputeEntryOffsetSize('care_map.txt'))
+
+ if 'compatibility.zip' in zip_file.namelist():
+ offsets.append(ComputeEntryOffsetSize('compatibility.zip'))
+
+ # 'META-INF/com/android/metadata' is required. We don't know its actual
+ # offset and length (as well as the values for other entries). So we
+ # reserve 10-byte as a placeholder, which is to cover the space for metadata
+ # entry ('xx:xxx', since it's ZIP_STORED which should appear at the
+ # beginning of the zip), as well as the possible value changes in other
+ # entries.
+ if reserve_space:
+ offsets.append('metadata:' + ' ' * 10)
+ else:
+ offsets.append(ComputeEntryOffsetSize(METADATA_NAME))
+
+ value = ','.join(offsets)
+ if expected_length is not None:
+ assert len(value) <= expected_length, \
+ 'Insufficient reserved space: reserved=%d, actual=%d' % (
+ expected_length, len(value))
+ value += ' ' * (expected_length - len(value))
+ return value
+
+ # The place where the output from the subprocess should go.
+ log_file = sys.stdout if OPTIONS.verbose else subprocess.PIPE
# A/B updater expects a signing key in RSA format. Gets the key ready for
# later use in step 3, unless a payload_signer has been specified.
if OPTIONS.payload_signer is None:
cmd = ["openssl", "pkcs8",
"-in", OPTIONS.package_key + OPTIONS.private_key_suffix,
- "-inform", "DER", "-nocrypt"]
+ "-inform", "DER"]
+ pw = OPTIONS.key_passwords[OPTIONS.package_key]
+ cmd.extend(["-passin", "pass:" + pw] if pw else ["-nocrypt"])
rsa_key = common.MakeTempFile(prefix="key-", suffix=".key")
cmd.extend(["-out", rsa_key])
- p1 = common.Run(cmd, stdout=subprocess.PIPE)
- p1.wait()
+ p1 = common.Run(cmd, verbose=False, stdout=log_file, stderr=subprocess.STDOUT)
+ p1.communicate()
assert p1.returncode == 0, "openssl pkcs8 failed"
# Stage the output zip package for package signing.
@@ -1326,8 +1077,8 @@
"--target_image", target_file]
if source_file is not None:
cmd.extend(["--source_image", source_file])
- p1 = common.Run(cmd, stdout=subprocess.PIPE)
- p1.wait()
+ p1 = common.Run(cmd, stdout=log_file, stderr=subprocess.STDOUT)
+ p1.communicate()
assert p1.returncode == 0, "brillo_update_payload generate failed"
# 2. Generate hashes of the payload and metadata files.
@@ -1338,8 +1089,8 @@
"--signature_size", "256",
"--metadata_hash_file", metadata_sig_file,
"--payload_hash_file", payload_sig_file]
- p1 = common.Run(cmd, stdout=subprocess.PIPE)
- p1.wait()
+ p1 = common.Run(cmd, stdout=log_file, stderr=subprocess.STDOUT)
+ p1.communicate()
assert p1.returncode == 0, "brillo_update_payload hash failed"
# 3. Sign the hashes and insert them back into the payload file.
@@ -1357,9 +1108,8 @@
"-pkeyopt", "digest:sha256"]
cmd.extend(["-in", payload_sig_file,
"-out", signed_payload_sig_file])
-
- p1 = common.Run(cmd, stdout=subprocess.PIPE)
- p1.wait()
+ p1 = common.Run(cmd, stdout=log_file, stderr=subprocess.STDOUT)
+ p1.communicate()
assert p1.returncode == 0, "openssl sign payload failed"
# 3b. Sign the metadata hash.
@@ -1372,8 +1122,8 @@
"-pkeyopt", "digest:sha256"]
cmd.extend(["-in", metadata_sig_file,
"-out", signed_metadata_sig_file])
- p1 = common.Run(cmd, stdout=subprocess.PIPE)
- p1.wait()
+ p1 = common.Run(cmd, stdout=log_file, stderr=subprocess.STDOUT)
+ p1.communicate()
assert p1.returncode == 0, "openssl sign metadata failed"
# 3c. Insert the signatures back into the payload file.
@@ -1385,8 +1135,8 @@
"--signature_size", "256",
"--metadata_signature_file", signed_metadata_sig_file,
"--payload_signature_file", signed_payload_sig_file]
- p1 = common.Run(cmd, stdout=subprocess.PIPE)
- p1.wait()
+ p1 = common.Run(cmd, stdout=log_file, stderr=subprocess.STDOUT)
+ p1.communicate()
assert p1.returncode == 0, "brillo_update_payload sign failed"
# 4. Dump the signed payload properties.
@@ -1395,8 +1145,8 @@
cmd = ["brillo_update_payload", "properties",
"--payload", signed_payload_file,
"--properties_file", properties_file]
- p1 = common.Run(cmd, stdout=subprocess.PIPE)
- p1.wait()
+ p1 = common.Run(cmd, stdout=log_file, stderr=subprocess.STDOUT)
+ p1.communicate()
assert p1.returncode == 0, "brillo_update_payload properties failed"
if OPTIONS.wipe_user_data:
@@ -1404,579 +1154,108 @@
f.write("POWERWASH=1\n")
metadata["ota-wipe"] = "yes"
- # Add the signed payload file and properties into the zip.
- common.ZipWrite(output_zip, properties_file, arcname="payload_properties.txt")
+ # Add the signed payload file and properties into the zip. In order to
+ # support streaming, we pack payload.bin, payload_properties.txt and
+ # care_map.txt as ZIP_STORED. So these entries can be read directly with
+ # the offset and length pairs.
common.ZipWrite(output_zip, signed_payload_file, arcname="payload.bin",
compress_type=zipfile.ZIP_STORED)
- WriteMetadata(metadata, output_zip)
+ common.ZipWrite(output_zip, properties_file,
+ arcname="payload_properties.txt",
+ compress_type=zipfile.ZIP_STORED)
# If dm-verity is supported for the device, copy contents of care_map
# into A/B OTA package.
- if OPTIONS.info_dict.get("verity") == "true":
- target_zip = zipfile.ZipFile(target_file, "r")
+ target_zip = zipfile.ZipFile(target_file, "r")
+ if (OPTIONS.info_dict.get("verity") == "true" or
+ OPTIONS.info_dict.get("board_avb_enable") == "true"):
care_map_path = "META/care_map.txt"
namelist = target_zip.namelist()
if care_map_path in namelist:
care_map_data = target_zip.read(care_map_path)
- common.ZipWriteStr(output_zip, "care_map.txt", care_map_data)
+ common.ZipWriteStr(output_zip, "care_map.txt", care_map_data,
+ compress_type=zipfile.ZIP_STORED)
else:
- print "Warning: cannot find care map file in target_file package"
- common.ZipClose(target_zip)
+ print("Warning: cannot find care map file in target_file package")
- # Sign the whole package to comply with the Android OTA package format.
- common.ZipClose(output_zip)
- SignOutput(temp_zip_file.name, output_file)
- temp_zip_file.close()
-
-
-class FileDifference(object):
- def __init__(self, partition, source_zip, target_zip, output_zip):
- self.deferred_patch_list = None
- print "Loading target..."
- self.target_data = target_data = LoadPartitionFiles(target_zip, partition)
- print "Loading source..."
- self.source_data = source_data = LoadPartitionFiles(source_zip, partition)
-
- self.verbatim_targets = verbatim_targets = []
- self.patch_list = patch_list = []
- diffs = []
- self.renames = renames = {}
- known_paths = set()
- largest_source_size = 0
-
- matching_file_cache = {}
- for fn, sf in source_data.items():
- assert fn == sf.name
- matching_file_cache["path:" + fn] = sf
- if fn in target_data.keys():
- AddToKnownPaths(fn, known_paths)
- # Only allow eligibility for filename/sha matching
- # if there isn't a perfect path match.
- if target_data.get(sf.name) is None:
- matching_file_cache["file:" + fn.split("/")[-1]] = sf
- matching_file_cache["sha:" + sf.sha1] = sf
-
- for fn in sorted(target_data.keys()):
- tf = target_data[fn]
- assert fn == tf.name
- sf = ClosestFileMatch(tf, matching_file_cache, renames)
- if sf is not None and sf.name != tf.name:
- print "File has moved from " + sf.name + " to " + tf.name
- renames[sf.name] = tf
-
- if sf is None or fn in OPTIONS.require_verbatim:
- # This file should be included verbatim
- if fn in OPTIONS.prohibit_verbatim:
- raise common.ExternalError("\"%s\" must be sent verbatim" % (fn,))
- print "send", fn, "verbatim"
- tf.AddToZip(output_zip)
- verbatim_targets.append((fn, tf.size, tf.sha1))
- if fn in target_data.keys():
- AddToKnownPaths(fn, known_paths)
- elif tf.sha1 != sf.sha1:
- # File is different; consider sending as a patch
- diffs.append(common.Difference(tf, sf))
- else:
- # Target file data identical to source (may still be renamed)
- pass
-
- common.ComputeDifferences(diffs)
-
- for diff in diffs:
- tf, sf, d = diff.GetPatch()
- path = "/".join(tf.name.split("/")[:-1])
- if d is None or len(d) > tf.size * OPTIONS.patch_threshold or \
- path not in known_paths:
- # patch is almost as big as the file; don't bother patching
- # or a patch + rename cannot take place due to the target
- # directory not existing
- tf.AddToZip(output_zip)
- verbatim_targets.append((tf.name, tf.size, tf.sha1))
- if sf.name in renames:
- del renames[sf.name]
- AddToKnownPaths(tf.name, known_paths)
- else:
- common.ZipWriteStr(output_zip, "patch/" + sf.name + ".p", d)
- patch_list.append((tf, sf, tf.size, common.sha1(d).hexdigest()))
- largest_source_size = max(largest_source_size, sf.size)
-
- self.largest_source_size = largest_source_size
-
- def EmitVerification(self, script):
- so_far = 0
- for tf, sf, _, _ in self.patch_list:
- if tf.name != sf.name:
- script.SkipNextActionIfTargetExists(tf.name, tf.sha1)
- script.PatchCheck("/"+sf.name, tf.sha1, sf.sha1)
- so_far += sf.size
- return so_far
-
- def EmitExplicitTargetVerification(self, script):
- for fn, _, sha1 in self.verbatim_targets:
- if fn[-1] != "/":
- script.FileCheck("/"+fn, sha1)
- for tf, _, _, _ in self.patch_list:
- script.FileCheck(tf.name, tf.sha1)
-
- def RemoveUnneededFiles(self, script, extras=()):
- file_list = ["/" + i[0] for i in self.verbatim_targets]
- file_list += ["/" + i for i in self.source_data
- if i not in self.target_data and i not in self.renames]
- file_list += list(extras)
- # Sort the list in descending order, which removes all the files first
- # before attempting to remove the folder. (Bug: 22960996)
- script.DeleteFiles(sorted(file_list, reverse=True))
-
- def TotalPatchSize(self):
- return sum(i[1].size for i in self.patch_list)
-
- def EmitPatches(self, script, total_patch_size, so_far):
- self.deferred_patch_list = deferred_patch_list = []
- for item in self.patch_list:
- tf, sf, _, _ = item
- if tf.name == "system/build.prop":
- deferred_patch_list.append(item)
- continue
- if sf.name != tf.name:
- script.SkipNextActionIfTargetExists(tf.name, tf.sha1)
- script.ApplyPatch("/" + sf.name, "-", tf.size, tf.sha1, sf.sha1,
- "patch/" + sf.name + ".p")
- so_far += tf.size
- script.SetProgress(so_far / total_patch_size)
- return so_far
-
- def EmitDeferredPatches(self, script):
- for item in self.deferred_patch_list:
- tf, sf, _, _ = item
- script.ApplyPatch("/"+sf.name, "-", tf.size, tf.sha1, sf.sha1,
- "patch/" + sf.name + ".p")
- script.SetPermissions("/system/build.prop", 0, 0, 0o644, None, None)
-
- def EmitRenames(self, script):
- if len(self.renames) > 0:
- script.Print("Renaming files...")
- for src, tgt in self.renames.iteritems():
- print "Renaming " + src + " to " + tgt.name
- script.RenameFile(src, tgt.name)
-
-
-def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
- target_has_recovery_patch = HasRecoveryPatch(target_zip)
- source_has_recovery_patch = HasRecoveryPatch(source_zip)
-
- if (OPTIONS.block_based and
- target_has_recovery_patch and
- source_has_recovery_patch):
- return WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip)
-
- source_version = OPTIONS.source_info_dict["recovery_api_version"]
- target_version = OPTIONS.target_info_dict["recovery_api_version"]
-
- if source_version == 0:
- print ("WARNING: generating edify script for a source that "
- "can't install it.")
- script = edify_generator.EdifyGenerator(
- source_version, OPTIONS.target_info_dict,
- fstab=OPTIONS.source_info_dict["fstab"])
-
- recovery_mount_options = OPTIONS.source_info_dict.get(
- "recovery_mount_options")
- source_oem_props = OPTIONS.source_info_dict.get("oem_fingerprint_properties")
- target_oem_props = OPTIONS.target_info_dict.get("oem_fingerprint_properties")
- oem_dicts = None
- if source_oem_props or target_oem_props:
- oem_dicts = _LoadOemDicts(script, recovery_mount_options)
-
- metadata = {
- "pre-device": GetOemProperty("ro.product.device", source_oem_props,
- oem_dicts and oem_dicts[0],
- OPTIONS.source_info_dict),
- "ota-type": "FILE",
- }
-
- HandleDowngradeMetadata(metadata)
-
- device_specific = common.DeviceSpecificParams(
- source_zip=source_zip,
- source_version=source_version,
- target_zip=target_zip,
- target_version=target_version,
- output_zip=output_zip,
- script=script,
- metadata=metadata,
- info_dict=OPTIONS.source_info_dict)
-
- system_diff = FileDifference("system", source_zip, target_zip, output_zip)
- script.Mount("/system", recovery_mount_options)
if HasVendorPartition(target_zip):
- vendor_diff = FileDifference("vendor", source_zip, target_zip, output_zip)
- script.Mount("/vendor", recovery_mount_options)
- else:
- vendor_diff = None
+ update_vendor = True
+ update_system = True
- target_fp = CalculateFingerprint(target_oem_props, oem_dicts and oem_dicts[0],
- OPTIONS.target_info_dict)
- source_fp = CalculateFingerprint(source_oem_props, oem_dicts and oem_dicts[0],
- OPTIONS.source_info_dict)
+ # If incremental then figure out what is being updated so metadata only for
+ # the updated image is included.
+ if source_file is not None:
+ input_tmp, input_zip = common.UnzipTemp(
+ target_file, UNZIP_PATTERN)
+ source_tmp, source_zip = common.UnzipTemp(
+ source_file, UNZIP_PATTERN)
- if source_oem_props is None and target_oem_props is None:
- script.AssertSomeFingerprint(source_fp, target_fp)
- elif source_oem_props is not None and target_oem_props is not None:
- script.AssertSomeThumbprint(
- GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
- GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
- elif source_oem_props is None and target_oem_props is not None:
- script.AssertFingerprintOrThumbprint(
- source_fp,
- GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict))
- else:
- script.AssertFingerprintOrThumbprint(
- target_fp,
- GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+ vendor_src = GetImage("vendor", source_tmp)
+ vendor_tgt = GetImage("vendor", input_tmp)
+ system_src = GetImage("system", source_tmp)
+ system_tgt = GetImage("system", input_tmp)
- metadata["pre-build"] = source_fp
- metadata["post-build"] = target_fp
- metadata["pre-build-incremental"] = GetBuildProp(
- "ro.build.version.incremental", OPTIONS.source_info_dict)
- metadata["post-build-incremental"] = GetBuildProp(
- "ro.build.version.incremental", OPTIONS.target_info_dict)
+ update_system = system_src.TotalSha1() != system_tgt.TotalSha1()
+ update_vendor = vendor_src.TotalSha1() != vendor_tgt.TotalSha1()
- source_boot = common.GetBootableImage(
- "/tmp/boot.img", "boot.img", OPTIONS.source_tmp, "BOOT",
- OPTIONS.source_info_dict)
- target_boot = common.GetBootableImage(
- "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT")
- updating_boot = (not OPTIONS.two_step and
- (source_boot.data != target_boot.data))
+ input_zip.close()
+ source_zip.close()
- source_recovery = common.GetBootableImage(
- "/tmp/recovery.img", "recovery.img", OPTIONS.source_tmp, "RECOVERY",
- OPTIONS.source_info_dict)
- target_recovery = common.GetBootableImage(
- "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")
- updating_recovery = (source_recovery.data != target_recovery.data)
+ target_zip = zipfile.ZipFile(target_file, "r")
+ AddCompatibilityArchive(target_zip, output_zip, update_system,
+ update_vendor)
+ common.ZipClose(target_zip)
- # Here's how we divide up the progress bar:
- # 0.1 for verifying the start state (PatchCheck calls)
- # 0.8 for applying patches (ApplyPatch calls)
- # 0.1 for unpacking verbatim files, symlinking, and doing the
- # device-specific commands.
-
- AppendAssertions(script, OPTIONS.target_info_dict, oem_dicts)
- device_specific.IncrementalOTA_Assertions()
-
- # Two-step incremental package strategy (in chronological order,
- # which is *not* the order in which the generated script has
- # things):
- #
- # if stage is not "2/3" or "3/3":
- # do verification on current system
- # write recovery image to boot partition
- # set stage to "2/3"
- # reboot to boot partition and restart recovery
- # else if stage is "2/3":
- # write recovery image to recovery partition
- # set stage to "3/3"
- # reboot to recovery partition and restart recovery
- # else:
- # (stage must be "3/3")
- # perform update:
- # patch system files, etc.
- # force full install of new boot image
- # set up system to update recovery partition on first boot
- # complete script normally
- # (allow recovery to mark itself finished and reboot)
-
- if OPTIONS.two_step:
- if not OPTIONS.source_info_dict.get("multistage_support", None):
- assert False, "two-step packages not supported by this build"
- fs = OPTIONS.source_info_dict["fstab"]["/misc"]
- assert fs.fs_type.upper() == "EMMC", \
- "two-step packages only supported on devices with EMMC /misc partitions"
- bcb_dev = {"bcb_dev": fs.device}
- common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
- script.AppendExtra("""
-if get_stage("%(bcb_dev)s") == "2/3" then
-""" % bcb_dev)
-
- # Stage 2/3: Write recovery image to /recovery (currently running /boot).
- script.Comment("Stage 2/3")
- script.AppendExtra("sleep(20);\n")
- script.WriteRawImage("/recovery", "recovery.img")
- script.AppendExtra("""
-set_stage("%(bcb_dev)s", "3/3");
-reboot_now("%(bcb_dev)s", "recovery");
-else if get_stage("%(bcb_dev)s") != "3/3" then
-""" % bcb_dev)
-
- # Stage 1/3: (a) Verify the current system.
- script.Comment("Stage 1/3")
-
- # Dump fingerprints
- script.Print("Source: %s" % (source_fp,))
- script.Print("Target: %s" % (target_fp,))
-
- script.Print("Verifying current system...")
-
- device_specific.IncrementalOTA_VerifyBegin()
-
- script.ShowProgress(0.1, 0)
- so_far = system_diff.EmitVerification(script)
- if vendor_diff:
- so_far += vendor_diff.EmitVerification(script)
-
- size = []
- if system_diff.patch_list:
- size.append(system_diff.largest_source_size)
- if vendor_diff:
- if vendor_diff.patch_list:
- size.append(vendor_diff.largest_source_size)
-
- if updating_boot:
- d = common.Difference(target_boot, source_boot)
- _, _, d = d.ComputePatch()
- print "boot target: %d source: %d diff: %d" % (
- target_boot.size, source_boot.size, len(d))
-
- common.ZipWriteStr(output_zip, "patch/boot.img.p", d)
-
- boot_type, boot_device = common.GetTypeAndDevice(
- "/boot", OPTIONS.source_info_dict)
-
- script.PatchCheck("%s:%s:%d:%s:%d:%s" %
- (boot_type, boot_device,
- source_boot.size, source_boot.sha1,
- target_boot.size, target_boot.sha1))
- so_far += source_boot.size
- size.append(target_boot.size)
-
- if size:
- script.CacheFreeSpaceCheck(max(size))
-
- device_specific.IncrementalOTA_VerifyEnd()
-
- if OPTIONS.two_step:
- # Stage 1/3: (b) Write recovery image to /boot.
- _WriteRecoveryImageToBoot(script, output_zip)
-
- script.AppendExtra("""
-set_stage("%(bcb_dev)s", "2/3");
-reboot_now("%(bcb_dev)s", "");
-else
-""" % bcb_dev)
-
- # Stage 3/3: Make changes.
- script.Comment("Stage 3/3")
-
- script.Comment("---- start making changes here ----")
-
- device_specific.IncrementalOTA_InstallBegin()
-
- if OPTIONS.two_step:
- common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
- script.WriteRawImage("/boot", "boot.img")
- print "writing full boot image (forced by two-step mode)"
-
- script.Print("Removing unneeded files...")
- system_diff.RemoveUnneededFiles(script, ("/system/recovery.img",))
- if vendor_diff:
- vendor_diff.RemoveUnneededFiles(script)
-
- script.ShowProgress(0.8, 0)
- total_patch_size = 1.0 + system_diff.TotalPatchSize()
- if vendor_diff:
- total_patch_size += vendor_diff.TotalPatchSize()
- if updating_boot:
- total_patch_size += target_boot.size
-
- script.Print("Patching system files...")
- so_far = system_diff.EmitPatches(script, total_patch_size, 0)
- if vendor_diff:
- script.Print("Patching vendor files...")
- so_far = vendor_diff.EmitPatches(script, total_patch_size, so_far)
-
- if not OPTIONS.two_step:
- if updating_boot:
- # Produce the boot image by applying a patch to the current
- # contents of the boot partition, and write it back to the
- # partition.
- script.Print("Patching boot image...")
- script.ApplyPatch("%s:%s:%d:%s:%d:%s"
- % (boot_type, boot_device,
- source_boot.size, source_boot.sha1,
- target_boot.size, target_boot.sha1),
- "-",
- target_boot.size, target_boot.sha1,
- source_boot.sha1, "patch/boot.img.p")
- so_far += target_boot.size
- script.SetProgress(so_far / total_patch_size)
- print "boot image changed; including."
- else:
- print "boot image unchanged; skipping."
-
- system_items = ItemSet("system", "META/filesystem_config.txt")
- if vendor_diff:
- vendor_items = ItemSet("vendor", "META/vendor_filesystem_config.txt")
-
- if updating_recovery:
- # Recovery is generated as a patch using both the boot image
- # (which contains the same linux kernel as recovery) and the file
- # /system/etc/recovery-resource.dat (which contains all the images
- # used in the recovery UI) as sources. This lets us minimize the
- # size of the patch, which must be included in every OTA package.
- #
- # For older builds where recovery-resource.dat is not present, we
- # use only the boot image as the source.
-
- if not target_has_recovery_patch:
- def output_sink(fn, data):
- common.ZipWriteStr(output_zip, "recovery/" + fn, data)
- system_items.Get("system/" + fn)
-
- common.MakeRecoveryPatch(OPTIONS.target_tmp, output_sink,
- target_recovery, target_boot)
- script.DeleteFiles(["/system/recovery-from-boot.p",
- "/system/etc/recovery.img",
- "/system/etc/install-recovery.sh"])
- print "recovery image changed; including as patch from boot."
- else:
- print "recovery image unchanged; skipping."
-
- script.ShowProgress(0.1, 10)
-
- target_symlinks = CopyPartitionFiles(system_items, target_zip, None)
- if vendor_diff:
- target_symlinks.extend(CopyPartitionFiles(vendor_items, target_zip, None))
-
- temp_script = script.MakeTemporary()
- system_items.GetMetadata(target_zip)
- system_items.Get("system").SetPermissions(temp_script)
- if vendor_diff:
- vendor_items.GetMetadata(target_zip)
- vendor_items.Get("vendor").SetPermissions(temp_script)
-
- # Note that this call will mess up the trees of Items, so make sure
- # we're done with them.
- source_symlinks = CopyPartitionFiles(system_items, source_zip, None)
- if vendor_diff:
- source_symlinks.extend(CopyPartitionFiles(vendor_items, source_zip, None))
-
- target_symlinks_d = dict([(i[1], i[0]) for i in target_symlinks])
- source_symlinks_d = dict([(i[1], i[0]) for i in source_symlinks])
-
- # Delete all the symlinks in source that aren't in target. This
- # needs to happen before verbatim files are unpacked, in case a
- # symlink in the source is replaced by a real file in the target.
-
- # If a symlink in the source will be replaced by a regular file, we cannot
- # delete the symlink/file in case the package gets applied again. For such
- # a symlink, we prepend a sha1_check() to detect if it has been updated.
- # (Bug: 23646151)
- replaced_symlinks = dict()
- if system_diff:
- for i in system_diff.verbatim_targets:
- replaced_symlinks["/%s" % (i[0],)] = i[2]
- if vendor_diff:
- for i in vendor_diff.verbatim_targets:
- replaced_symlinks["/%s" % (i[0],)] = i[2]
-
- if system_diff:
- for tf in system_diff.renames.values():
- replaced_symlinks["/%s" % (tf.name,)] = tf.sha1
- if vendor_diff:
- for tf in vendor_diff.renames.values():
- replaced_symlinks["/%s" % (tf.name,)] = tf.sha1
-
- always_delete = []
- may_delete = []
- for dest, link in source_symlinks:
- if link not in target_symlinks_d:
- if link in replaced_symlinks:
- may_delete.append((link, replaced_symlinks[link]))
- else:
- always_delete.append(link)
- script.DeleteFiles(always_delete)
- script.DeleteFilesIfNotMatching(may_delete)
-
- if system_diff.verbatim_targets:
- script.Print("Unpacking new system files...")
- script.UnpackPackageDir("system", "/system")
- if vendor_diff and vendor_diff.verbatim_targets:
- script.Print("Unpacking new vendor files...")
- script.UnpackPackageDir("vendor", "/vendor")
-
- if updating_recovery and not target_has_recovery_patch:
- script.Print("Unpacking new recovery...")
- script.UnpackPackageDir("recovery", "/system")
-
- system_diff.EmitRenames(script)
- if vendor_diff:
- vendor_diff.EmitRenames(script)
-
- script.Print("Symlinks and permissions...")
-
- # Create all the symlinks that don't already exist, or point to
- # somewhere different than what we want. Delete each symlink before
- # creating it, since the 'symlink' command won't overwrite.
- to_create = []
- for dest, link in target_symlinks:
- if link in source_symlinks_d:
- if dest != source_symlinks_d[link]:
- to_create.append((dest, link))
- else:
- to_create.append((dest, link))
- script.DeleteFiles([i[1] for i in to_create])
- script.MakeSymlinks(to_create)
-
- # Now that the symlinks are created, we can set all the
- # permissions.
- script.AppendScript(temp_script)
-
- # Do device-specific installation (eg, write radio image).
- device_specific.IncrementalOTA_InstallEnd()
-
- if OPTIONS.extra_script is not None:
- script.AppendExtra(OPTIONS.extra_script)
-
- # Patch the build.prop file last, so if something fails but the
- # device can still come up, it appears to be the old build and will
- # get set the OTA package again to retry.
- script.Print("Patching remaining system files...")
- system_diff.EmitDeferredPatches(script)
-
- if OPTIONS.wipe_user_data:
- script.Print("Erasing user data...")
- script.FormatPartition("/data")
- metadata["ota-wipe"] = "yes"
-
- if OPTIONS.two_step:
- script.AppendExtra("""
-set_stage("%(bcb_dev)s", "");
-endif;
-endif;
-""" % bcb_dev)
-
- if OPTIONS.verify and system_diff:
- script.Print("Remounting and verifying system partition files...")
- script.Unmount("/system")
- script.Mount("/system", recovery_mount_options)
- system_diff.EmitExplicitTargetVerification(script)
-
- if OPTIONS.verify and vendor_diff:
- script.Print("Remounting and verifying vendor partition files...")
- script.Unmount("/vendor")
- script.Mount("/vendor", recovery_mount_options)
- vendor_diff.EmitExplicitTargetVerification(script)
-
- # For downgrade OTAs, we prefer to use the update-binary in the source
- # build that is actually newer than the one in the target build.
- if OPTIONS.downgrade:
- script.AddToZip(source_zip, output_zip, input_path=OPTIONS.updater_binary)
- else:
- script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
-
- metadata["ota-required-cache"] = str(script.required_cache)
+ # Write the current metadata entry with placeholders.
+ metadata['ota-streaming-property-files'] = ComputeStreamingMetadata(
+ output_zip, reserve_space=True)
WriteMetadata(metadata, output_zip)
+ common.ZipClose(output_zip)
+
+ # SignOutput(), which in turn calls signapk.jar, will possibly reorder the
+ # zip entries, as well as padding the entry headers. We do a preliminary
+ # signing (with an incomplete metadata entry) to allow that to happen. Then
+ # compute the zip entry offsets, write back the final metadata and do the
+ # final signing.
+ prelim_signing = tempfile.NamedTemporaryFile()
+ SignOutput(temp_zip_file.name, prelim_signing.name)
+ common.ZipClose(temp_zip_file)
+
+ # Open the signed zip. Compute the final metadata that's needed for streaming.
+ prelim_zip = zipfile.ZipFile(prelim_signing, "r",
+ compression=zipfile.ZIP_DEFLATED)
+ expected_length = len(metadata['ota-streaming-property-files'])
+ metadata['ota-streaming-property-files'] = ComputeStreamingMetadata(
+ prelim_zip, reserve_space=False, expected_length=expected_length)
+
+ # Copy the zip entries, as we cannot update / delete entries with zipfile.
+ final_signing = tempfile.NamedTemporaryFile()
+ output_zip = zipfile.ZipFile(final_signing, "w",
+ compression=zipfile.ZIP_DEFLATED)
+ for item in prelim_zip.infolist():
+ if item.filename == METADATA_NAME:
+ continue
+
+ data = prelim_zip.read(item.filename)
+ out_info = copy.copy(item)
+ common.ZipWriteStr(output_zip, out_info, data)
+
+ # Now write the final metadata entry.
+ WriteMetadata(metadata, output_zip)
+ common.ZipClose(prelim_zip)
+ common.ZipClose(output_zip)
+
+ # Re-sign the package after updating the metadata entry.
+ SignOutput(final_signing.name, output_file)
+ final_signing.close()
+
+ # Reopen the final signed zip to double check the streaming metadata.
+ output_zip = zipfile.ZipFile(output_file, "r")
+ actual = metadata['ota-streaming-property-files'].strip()
+ expected = ComputeStreamingMetadata(output_zip)
+ assert actual == expected, \
+ "Mismatching streaming metadata: %s vs %s." % (actual, expected)
+ common.ZipClose(output_zip)
def main(argv):
@@ -1994,8 +1273,6 @@
OPTIONS.full_bootloader = True
elif o in ("-w", "--wipe_user_data"):
OPTIONS.wipe_user_data = True
- elif o in ("-n", "--no_prereq"):
- OPTIONS.omit_prereq = True
elif o == "--downgrade":
OPTIONS.downgrade = True
OPTIONS.wipe_user_data = True
@@ -2007,11 +1284,6 @@
OPTIONS.oem_no_mount = True
elif o in ("-e", "--extra_script"):
OPTIONS.extra_script = a
- elif o in ("-a", "--aslr_mode"):
- if a in ("on", "On", "true", "True", "yes", "Yes"):
- OPTIONS.aslr_mode = True
- else:
- OPTIONS.aslr_mode = False
elif o in ("-t", "--worker_threads"):
if a.isdigit():
OPTIONS.worker_threads = int(a)
@@ -2044,12 +1316,14 @@
OPTIONS.payload_signer = a
elif o == "--payload_signer_args":
OPTIONS.payload_signer_args = shlex.split(a)
+ elif o == "--extracted_input_target_files":
+ OPTIONS.extracted_input = a
else:
return False
return True
args = common.ParseOptions(argv, __doc__,
- extra_opts="b:k:i:d:wne:t:a:2o:",
+ extra_opts="b:k:i:d:we:t:2o:",
extra_long_opts=[
"board_config=",
"package_key=",
@@ -2057,12 +1331,10 @@
"full_radio",
"full_bootloader",
"wipe_user_data",
- "no_prereq",
"downgrade",
"override_timestamp",
"extra_script=",
"worker_threads=",
- "aslr_mode=",
"two_step",
"no_signing",
"block",
@@ -2076,6 +1348,7 @@
"log_diff=",
"payload_signer=",
"payload_signer_args=",
+ "extracted_input_target_files=",
], extra_option_handler=option_handler)
if len(args) != 2:
@@ -2091,20 +1364,33 @@
# 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 - consider"
- "using --omit_prereq?")
+ raise ValueError("Cannot generate downgradable full OTAs")
assert not (OPTIONS.downgrade and OPTIONS.timestamp), \
"Cannot have --downgrade AND --override_timestamp both"
# Load the dict file from the zip directly to have a peek at the OTA type.
# For packages using A/B update, unzipping is not needed.
- input_zip = zipfile.ZipFile(args[0], "r")
- OPTIONS.info_dict = common.LoadInfoDict(input_zip)
- common.ZipClose(input_zip)
+ if OPTIONS.extracted_input is not None:
+ OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.extracted_input, OPTIONS.extracted_input)
+ else:
+ input_zip = zipfile.ZipFile(args[0], "r")
+ OPTIONS.info_dict = common.LoadInfoDict(input_zip)
+ common.ZipClose(input_zip)
ab_update = OPTIONS.info_dict.get("ab_update") == "true"
+ # Use the default key to sign the package if not specified with package_key.
+ # package_keys are needed on ab_updates, so always define them if an
+ # ab_update is getting created.
+ if not OPTIONS.no_signing or ab_update:
+ if OPTIONS.package_key is None:
+ OPTIONS.package_key = OPTIONS.info_dict.get(
+ "default_system_dev_certificate",
+ "build/target/product/security/testkey")
+ # Get signing keys
+ OPTIONS.key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
+
if ab_update:
if OPTIONS.incremental_source is not None:
OPTIONS.target_info_dict = OPTIONS.info_dict
@@ -2113,11 +1399,11 @@
common.ZipClose(source_zip)
if OPTIONS.verbose:
- print "--- target info ---"
+ print("--- target info ---")
common.DumpInfoDict(OPTIONS.info_dict)
if OPTIONS.incremental_source is not None:
- print "--- source info ---"
+ print("--- source info ---")
common.DumpInfoDict(OPTIONS.source_info_dict)
WriteABOTAPackageWithBrilloScript(
@@ -2125,20 +1411,27 @@
output_file=args[1],
source_file=OPTIONS.incremental_source)
- print "done."
+ print("done.")
return
if OPTIONS.extra_script is not None:
OPTIONS.extra_script = open(OPTIONS.extra_script).read()
- print "unzipping target target-files..."
- OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
+ if OPTIONS.extracted_input is not None:
+ OPTIONS.input_tmp = OPTIONS.extracted_input
+ OPTIONS.target_tmp = OPTIONS.input_tmp
+ OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.input_tmp, OPTIONS.input_tmp)
+ input_zip = zipfile.ZipFile(args[0], "r")
+ else:
+ print("unzipping target target-files...")
+ OPTIONS.input_tmp, input_zip = common.UnzipTemp(
+ args[0], UNZIP_PATTERN)
- OPTIONS.target_tmp = OPTIONS.input_tmp
- OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.target_tmp)
+ OPTIONS.target_tmp = OPTIONS.input_tmp
+ OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.target_tmp)
if OPTIONS.verbose:
- print "--- target info ---"
+ print("--- target info ---")
common.DumpInfoDict(OPTIONS.info_dict)
# If the caller explicitly specified the device-specific extensions
@@ -2151,7 +1444,7 @@
if OPTIONS.device_specific is None:
from_input = os.path.join(OPTIONS.input_tmp, "META", "releasetools.py")
if os.path.exists(from_input):
- print "(using device-specific extensions from target_files)"
+ print("(using device-specific extensions from target_files)")
OPTIONS.device_specific = from_input
else:
OPTIONS.device_specific = OPTIONS.info_dict.get("tool_extensions", None)
@@ -2163,13 +1456,6 @@
raise common.ExternalError(
"--- target build has specified no recovery ---")
- # Use the default key to sign the package if not specified with package_key.
- if not OPTIONS.no_signing:
- if OPTIONS.package_key is None:
- OPTIONS.package_key = OPTIONS.info_dict.get(
- "default_system_dev_certificate",
- "build/target/product/security/testkey")
-
# Set up the output zip. Create a temporary zip file if signing is needed.
if OPTIONS.no_signing:
if os.path.exists(args[1]):
@@ -2184,7 +1470,7 @@
# Non A/B OTAs rely on /cache partition to store temporary files.
cache_size = OPTIONS.info_dict.get("cache_size", None)
if cache_size is None:
- print "--- can't determine the cache partition size ---"
+ print("--- can't determine the cache partition size ---")
OPTIONS.cache_size = cache_size
# Generate a verify package.
@@ -2198,17 +1484,18 @@
# Generate an incremental OTA. It will fall back to generate a full OTA on
# failure unless no_fallback_to_full is specified.
else:
- print "unzipping source target-files..."
+ print("unzipping source target-files...")
OPTIONS.source_tmp, source_zip = common.UnzipTemp(
- OPTIONS.incremental_source)
+ OPTIONS.incremental_source,
+ UNZIP_PATTERN)
OPTIONS.target_info_dict = OPTIONS.info_dict
OPTIONS.source_info_dict = common.LoadInfoDict(source_zip,
OPTIONS.source_tmp)
if OPTIONS.verbose:
- print "--- source info ---"
+ print("--- source info ---")
common.DumpInfoDict(OPTIONS.source_info_dict)
try:
- WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
+ WriteBlockIncrementalOTAPackage(input_zip, source_zip, output_zip)
if OPTIONS.log_diff:
out_file = open(OPTIONS.log_diff, 'w')
import target_files_diff
@@ -2220,7 +1507,7 @@
except ValueError:
if not OPTIONS.fallback_to_full:
raise
- print "--- failed to build incremental; falling back to full ---"
+ print("--- failed to build incremental; falling back to full ---")
OPTIONS.incremental_source = None
WriteFullOTAPackage(input_zip, output_zip)
@@ -2231,7 +1518,7 @@
SignOutput(temp_zip_file.name, args[1])
temp_zip_file.close()
- print "done."
+ print("done.")
if __name__ == '__main__':
@@ -2239,9 +1526,7 @@
common.CloseInheritedPipes()
main(sys.argv[1:])
except common.ExternalError as e:
- print
- print " ERROR: %s" % (e,)
- print
+ print("\n ERROR: %s\n" % (e,))
sys.exit(1)
finally:
common.Cleanup()
diff --git a/tools/releasetools/ota_package_parser.py b/tools/releasetools/ota_package_parser.py
new file mode 100755
index 0000000..331122b
--- /dev/null
+++ b/tools/releasetools/ota_package_parser.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env python
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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.
+
+import argparse
+import logging
+import sys
+import traceback
+import zipfile
+
+from rangelib import RangeSet
+
+class Stash(object):
+ """Build a map to track stashed blocks during update simulation."""
+
+ def __init__(self):
+ self.blocks_stashed = 0
+ self.overlap_blocks_stashed = 0
+ self.max_stash_needed = 0
+ self.current_stash_size = 0
+ self.stash_map = {}
+
+ def StashBlocks(self, SHA1, blocks):
+ if SHA1 in self.stash_map:
+ logging.info("already stashed {}: {}".format(SHA1, blocks))
+ return
+ self.blocks_stashed += blocks.size()
+ self.current_stash_size += blocks.size()
+ self.max_stash_needed = max(self.current_stash_size, self.max_stash_needed)
+ self.stash_map[SHA1] = blocks
+
+ def FreeBlocks(self, SHA1):
+ assert self.stash_map.has_key(SHA1), "stash {} not found".format(SHA1)
+ self.current_stash_size -= self.stash_map[SHA1].size()
+ del self.stash_map[SHA1]
+
+ def HandleOverlapBlocks(self, SHA1, blocks):
+ self.StashBlocks(SHA1, blocks)
+ self.overlap_blocks_stashed += blocks.size()
+ self.FreeBlocks(SHA1)
+
+
+class OtaPackageParser(object):
+ """Parse a block-based OTA package."""
+
+ def __init__(self, package):
+ self.package = package
+ self.new_data_size = 0
+ self.patch_data_size = 0
+ self.block_written = 0
+ self.block_stashed = 0
+
+ @staticmethod
+ def GetSizeString(size):
+ assert size >= 0
+ base = 1024.0
+ if size <= base:
+ return "{} bytes".format(size)
+ for units in ['K', 'M', 'G']:
+ if size <= base * 1024 or units == 'G':
+ return "{:.1f}{}".format(size / base, units)
+ base *= 1024
+
+ def ParseTransferList(self, name):
+ """Simulate the transfer commands and calculate the amout of I/O."""
+
+ logging.info("\nSimulating commands in '{}':".format(name))
+ lines = self.package.read(name).strip().splitlines()
+ assert len(lines) >= 4, "{} is too short; Transfer list expects at least" \
+ "4 lines, it has {}".format(name, len(lines))
+ assert int(lines[0]) >= 3
+ logging.info("(version: {})".format(lines[0]))
+
+ blocks_written = 0
+ my_stash = Stash()
+ for line in lines[4:]:
+ cmd_list = line.strip().split(" ")
+ cmd_name = cmd_list[0]
+ try:
+ if cmd_name == "new" or cmd_name == "zero":
+ assert len(cmd_list) == 2, "command format error: {}".format(line)
+ target_range = RangeSet.parse_raw(cmd_list[1])
+ blocks_written += target_range.size()
+ elif cmd_name == "move":
+ # Example: move <onehash> <tgt_range> <src_blk_count> <src_range>
+ # [<loc_range> <stashed_blocks>]
+ assert len(cmd_list) >= 5, "command format error: {}".format(line)
+ target_range = RangeSet.parse_raw(cmd_list[2])
+ blocks_written += target_range.size()
+ if cmd_list[4] == '-':
+ continue
+ SHA1 = cmd_list[1]
+ source_range = RangeSet.parse_raw(cmd_list[4])
+ if target_range.overlaps(source_range):
+ my_stash.HandleOverlapBlocks(SHA1, source_range)
+ elif cmd_name == "bsdiff" or cmd_name == "imgdiff":
+ # Example: bsdiff <offset> <len> <src_hash> <tgt_hash> <tgt_range>
+ # <src_blk_count> <src_range> [<loc_range> <stashed_blocks>]
+ assert len(cmd_list) >= 8, "command format error: {}".format(line)
+ target_range = RangeSet.parse_raw(cmd_list[5])
+ blocks_written += target_range.size()
+ if cmd_list[7] == '-':
+ continue
+ source_SHA1 = cmd_list[3]
+ source_range = RangeSet.parse_raw(cmd_list[7])
+ if target_range.overlaps(source_range):
+ my_stash.HandleOverlapBlocks(source_SHA1, source_range)
+ elif cmd_name == "stash":
+ assert len(cmd_list) == 3, "command format error: {}".format(line)
+ SHA1 = cmd_list[1]
+ source_range = RangeSet.parse_raw(cmd_list[2])
+ my_stash.StashBlocks(SHA1, source_range)
+ elif cmd_name == "free":
+ assert len(cmd_list) == 2, "command format error: {}".format(line)
+ SHA1 = cmd_list[1]
+ my_stash.FreeBlocks(SHA1)
+ except:
+ logging.error("failed to parse command in: " + line)
+ raise
+
+ self.block_written += blocks_written
+ self.block_stashed += my_stash.blocks_stashed
+
+ logging.info("blocks written: {} (expected: {})".format(
+ blocks_written, lines[1]))
+ logging.info("max blocks stashed simultaneously: {} (expected: {})".
+ format(my_stash.max_stash_needed, lines[3]))
+ logging.info("total blocks stashed: {}".format(my_stash.blocks_stashed))
+ logging.info("blocks stashed implicitly: {}".format(
+ my_stash.overlap_blocks_stashed))
+
+ def PrintDataInfo(self, partition):
+ logging.info("\nReading data info for {} partition:".format(partition))
+ new_data = self.package.getinfo(partition + ".new.dat")
+ patch_data = self.package.getinfo(partition + ".patch.dat")
+ logging.info("{:<40}{:<40}".format(new_data.filename, patch_data.filename))
+ logging.info("{:<40}{:<40}".format(
+ "compress_type: " + str(new_data.compress_type),
+ "compress_type: " + str(patch_data.compress_type)))
+ logging.info("{:<40}{:<40}".format(
+ "compressed_size: " + OtaPackageParser.GetSizeString(
+ new_data.compress_size),
+ "compressed_size: " + OtaPackageParser.GetSizeString(
+ patch_data.compress_size)))
+ logging.info("{:<40}{:<40}".format(
+ "file_size: " + OtaPackageParser.GetSizeString(new_data.file_size),
+ "file_size: " + OtaPackageParser.GetSizeString(patch_data.file_size)))
+
+ self.new_data_size += new_data.file_size
+ self.patch_data_size += patch_data.file_size
+
+ def AnalyzePartition(self, partition):
+ assert partition in ("system", "vendor")
+ assert partition + ".new.dat" in self.package.namelist()
+ assert partition + ".patch.dat" in self.package.namelist()
+ assert partition + ".transfer.list" in self.package.namelist()
+
+ self.PrintDataInfo(partition)
+ self.ParseTransferList(partition + ".transfer.list")
+
+ def PrintMetadata(self):
+ metadata_path = "META-INF/com/android/metadata"
+ logging.info("\nMetadata info:")
+ metadata_info = {}
+ for line in self.package.read(metadata_path).strip().splitlines():
+ index = line.find("=")
+ metadata_info[line[0 : index].strip()] = line[index + 1:].strip()
+ assert metadata_info.get("ota-type") == "BLOCK"
+ assert "pre-device" in metadata_info
+ logging.info("device: {}".format(metadata_info["pre-device"]))
+ if "pre-build" in metadata_info:
+ logging.info("pre-build: {}".format(metadata_info["pre-build"]))
+ assert "post-build" in metadata_info
+ logging.info("post-build: {}".format(metadata_info["post-build"]))
+
+ def Analyze(self):
+ logging.info("Analyzing ota package: " + self.package.filename)
+ self.PrintMetadata()
+ assert "system.new.dat" in self.package.namelist()
+ self.AnalyzePartition("system")
+ if "vendor.new.dat" in self.package.namelist():
+ self.AnalyzePartition("vendor")
+
+ #TODO Add analysis of other partitions(e.g. bootloader, boot, radio)
+
+ BLOCK_SIZE = 4096
+ logging.info("\nOTA package analyzed:")
+ logging.info("new data size (uncompressed): " +
+ OtaPackageParser.GetSizeString(self.new_data_size))
+ logging.info("patch data size (uncompressed): " +
+ OtaPackageParser.GetSizeString(self.patch_data_size))
+ logging.info("total data written: " +
+ OtaPackageParser.GetSizeString(self.block_written * BLOCK_SIZE))
+ logging.info("total data stashed: " +
+ OtaPackageParser.GetSizeString(self.block_stashed * BLOCK_SIZE))
+
+
+def main(argv):
+ parser = argparse.ArgumentParser(description='Analyze an OTA package.')
+ parser.add_argument("ota_package", help='Path of the OTA package.')
+ args = parser.parse_args(argv)
+
+ logging_format = '%(message)s'
+ logging.basicConfig(level=logging.INFO, format=logging_format)
+
+ try:
+ with zipfile.ZipFile(args.ota_package, 'r') as package:
+ package_parser = OtaPackageParser(package)
+ package_parser.Analyze()
+ except:
+ logging.error("Failed to read " + args.ota_package)
+ traceback.print_exc()
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/tools/releasetools/rangelib.py b/tools/releasetools/rangelib.py
index c9bd375..fa6eec1 100644
--- a/tools/releasetools/rangelib.py
+++ b/tools/releasetools/rangelib.py
@@ -71,6 +71,19 @@
"""
return cls(text)
+ @classmethod
+ def parse_raw(cls, text):
+ """Parse a string generated by RangeSet.to_string_raw().
+
+ >>> RangeSet.parse_raw(RangeSet("0-9").to_string_raw())
+ <RangeSet("0-9")>
+ """
+
+ raw = [int(i) for i in text.split(',')]
+ assert raw[0] == len(raw[1:]), "Invalid raw string."
+
+ return cls(data=raw[1:])
+
def _parse_internal(self, text):
data = []
last = -1
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 52b526c..b9bb4d0 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -92,7 +92,6 @@
import errno
import os
import re
-import shutil
import subprocess
import tempfile
import zipfile
@@ -104,6 +103,7 @@
OPTIONS.extra_apks = {}
OPTIONS.key_map = {}
+OPTIONS.rebuild_recovery = False
OPTIONS.replace_ota_keys = False
OPTIONS.replace_verity_public_key = False
OPTIONS.replace_verity_private_key = False
@@ -186,27 +186,8 @@
maxsize = max([len(os.path.basename(i.filename))
for i in input_tf_zip.infolist()
if i.filename.endswith('.apk')])
- rebuild_recovery = False
system_root_image = misc_info.get("system_root_image") == "true"
- # tmpdir will only be used to regenerate the recovery-from-boot patch.
- tmpdir = tempfile.mkdtemp()
- def write_to_temp(fn, attr, data):
- fn = os.path.join(tmpdir, fn)
- if fn.endswith("/"):
- fn = os.path.join(tmpdir, fn)
- os.mkdir(fn)
- else:
- d = os.path.dirname(fn)
- if d and not os.path.exists(d):
- os.makedirs(d)
-
- if attr >> 16 == 0xa1ff:
- os.symlink(data, fn)
- else:
- with open(fn, "wb") as f:
- f.write(data)
-
for info in input_tf_zip.infolist():
if info.filename.startswith("IMAGES/"):
continue
@@ -237,21 +218,17 @@
print "rewriting %s:" % (info.filename,)
new_data = RewriteProps(data, misc_info)
common.ZipWriteStr(output_tf_zip, out_info, new_data)
- if info.filename in ("BOOT/RAMDISK/default.prop",
- "ROOT/default.prop",
- "RECOVERY/RAMDISK/default.prop"):
- write_to_temp(info.filename, info.external_attr, new_data)
elif info.filename.endswith("mac_permissions.xml"):
print "rewriting %s with new keys." % (info.filename,)
new_data = ReplaceCerts(data)
common.ZipWriteStr(output_tf_zip, out_info, new_data)
- # Trigger a rebuild of the recovery patch if needed.
+ # Ask add_img_to_target_files to rebuild the recovery patch if needed.
elif info.filename in ("SYSTEM/recovery-from-boot.p",
"SYSTEM/etc/recovery.img",
"SYSTEM/bin/install-recovery.sh"):
- rebuild_recovery = True
+ OPTIONS.rebuild_recovery = True
# Don't copy OTA keys if we're replacing them.
elif (OPTIONS.replace_ota_keys and
@@ -280,34 +257,15 @@
pass
# Skip the care_map as we will regenerate the system/vendor images.
- elif (info.filename == "META/care_map.txt"):
+ elif info.filename == "META/care_map.txt":
pass
- # Copy BOOT/, RECOVERY/, META/, ROOT/ to rebuild recovery patch. This case
- # must come AFTER other matching rules.
- elif (info.filename.startswith("BOOT/") or
- info.filename.startswith("RECOVERY/") or
- info.filename.startswith("META/") or
- info.filename.startswith("ROOT/") or
- info.filename == "SYSTEM/etc/recovery-resource.dat"):
- write_to_temp(info.filename, info.external_attr, data)
- common.ZipWriteStr(output_tf_zip, out_info, data)
-
# A non-APK file; copy it verbatim.
else:
common.ZipWriteStr(output_tf_zip, out_info, data)
if OPTIONS.replace_ota_keys:
- new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
- if new_recovery_keys:
- if system_root_image:
- recovery_keys_location = "BOOT/RAMDISK/res/keys"
- else:
- recovery_keys_location = "RECOVERY/RAMDISK/res/keys"
- # The "new_recovery_keys" has been already written into the output_tf_zip
- # while calling ReplaceOtaKeys(). We're just putting the same copy to
- # tmpdir in case we need to regenerate the recovery-from-boot patch.
- write_to_temp(recovery_keys_location, 0o755 << 16, new_recovery_keys)
+ ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
# Replace the keyid string in META/misc_info.txt.
if OPTIONS.replace_verity_private_key:
@@ -321,33 +279,13 @@
dest = "BOOT/RAMDISK/verity_key"
# We are replacing the one in boot image only, since the one under
# recovery won't ever be needed.
- new_data = ReplaceVerityPublicKey(
+ ReplaceVerityPublicKey(
output_tf_zip, dest, OPTIONS.replace_verity_public_key[1])
- write_to_temp(dest, 0o755 << 16, new_data)
# Replace the keyid string in BOOT/cmdline.
if OPTIONS.replace_verity_keyid:
- new_cmdline = ReplaceVerityKeyId(input_tf_zip, output_tf_zip,
- OPTIONS.replace_verity_keyid[1])
- # Writing the new cmdline to tmpdir is redundant as the bootimage
- # gets build in the add_image_to_target_files and rebuild_recovery
- # is not exercised while building the boot image for the A/B
- # path
- write_to_temp("BOOT/cmdline", 0o755 << 16, new_cmdline)
-
- if rebuild_recovery:
- recovery_img = common.GetBootableImage(
- "recovery.img", "recovery.img", tmpdir, "RECOVERY", info_dict=misc_info)
- boot_img = common.GetBootableImage(
- "boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info)
-
- def output_sink(fn, data):
- common.ZipWriteStr(output_tf_zip, "SYSTEM/" + fn, data)
-
- common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img,
- info_dict=misc_info)
-
- shutil.rmtree(tmpdir)
+ ReplaceVerityKeyId(input_tf_zip, output_tf_zip,
+ OPTIONS.replace_verity_keyid[1])
def ReplaceCerts(data):
@@ -553,9 +491,12 @@
for param in in_cmdline.split():
if "veritykeyid" in param:
# extract keyid using openssl command
- p = common.Run(["openssl", "x509", "-in", keypath, "-text"], stdout=subprocess.PIPE)
+ p = common.Run(
+ ["openssl", "x509", "-in", keypath, "-text"],
+ stdout=subprocess.PIPE)
keyid, stderr = p.communicate()
- keyid = re.search(r'keyid:([0-9a-fA-F:]*)', keyid).group(1).replace(':', '').lower()
+ keyid = re.search(
+ r'keyid:([0-9a-fA-F:]*)', keyid).group(1).replace(':', '').lower()
print "Replacing verity keyid with %s error=%s" % (keyid, stderr)
out_cmdline.append("veritykeyid=id:%s" % (keyid,))
else:
@@ -592,7 +533,6 @@
codename = None
for line in data.split("\n"):
line = line.strip()
- original_line = line
if line and line[0] != '#' and "=" in line:
key, value = line.split("=", 1)
key = key.strip()
@@ -615,7 +555,6 @@
codenames = None
for line in data.split("\n"):
line = line.strip()
- original_line = line
if line and line[0] != '#' and "=" in line:
key, value = line.split("=", 1)
key = key.strip()
@@ -698,12 +637,8 @@
CheckAllApksSigned(input_zip, apk_key_map)
key_passwords = common.GetKeyPasswords(set(apk_key_map.values()))
- platform_api_level, platform_codename = GetApiLevelAndCodename(input_zip)
+ platform_api_level, _ = GetApiLevelAndCodename(input_zip)
codename_to_api_level_map = GetCodenameToApiLevelMap(input_zip)
- # Android N will be API Level 24, but isn't yet.
- # TODO: Remove this workaround once Android N is officially API Level 24.
- if platform_api_level == 23 and platform_codename == "N":
- platform_api_level = 24
ProcessTargetFiles(input_zip, output_zip, misc_info,
apk_key_map, key_passwords,
@@ -714,7 +649,12 @@
common.ZipClose(output_zip)
# Skip building userdata.img and cache.img when signing the target files.
- new_args = ["--is_signing", args[1]]
+ new_args = ["--is_signing"]
+ # add_img_to_target_files builds the system image from scratch, so the
+ # recovery patch is guaranteed to be regenerated there.
+ if OPTIONS.rebuild_recovery:
+ new_args.append("--rebuild_recovery")
+ new_args.append(args[1])
add_img_to_target_files.main(new_args)
print "done."
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
index 4ba7560..7eb60d9 100644
--- a/tools/releasetools/sparse_img.py
+++ b/tools/releasetools/sparse_img.py
@@ -144,6 +144,12 @@
f.seek(16, os.SEEK_SET)
f.write(struct.pack("<2I", self.total_blocks, self.total_chunks))
+ def RangeSha1(self, ranges):
+ h = sha1()
+ for data in self._GetRangeData(ranges):
+ h.update(data)
+ return h.hexdigest()
+
def ReadRangeSet(self, ranges):
return [d for d in self._GetRangeData(ranges)]
@@ -155,10 +161,11 @@
ranges = self.care_map
if not include_clobbered_blocks:
ranges = ranges.subtract(self.clobbered_blocks)
- h = sha1()
- for d in self._GetRangeData(ranges):
- h.update(d)
- return h.hexdigest()
+ return self.RangeSha1(ranges)
+
+ def WriteRangeDataToFd(self, ranges, fd):
+ for data in self._GetRangeData(ranges):
+ fd.write(data)
def _GetRangeData(self, ranges):
"""Generator that produces all the image data in 'ranges'. The
diff --git a/tools/releasetools/target_files_diff.py b/tools/releasetools/target_files_diff.py
index 0f717e0..7415f27 100755
--- a/tools/releasetools/target_files_diff.py
+++ b/tools/releasetools/target_files_diff.py
@@ -51,10 +51,6 @@
'RECOVERY/RAMDISK/selinux_version']:
return True
- # b/26956807 .odex files are not deterministic
- if name.endswith('.odex'):
- return True
-
return False
diff --git a/tools/releasetools/test_blockimgdiff.py b/tools/releasetools/test_blockimgdiff.py
index 03e8c8b..e5a3694 100644
--- a/tools/releasetools/test_blockimgdiff.py
+++ b/tools/releasetools/test_blockimgdiff.py
@@ -19,8 +19,7 @@
import common
import unittest
-from collections import OrderedDict
-from blockimgdiff import BlockImageDiff, EmptyImage, DataImage, Transfer
+from blockimgdiff import BlockImageDiff, EmptyImage, Transfer
from rangelib import RangeSet
class BlockImageDiffTest(unittest.TestCase):
@@ -42,14 +41,14 @@
block_image_diff = BlockImageDiff(tgt, src)
transfers = block_image_diff.transfers
- t0 = Transfer(
- "t1", "t1", RangeSet("10-15"), RangeSet("0-5"), "move", transfers)
- t1 = Transfer(
- "t2", "t2", RangeSet("20-25"), RangeSet("0-7"), "move", transfers)
- t2 = Transfer(
- "t3", "t3", RangeSet("30-35"), RangeSet("0-4"), "move", transfers)
- t3 = Transfer(
- "t4", "t4", RangeSet("0-10"), RangeSet("40-50"), "move", transfers)
+ t0 = Transfer("t1", "t1", RangeSet("10-15"), RangeSet("0-5"), "t1hash",
+ "t1hash", "move", transfers)
+ t1 = Transfer("t2", "t2", RangeSet("20-25"), RangeSet("0-7"), "t2hash",
+ "t2hash", "move", transfers)
+ t2 = Transfer("t3", "t3", RangeSet("30-35"), RangeSet("0-4"), "t3hash",
+ "t3hash", "move", transfers)
+ t3 = Transfer("t4", "t4", RangeSet("0-10"), RangeSet("40-50"), "t4hash",
+ "t4hash", "move", transfers)
block_image_diff.GenerateDigraph()
t3_goes_after_copy = t3.goes_after.copy()
@@ -75,3 +74,70 @@
self.assertEqual(t2, elements[0])
self.assertEqual(t0, elements[1])
self.assertEqual(t1, elements[2])
+
+ def test_ReviseStashSize(self):
+ """ReviseStashSize should convert transfers to 'new' commands as needed.
+
+ t1: diff <20-29> => <11-15>
+ t2: diff <11-15> => <20-29>
+ """
+
+ src = EmptyImage()
+ tgt = EmptyImage()
+ block_image_diff = BlockImageDiff(tgt, src, version=3)
+
+ transfers = block_image_diff.transfers
+ Transfer("t1", "t1", RangeSet("11-15"), RangeSet("20-29"), "t1hash",
+ "t1hash", "diff", transfers)
+ Transfer("t2", "t2", RangeSet("20-29"), RangeSet("11-15"), "t2hash",
+ "t2hash", "diff", transfers)
+
+ block_image_diff.GenerateDigraph()
+ block_image_diff.FindVertexSequence()
+ block_image_diff.ReverseBackwardEdges()
+
+ # Sufficient cache to stash 5 blocks (size * 0.8 >= 5).
+ common.OPTIONS.cache_size = 7 * 4096
+ self.assertEqual(0, block_image_diff.ReviseStashSize())
+
+ # Insufficient cache to stash 5 blocks (size * 0.8 < 5).
+ common.OPTIONS.cache_size = 6 * 4096
+ self.assertEqual(10, block_image_diff.ReviseStashSize())
+
+ def test_ReviseStashSize_bug_33687949(self):
+ """ReviseStashSize() should "free" the used stash _after_ the command.
+
+ t1: diff <1-5> => <11-15>
+ t2: diff <11-15> => <21-25>
+ t3: diff <11-15 30-39> => <1-5 30-39>
+
+ For transfer t3, the used stash "11-15" should not be freed until the
+ command finishes. Assume the allowed cache size is 12-block, it should
+ convert the command to 'new' due to insufficient cache (12 < 5 + 10).
+ """
+
+ src = EmptyImage()
+ tgt = EmptyImage()
+ block_image_diff = BlockImageDiff(tgt, src, version=3)
+
+ transfers = block_image_diff.transfers
+ t1 = Transfer("t1", "t1", RangeSet("11-15"), RangeSet("1-5"), "t1hash",
+ "t1hash", "diff", transfers)
+ t2 = Transfer("t2", "t2", RangeSet("21-25"), RangeSet("11-15"), "t2hash",
+ "t2hash", "diff", transfers)
+ t3 = Transfer("t3", "t3", RangeSet("1-5 30-39"), RangeSet("11-15 30-39"),
+ "t3hash", "t3hash", "diff", transfers)
+
+ block_image_diff.GenerateDigraph()
+
+ # Instead of calling FindVertexSequence() and ReverseBackwardEdges(), we
+ # just set up the stash_before and use_stash manually. Otherwise it will
+ # reorder the transfer, which makes testing ReviseStashSize() harder.
+ t1.stash_before.append((0, RangeSet("11-15")))
+ t2.use_stash.append((0, RangeSet("11-15")))
+ t1.stash_before.append((1, RangeSet("11-15")))
+ t3.use_stash.append((1, RangeSet("11-15")))
+
+ # Insufficient cache to stash 15 blocks (size * 0.8 < 15).
+ common.OPTIONS.cache_size = 15 * 4096
+ self.assertEqual(15, block_image_diff.ReviseStashSize())
diff --git a/tools/releasetools/test_rangelib.py b/tools/releasetools/test_rangelib.py
index edf1c4b..e181187 100644
--- a/tools/releasetools/test_rangelib.py
+++ b/tools/releasetools/test_rangelib.py
@@ -125,6 +125,20 @@
self.assertTrue(RangeSet(data=[0, 5, 5, 10]).monotonic)
self.assertFalse(RangeSet(data=[5, 10, 0, 5]).monotonic)
+ def test_parse_raw(self):
+ self.assertEqual(
+ RangeSet.parse_raw(RangeSet("0-9").to_string_raw()),
+ RangeSet("0-9"))
+ self.assertEqual(RangeSet.parse_raw(
+ RangeSet("2-10 12").to_string_raw()),
+ RangeSet("2-10 12"))
+ self.assertEqual(
+ RangeSet.parse_raw(RangeSet("11 2-10 12 1 0").to_string_raw()),
+ RangeSet("11 2-10 12 1 0"))
+
+ with self.assertRaises(AssertionError):
+ RangeSet.parse_raw("4,0,10")
+
def test_next_item(self):
self.assertEqual(
list(RangeSet("0-9").next_item()),
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
new file mode 100755
index 0000000..1dd3159
--- /dev/null
+++ b/tools/releasetools/validate_target_files.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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.
+
+"""
+Validate a given (signed) target_files.zip.
+
+It performs checks to ensure the integrity of the input zip.
+ - It verifies the file consistency between the ones in IMAGES/system.img (read
+ via IMAGES/system.map) and the ones under unpacked folder of SYSTEM/. The
+ same check also applies to the vendor image if present.
+"""
+
+import common
+import logging
+import os.path
+import sparse_img
+import sys
+
+
+def _GetImage(which, tmpdir):
+ assert which in ('system', 'vendor')
+
+ path = os.path.join(tmpdir, 'IMAGES', which + '.img')
+ mappath = os.path.join(tmpdir, 'IMAGES', which + '.map')
+
+ # Map file must exist (allowed to be empty).
+ assert os.path.exists(path) and os.path.exists(mappath)
+
+ clobbered_blocks = '0'
+ return sparse_img.SparseImage(path, mappath, clobbered_blocks)
+
+
+def ValidateFileConsistency(input_zip, input_tmp):
+ """Compare the files from image files and unpacked folders."""
+
+ def RoundUpTo4K(value):
+ rounded_up = value + 4095
+ return rounded_up - (rounded_up % 4096)
+
+ def CheckAllFiles(which):
+ logging.info('Checking %s image.', which)
+ image = _GetImage(which, input_tmp)
+ prefix = '/' + which
+ for entry in image.file_map:
+ if not entry.startswith(prefix):
+ continue
+
+ # Read the blocks that the file resides. Note that it will contain the
+ # bytes past the file length, which is expected to be padded with '\0's.
+ ranges = image.file_map[entry]
+ blocks_sha1 = image.RangeSha1(ranges)
+
+ # The filename under unpacked directory, such as SYSTEM/bin/sh.
+ unpacked_name = os.path.join(
+ input_tmp, which.upper(), entry[(len(prefix) + 1):])
+ with open(unpacked_name) as f:
+ file_data = f.read()
+ file_size = len(file_data)
+ file_size_rounded_up = RoundUpTo4K(file_size)
+ file_data += '\0' * (file_size_rounded_up - file_size)
+ file_sha1 = common.File(entry, file_data).sha1
+
+ assert blocks_sha1 == file_sha1, \
+ 'file: %s, range: %s, blocks_sha1: %s, file_sha1: %s' % (
+ entry, ranges, blocks_sha1, file_sha1)
+
+ logging.info('Validating file consistency.')
+
+ # Verify IMAGES/system.img.
+ CheckAllFiles('system')
+
+ # Verify IMAGES/vendor.img if applicable.
+ if 'VENDOR/' in input_zip.namelist():
+ CheckAllFiles('vendor')
+
+ # Not checking IMAGES/system_other.img since it doesn't have the map file.
+
+
+def main(argv):
+ def option_handler():
+ return True
+
+ args = common.ParseOptions(
+ argv, __doc__, extra_opts="",
+ extra_long_opts=[],
+ extra_option_handler=option_handler)
+
+ if len(args) != 1:
+ common.Usage(__doc__)
+ sys.exit(1)
+
+ logging_format = '%(asctime)s - %(filename)s - %(levelname)-8s: %(message)s'
+ date_format = '%Y/%m/%d %H:%M:%S'
+ logging.basicConfig(level=logging.INFO, format=logging_format,
+ datefmt=date_format)
+
+ logging.info("Unzipping the input target_files.zip: %s", args[0])
+ input_tmp, input_zip = common.UnzipTemp(args[0])
+
+ ValidateFileConsistency(input_zip, input_tmp)
+
+ # TODO: Check if the OTA keys have been properly updated (the ones on /system,
+ # in recovery image).
+
+ # TODO(b/35411009): Verify the contents in /system/bin/install-recovery.sh.
+
+ logging.info("Done.")
+
+
+if __name__ == '__main__':
+ try:
+ main(sys.argv[1:])
+ finally:
+ common.Cleanup()
diff --git a/tools/rgb2565/Android.mk b/tools/rgb2565/Android.mk
deleted file mode 100644
index 189584d..0000000
--- a/tools/rgb2565/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-# Android.mk for rgb2565
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-# rgb2565 host tool
-# =========================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := to565.c
-
-LOCAL_CFLAGS += -O2 -Wall -Wno-unused-parameter
-LOCAL_MODULE := rgb2565
-
-include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/rgb2565/to565.c b/tools/rgb2565/to565.c
deleted file mode 100644
index abf9cdb..0000000
--- a/tools/rgb2565/to565.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#define to565(r,g,b) \
- ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
-
-#define from565_r(x) ((((x) >> 11) & 0x1f) * 255 / 31)
-#define from565_g(x) ((((x) >> 5) & 0x3f) * 255 / 63)
-#define from565_b(x) (((x) & 0x1f) * 255 / 31)
-
-void to_565_raw(void)
-{
- unsigned char in[3];
- unsigned short out;
-
- while(read(0, in, 3) == 3) {
- out = to565(in[0],in[1],in[2]);
- write(1, &out, 2);
- }
- return;
-}
-
-void to_565_raw_dither(int width)
-{
- unsigned char in[3];
- unsigned short out;
- int i = 0;
- int e;
-
- int* error = malloc((width+2) * 3 * sizeof(int));
- int* next_error = malloc((width+2) * 3 * sizeof(int));
- memset(error, 0, (width+2) * 3 * sizeof(int));
- memset(next_error, 0, (width+2) * 3 * sizeof(int));
- error += 3; // array goes from [-3..((width+1)*3+2)]
- next_error += 3;
-
- while(read(0, in, 3) == 3) {
- int r = in[0] + error[i*3+0];
- int rb = (r < 0) ? 0 : ((r > 255) ? 255 : r);
-
- int g = in[1] + error[i*3+1];
- int gb = (g < 0) ? 0 : ((g > 255) ? 255 : g);
-
- int b = in[2] + error[i*3+2];
- int bb = (b < 0) ? 0 : ((b > 255) ? 255 : b);
-
- out = to565(rb, gb, bb);
- write(1, &out, 2);
-
-#define apply_error(ch) { \
- next_error[(i-1)*3+ch] += e * 3 / 16; \
- next_error[(i)*3+ch] += e * 5 / 16; \
- next_error[(i+1)*3+ch] += e * 1 / 16; \
- error[(i+1)*3+ch] += e - ((e*1/16) + (e*3/16) + (e*5/16)); \
- }
-
- e = r - from565_r(out);
- apply_error(0);
-
- e = g - from565_g(out);
- apply_error(1);
-
- e = b - from565_b(out);
- apply_error(2);
-
-#undef apply_error
-
- ++i;
- if (i == width) {
- // error <- next_error; next_error <- 0
- int* temp = error; error = next_error; next_error = temp;
- memset(next_error, 0, (width+1) * 3 * sizeof(int));
- i = 0;
- }
- }
-
- free(error-3);
- free(next_error-3);
-
- return;
-}
-
-void to_565_rle(void)
-{
- unsigned char in[3];
- unsigned short last, color, count;
- unsigned total = 0;
- count = 0;
-
- while(read(0, in, 3) == 3) {
- color = to565(in[0],in[1],in[2]);
- if (count) {
- if ((color == last) && (count != 65535)) {
- count++;
- continue;
- } else {
- write(1, &count, 2);
- write(1, &last, 2);
- total += count;
- }
- }
- last = color;
- count = 1;
- }
- if (count) {
- write(1, &count, 2);
- write(1, &last, 2);
- total += count;
- }
- fprintf(stderr,"%d pixels\n",total);
-}
-
-int main(int argc, char **argv)
-{
- if ((argc == 2) && (!strcmp(argv[1],"-rle"))) {
- to_565_rle();
- } else {
- if (argc > 2 && (!strcmp(argv[1], "-w"))) {
- to_565_raw_dither(atoi(argv[2]));
- } else {
- to_565_raw();
- }
- }
- return 0;
-}
diff --git a/tools/signapk/Android.mk b/tools/signapk/Android.mk
index ac217c7..051a51d 100644
--- a/tools/signapk/Android.mk
+++ b/tools/signapk/Android.mk
@@ -21,12 +21,15 @@
LOCAL_MODULE := signapk
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAR_MANIFEST := SignApk.mf
-LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host bouncycastle-bcpkix-host conscrypt-host
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ apksig \
+ bouncycastle-host \
+ bouncycastle-bcpkix-host \
+ conscrypt-host
LOCAL_REQUIRED_MODULES := libconscrypt_openjdk_jni
include $(BUILD_HOST_JAVA_LIBRARY)
ifeq ($(TARGET_BUILD_APPS),)
-ifeq ($(BRILLO),)
# The post-build signing tools need signapk.jar and its shared libraries,
# but we don't need this if we're just doing unbundled apps.
my_dist_files := $(LOCAL_INSTALLED_MODULE) \
@@ -35,4 +38,3 @@
$(call dist-for-goals,droidcore,$(my_dist_files))
my_dist_files :=
endif
-endif
diff --git a/tools/signapk/src/com/android/signapk/ApkSignerV2.java b/tools/signapk/src/com/android/signapk/ApkSignerV2.java
deleted file mode 100644
index 46cd11e..0000000
--- a/tools/signapk/src/com/android/signapk/ApkSignerV2.java
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.signapk;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.DigestException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.MGF1ParameterSpec;
-import java.security.spec.PSSParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * APK Signature Scheme v2 signer.
- *
- * <p>APK Signature Scheme v2 is a whole-file signature scheme which aims to protect every single
- * bit of the APK, as opposed to the JAR Signature Scheme which protects only the names and
- * uncompressed contents of ZIP entries.
- */
-public abstract class ApkSignerV2 {
- /*
- * The two main goals of APK Signature Scheme v2 are:
- * 1. Detect any unauthorized modifications to the APK. This is achieved by making the signature
- * cover every byte of the APK being signed.
- * 2. Enable much faster signature and integrity verification. This is achieved by requiring
- * only a minimal amount of APK parsing before the signature is verified, thus completely
- * bypassing ZIP entry decompression and by making integrity verification parallelizable by
- * employing a hash tree.
- *
- * The generated signature block is wrapped into an APK Signing Block and inserted into the
- * original APK immediately before the start of ZIP Central Directory. This is to ensure that
- * JAR and ZIP parsers continue to work on the signed APK. The APK Signing Block is designed for
- * extensibility. For example, a future signature scheme could insert its signatures there as
- * well. The contract of the APK Signing Block is that all contents outside of the block must be
- * protected by signatures inside the block.
- */
-
- public static final int SIGNATURE_RSA_PSS_WITH_SHA256 = 0x0101;
- public static final int SIGNATURE_RSA_PSS_WITH_SHA512 = 0x0102;
- public static final int SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256 = 0x0103;
- public static final int SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512 = 0x0104;
- public static final int SIGNATURE_ECDSA_WITH_SHA256 = 0x0201;
- public static final int SIGNATURE_ECDSA_WITH_SHA512 = 0x0202;
- public static final int SIGNATURE_DSA_WITH_SHA256 = 0x0301;
- public static final int SIGNATURE_DSA_WITH_SHA512 = 0x0302;
-
- /**
- * {@code .SF} file header section attribute indicating that the APK is signed not just with
- * JAR signature scheme but also with APK Signature Scheme v2 or newer. This attribute
- * facilitates v2 signature stripping detection.
- *
- * <p>The attribute contains a comma-separated set of signature scheme IDs.
- */
- public static final String SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME = "X-Android-APK-Signed";
- public static final String SF_ATTRIBUTE_ANDROID_APK_SIGNED_VALUE = "2";
-
- private static final int CONTENT_DIGEST_CHUNKED_SHA256 = 0;
- private static final int CONTENT_DIGEST_CHUNKED_SHA512 = 1;
-
- private static final int CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES = 1024 * 1024;
-
- private static final byte[] APK_SIGNING_BLOCK_MAGIC =
- new byte[] {
- 0x41, 0x50, 0x4b, 0x20, 0x53, 0x69, 0x67, 0x20,
- 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x34, 0x32,
- };
- private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;
-
- private ApkSignerV2() {}
-
- /**
- * Signer configuration.
- */
- public static final class SignerConfig {
- /** Private key. */
- public PrivateKey privateKey;
-
- /**
- * Certificates, with the first certificate containing the public key corresponding to
- * {@link #privateKey}.
- */
- public List<X509Certificate> certificates;
-
- /**
- * List of signature algorithms with which to sign (see {@code SIGNATURE_...} constants).
- */
- public List<Integer> signatureAlgorithms;
- }
-
- /**
- * Signs the provided APK using APK Signature Scheme v2 and returns the signed APK as a list of
- * consecutive chunks.
- *
- * <p>NOTE: To enable APK signature verifier to detect v2 signature stripping, header sections
- * of META-INF/*.SF files of APK being signed must contain the
- * {@code X-Android-APK-Signed: true} attribute.
- *
- * @param inputApk contents of the APK to be signed. The APK starts at the current position
- * of the buffer and ends at the limit of the buffer.
- * @param signerConfigs signer configurations, one for each signer.
- *
- * @throws ApkParseException if the APK cannot be parsed.
- * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or
- * cannot be used in general.
- * @throws SignatureException if an error occurs when computing digests of generating
- * signatures.
- */
- public static ByteBuffer[] sign(
- ByteBuffer inputApk,
- List<SignerConfig> signerConfigs)
- throws ApkParseException, InvalidKeyException, SignatureException {
- // Slice/create a view in the inputApk to make sure that:
- // 1. inputApk is what's between position and limit of the original inputApk, and
- // 2. changes to position, limit, and byte order are not reflected in the original.
- ByteBuffer originalInputApk = inputApk;
- inputApk = originalInputApk.slice();
- inputApk.order(ByteOrder.LITTLE_ENDIAN);
-
- // Locate ZIP End of Central Directory (EoCD), Central Directory, and check that Central
- // Directory is immediately followed by the ZIP End of Central Directory.
- int eocdOffset = ZipUtils.findZipEndOfCentralDirectoryRecord(inputApk);
- if (eocdOffset == -1) {
- throw new ApkParseException("Failed to locate ZIP End of Central Directory");
- }
- if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(inputApk, eocdOffset)) {
- throw new ApkParseException("ZIP64 format not supported");
- }
- inputApk.position(eocdOffset);
- long centralDirSizeLong = ZipUtils.getZipEocdCentralDirectorySizeBytes(inputApk);
- if (centralDirSizeLong > Integer.MAX_VALUE) {
- throw new ApkParseException(
- "ZIP Central Directory size out of range: " + centralDirSizeLong);
- }
- int centralDirSize = (int) centralDirSizeLong;
- long centralDirOffsetLong = ZipUtils.getZipEocdCentralDirectoryOffset(inputApk);
- if (centralDirOffsetLong > Integer.MAX_VALUE) {
- throw new ApkParseException(
- "ZIP Central Directory offset in file out of range: " + centralDirOffsetLong);
- }
- int centralDirOffset = (int) centralDirOffsetLong;
- int expectedEocdOffset = centralDirOffset + centralDirSize;
- if (expectedEocdOffset < centralDirOffset) {
- throw new ApkParseException(
- "ZIP Central Directory extent too large. Offset: " + centralDirOffset
- + ", size: " + centralDirSize);
- }
- if (eocdOffset != expectedEocdOffset) {
- throw new ApkParseException(
- "ZIP Central Directory not immeiately followed by ZIP End of"
- + " Central Directory. CD end: " + expectedEocdOffset
- + ", EoCD start: " + eocdOffset);
- }
-
- // Create ByteBuffers holding the contents of everything before ZIP Central Directory,
- // ZIP Central Directory, and ZIP End of Central Directory.
- inputApk.clear();
- ByteBuffer beforeCentralDir = getByteBuffer(inputApk, centralDirOffset);
- ByteBuffer centralDir = getByteBuffer(inputApk, eocdOffset - centralDirOffset);
- // Create a copy of End of Central Directory because we'll need modify its contents later.
- byte[] eocdBytes = new byte[inputApk.remaining()];
- inputApk.get(eocdBytes);
- ByteBuffer eocd = ByteBuffer.wrap(eocdBytes);
- eocd.order(inputApk.order());
-
- // Figure which which digests to use for APK contents.
- Set<Integer> contentDigestAlgorithms = new HashSet<>();
- for (SignerConfig signerConfig : signerConfigs) {
- for (int signatureAlgorithm : signerConfig.signatureAlgorithms) {
- contentDigestAlgorithms.add(
- getSignatureAlgorithmContentDigestAlgorithm(signatureAlgorithm));
- }
- }
-
- // Compute digests of APK contents.
- Map<Integer, byte[]> contentDigests; // digest algorithm ID -> digest
- try {
- contentDigests =
- computeContentDigests(
- contentDigestAlgorithms,
- new ByteBuffer[] {beforeCentralDir, centralDir, eocd});
- } catch (DigestException e) {
- throw new SignatureException("Failed to compute digests of APK", e);
- }
-
- // Sign the digests and wrap the signatures and signer info into an APK Signing Block.
- ByteBuffer apkSigningBlock =
- ByteBuffer.wrap(generateApkSigningBlock(signerConfigs, contentDigests));
-
- // Update Central Directory Offset in End of Central Directory Record. Central Directory
- // follows the APK Signing Block and thus is shifted by the size of the APK Signing Block.
- centralDirOffset += apkSigningBlock.remaining();
- eocd.clear();
- ZipUtils.setZipEocdCentralDirectoryOffset(eocd, centralDirOffset);
-
- // Follow the Java NIO pattern for ByteBuffer whose contents have been consumed.
- originalInputApk.position(originalInputApk.limit());
-
- // Reset positions (to 0) and limits (to capacity) in the ByteBuffers below to follow the
- // Java NIO pattern for ByteBuffers which are ready for their contents to be read by caller.
- // Contrary to the name, this does not clear the contents of these ByteBuffer.
- beforeCentralDir.clear();
- centralDir.clear();
- eocd.clear();
-
- // Insert APK Signing Block immediately before the ZIP Central Directory.
- return new ByteBuffer[] {
- beforeCentralDir,
- apkSigningBlock,
- centralDir,
- eocd,
- };
- }
-
- private static Map<Integer, byte[]> computeContentDigests(
- Set<Integer> digestAlgorithms,
- ByteBuffer[] contents) throws DigestException {
- // For each digest algorithm the result is computed as follows:
- // 1. Each segment of contents is split into consecutive chunks of 1 MB in size.
- // The final chunk will be shorter iff the length of segment is not a multiple of 1 MB.
- // No chunks are produced for empty (zero length) segments.
- // 2. The digest of each chunk is computed over the concatenation of byte 0xa5, the chunk's
- // length in bytes (uint32 little-endian) and the chunk's contents.
- // 3. The output digest is computed over the concatenation of the byte 0x5a, the number of
- // chunks (uint32 little-endian) and the concatenation of digests of chunks of all
- // segments in-order.
-
- int chunkCount = 0;
- for (ByteBuffer input : contents) {
- chunkCount += getChunkCount(input.remaining(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
- }
-
- final Map<Integer, byte[]> digestsOfChunks = new HashMap<>(digestAlgorithms.size());
- for (int digestAlgorithm : digestAlgorithms) {
- int digestOutputSizeBytes = getContentDigestAlgorithmOutputSizeBytes(digestAlgorithm);
- byte[] concatenationOfChunkCountAndChunkDigests =
- new byte[5 + chunkCount * digestOutputSizeBytes];
- concatenationOfChunkCountAndChunkDigests[0] = 0x5a;
- setUnsignedInt32LittleEngian(
- chunkCount, concatenationOfChunkCountAndChunkDigests, 1);
- digestsOfChunks.put(digestAlgorithm, concatenationOfChunkCountAndChunkDigests);
- }
-
- int chunkIndex = 0;
- byte[] chunkContentPrefix = new byte[5];
- chunkContentPrefix[0] = (byte) 0xa5;
- // Optimization opportunity: digests of chunks can be computed in parallel.
- for (ByteBuffer input : contents) {
- while (input.hasRemaining()) {
- int chunkSize =
- Math.min(input.remaining(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
- final ByteBuffer chunk = getByteBuffer(input, chunkSize);
- for (int digestAlgorithm : digestAlgorithms) {
- String jcaAlgorithmName =
- getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm);
- MessageDigest md;
- try {
- md = MessageDigest.getInstance(jcaAlgorithmName);
- } catch (NoSuchAlgorithmException e) {
- throw new DigestException(
- jcaAlgorithmName + " MessageDigest not supported", e);
- }
- // Reset position to 0 and limit to capacity. Position would've been modified
- // by the preceding iteration of this loop. NOTE: Contrary to the method name,
- // this does not modify the contents of the chunk.
- chunk.clear();
- setUnsignedInt32LittleEngian(chunk.remaining(), chunkContentPrefix, 1);
- md.update(chunkContentPrefix);
- md.update(chunk);
- byte[] concatenationOfChunkCountAndChunkDigests =
- digestsOfChunks.get(digestAlgorithm);
- int expectedDigestSizeBytes =
- getContentDigestAlgorithmOutputSizeBytes(digestAlgorithm);
- int actualDigestSizeBytes =
- md.digest(
- concatenationOfChunkCountAndChunkDigests,
- 5 + chunkIndex * expectedDigestSizeBytes,
- expectedDigestSizeBytes);
- if (actualDigestSizeBytes != expectedDigestSizeBytes) {
- throw new DigestException(
- "Unexpected output size of " + md.getAlgorithm()
- + " digest: " + actualDigestSizeBytes);
- }
- }
- chunkIndex++;
- }
- }
-
- Map<Integer, byte[]> result = new HashMap<>(digestAlgorithms.size());
- for (Map.Entry<Integer, byte[]> entry : digestsOfChunks.entrySet()) {
- int digestAlgorithm = entry.getKey();
- byte[] concatenationOfChunkCountAndChunkDigests = entry.getValue();
- String jcaAlgorithmName = getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm);
- MessageDigest md;
- try {
- md = MessageDigest.getInstance(jcaAlgorithmName);
- } catch (NoSuchAlgorithmException e) {
- throw new DigestException(jcaAlgorithmName + " MessageDigest not supported", e);
- }
- result.put(digestAlgorithm, md.digest(concatenationOfChunkCountAndChunkDigests));
- }
- return result;
- }
-
- private static final int getChunkCount(int inputSize, int chunkSize) {
- return (inputSize + chunkSize - 1) / chunkSize;
- }
-
- private static void setUnsignedInt32LittleEngian(int value, byte[] result, int offset) {
- result[offset] = (byte) (value & 0xff);
- result[offset + 1] = (byte) ((value >> 8) & 0xff);
- result[offset + 2] = (byte) ((value >> 16) & 0xff);
- result[offset + 3] = (byte) ((value >> 24) & 0xff);
- }
-
- private static byte[] generateApkSigningBlock(
- List<SignerConfig> signerConfigs,
- Map<Integer, byte[]> contentDigests) throws InvalidKeyException, SignatureException {
- byte[] apkSignatureSchemeV2Block =
- generateApkSignatureSchemeV2Block(signerConfigs, contentDigests);
- return generateApkSigningBlock(apkSignatureSchemeV2Block);
- }
-
- private static byte[] generateApkSigningBlock(byte[] apkSignatureSchemeV2Block) {
- // FORMAT:
- // uint64: size (excluding this field)
- // repeated ID-value pairs:
- // uint64: size (excluding this field)
- // uint32: ID
- // (size - 4) bytes: value
- // uint64: size (same as the one above)
- // uint128: magic
-
- int resultSize =
- 8 // size
- + 8 + 4 + apkSignatureSchemeV2Block.length // v2Block as ID-value pair
- + 8 // size
- + 16 // magic
- ;
- ByteBuffer result = ByteBuffer.allocate(resultSize);
- result.order(ByteOrder.LITTLE_ENDIAN);
- long blockSizeFieldValue = resultSize - 8;
- result.putLong(blockSizeFieldValue);
-
- long pairSizeFieldValue = 4 + apkSignatureSchemeV2Block.length;
- result.putLong(pairSizeFieldValue);
- result.putInt(APK_SIGNATURE_SCHEME_V2_BLOCK_ID);
- result.put(apkSignatureSchemeV2Block);
-
- result.putLong(blockSizeFieldValue);
- result.put(APK_SIGNING_BLOCK_MAGIC);
-
- return result.array();
- }
-
- private static byte[] generateApkSignatureSchemeV2Block(
- List<SignerConfig> signerConfigs,
- Map<Integer, byte[]> contentDigests) throws InvalidKeyException, SignatureException {
- // FORMAT:
- // * length-prefixed sequence of length-prefixed signer blocks.
-
- List<byte[]> signerBlocks = new ArrayList<>(signerConfigs.size());
- int signerNumber = 0;
- for (SignerConfig signerConfig : signerConfigs) {
- signerNumber++;
- byte[] signerBlock;
- try {
- signerBlock = generateSignerBlock(signerConfig, contentDigests);
- } catch (InvalidKeyException e) {
- throw new InvalidKeyException("Signer #" + signerNumber + " failed", e);
- } catch (SignatureException e) {
- throw new SignatureException("Signer #" + signerNumber + " failed", e);
- }
- signerBlocks.add(signerBlock);
- }
-
- return encodeAsSequenceOfLengthPrefixedElements(
- new byte[][] {
- encodeAsSequenceOfLengthPrefixedElements(signerBlocks),
- });
- }
-
- private static byte[] generateSignerBlock(
- SignerConfig signerConfig,
- Map<Integer, byte[]> contentDigests) throws InvalidKeyException, SignatureException {
- if (signerConfig.certificates.isEmpty()) {
- throw new SignatureException("No certificates configured for signer");
- }
- PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey();
-
- byte[] encodedPublicKey = encodePublicKey(publicKey);
-
- V2SignatureSchemeBlock.SignedData signedData = new V2SignatureSchemeBlock.SignedData();
- try {
- signedData.certificates = encodeCertificates(signerConfig.certificates);
- } catch (CertificateEncodingException e) {
- throw new SignatureException("Failed to encode certificates", e);
- }
-
- List<Pair<Integer, byte[]>> digests =
- new ArrayList<>(signerConfig.signatureAlgorithms.size());
- for (int signatureAlgorithm : signerConfig.signatureAlgorithms) {
- int contentDigestAlgorithm =
- getSignatureAlgorithmContentDigestAlgorithm(signatureAlgorithm);
- byte[] contentDigest = contentDigests.get(contentDigestAlgorithm);
- if (contentDigest == null) {
- throw new RuntimeException(
- getContentDigestAlgorithmJcaDigestAlgorithm(contentDigestAlgorithm)
- + " content digest for "
- + getSignatureAlgorithmJcaSignatureAlgorithm(signatureAlgorithm)
- + " not computed");
- }
- digests.add(Pair.create(signatureAlgorithm, contentDigest));
- }
- signedData.digests = digests;
-
- V2SignatureSchemeBlock.Signer signer = new V2SignatureSchemeBlock.Signer();
- // FORMAT:
- // * length-prefixed sequence of length-prefixed digests:
- // * uint32: signature algorithm ID
- // * length-prefixed bytes: digest of contents
- // * length-prefixed sequence of certificates:
- // * length-prefixed bytes: X.509 certificate (ASN.1 DER encoded).
- // * length-prefixed sequence of length-prefixed additional attributes:
- // * uint32: ID
- // * (length - 4) bytes: value
- signer.signedData = encodeAsSequenceOfLengthPrefixedElements(new byte[][] {
- encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(signedData.digests),
- encodeAsSequenceOfLengthPrefixedElements(signedData.certificates),
- // additional attributes
- new byte[0],
- });
- signer.publicKey = encodedPublicKey;
- signer.signatures = new ArrayList<>();
- for (int signatureAlgorithm : signerConfig.signatureAlgorithms) {
- Pair<String, ? extends AlgorithmParameterSpec> signatureParams =
- getSignatureAlgorithmJcaSignatureAlgorithm(signatureAlgorithm);
- String jcaSignatureAlgorithm = signatureParams.getFirst();
- AlgorithmParameterSpec jcaSignatureAlgorithmParams = signatureParams.getSecond();
- byte[] signatureBytes;
- try {
- Signature signature = Signature.getInstance(jcaSignatureAlgorithm);
- signature.initSign(signerConfig.privateKey);
- if (jcaSignatureAlgorithmParams != null) {
- signature.setParameter(jcaSignatureAlgorithmParams);
- }
- signature.update(signer.signedData);
- signatureBytes = signature.sign();
- } catch (InvalidKeyException e) {
- throw new InvalidKeyException("Failed sign using " + jcaSignatureAlgorithm, e);
- } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
- | SignatureException e) {
- throw new SignatureException("Failed sign using " + jcaSignatureAlgorithm, e);
- }
-
- try {
- Signature signature = Signature.getInstance(jcaSignatureAlgorithm);
- signature.initVerify(publicKey);
- if (jcaSignatureAlgorithmParams != null) {
- signature.setParameter(jcaSignatureAlgorithmParams);
- }
- signature.update(signer.signedData);
- if (!signature.verify(signatureBytes)) {
- throw new SignatureException("Signature did not verify");
- }
- } catch (InvalidKeyException e) {
- throw new InvalidKeyException("Failed to verify generated " + jcaSignatureAlgorithm
- + " signature using public key from certificate", e);
- } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
- | SignatureException e) {
- throw new SignatureException("Failed to verify generated " + jcaSignatureAlgorithm
- + " signature using public key from certificate", e);
- }
-
- signer.signatures.add(Pair.create(signatureAlgorithm, signatureBytes));
- }
-
- // FORMAT:
- // * length-prefixed signed data
- // * length-prefixed sequence of length-prefixed signatures:
- // * uint32: signature algorithm ID
- // * length-prefixed bytes: signature of signed data
- // * length-prefixed bytes: public key (X.509 SubjectPublicKeyInfo, ASN.1 DER encoded)
- return encodeAsSequenceOfLengthPrefixedElements(
- new byte[][] {
- signer.signedData,
- encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(
- signer.signatures),
- signer.publicKey,
- });
- }
-
- private static final class V2SignatureSchemeBlock {
- private static final class Signer {
- public byte[] signedData;
- public List<Pair<Integer, byte[]>> signatures;
- public byte[] publicKey;
- }
-
- private static final class SignedData {
- public List<Pair<Integer, byte[]>> digests;
- public List<byte[]> certificates;
- }
- }
-
- private static byte[] encodePublicKey(PublicKey publicKey) throws InvalidKeyException {
- byte[] encodedPublicKey = null;
- if ("X.509".equals(publicKey.getFormat())) {
- encodedPublicKey = publicKey.getEncoded();
- }
- if (encodedPublicKey == null) {
- try {
- encodedPublicKey =
- KeyFactory.getInstance(publicKey.getAlgorithm())
- .getKeySpec(publicKey, X509EncodedKeySpec.class)
- .getEncoded();
- } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
- throw new InvalidKeyException(
- "Failed to obtain X.509 encoded form of public key " + publicKey
- + " of class " + publicKey.getClass().getName(),
- e);
- }
- }
- if ((encodedPublicKey == null) || (encodedPublicKey.length == 0)) {
- throw new InvalidKeyException(
- "Failed to obtain X.509 encoded form of public key " + publicKey
- + " of class " + publicKey.getClass().getName());
- }
- return encodedPublicKey;
- }
-
- public static List<byte[]> encodeCertificates(List<X509Certificate> certificates)
- throws CertificateEncodingException {
- List<byte[]> result = new ArrayList<>();
- for (X509Certificate certificate : certificates) {
- result.add(certificate.getEncoded());
- }
- return result;
- }
-
- private static byte[] encodeAsSequenceOfLengthPrefixedElements(List<byte[]> sequence) {
- return encodeAsSequenceOfLengthPrefixedElements(
- sequence.toArray(new byte[sequence.size()][]));
- }
-
- private static byte[] encodeAsSequenceOfLengthPrefixedElements(byte[][] sequence) {
- int payloadSize = 0;
- for (byte[] element : sequence) {
- payloadSize += 4 + element.length;
- }
- ByteBuffer result = ByteBuffer.allocate(payloadSize);
- result.order(ByteOrder.LITTLE_ENDIAN);
- for (byte[] element : sequence) {
- result.putInt(element.length);
- result.put(element);
- }
- return result.array();
- }
-
- private static byte[] encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(
- List<Pair<Integer, byte[]>> sequence) {
- int resultSize = 0;
- for (Pair<Integer, byte[]> element : sequence) {
- resultSize += 12 + element.getSecond().length;
- }
- ByteBuffer result = ByteBuffer.allocate(resultSize);
- result.order(ByteOrder.LITTLE_ENDIAN);
- for (Pair<Integer, byte[]> element : sequence) {
- byte[] second = element.getSecond();
- result.putInt(8 + second.length);
- result.putInt(element.getFirst());
- result.putInt(second.length);
- result.put(second);
- }
- return result.array();
- }
-
- /**
- * Relative <em>get</em> method for reading {@code size} number of bytes from the current
- * position of this buffer.
- *
- * <p>This method reads the next {@code size} bytes at this buffer's current position,
- * returning them as a {@code ByteBuffer} with start set to 0, limit and capacity set to
- * {@code size}, byte order set to this buffer's byte order; and then increments the position by
- * {@code size}.
- */
- private static ByteBuffer getByteBuffer(ByteBuffer source, int size) {
- if (size < 0) {
- throw new IllegalArgumentException("size: " + size);
- }
- int originalLimit = source.limit();
- int position = source.position();
- int limit = position + size;
- if ((limit < position) || (limit > originalLimit)) {
- throw new BufferUnderflowException();
- }
- source.limit(limit);
- try {
- ByteBuffer result = source.slice();
- result.order(source.order());
- source.position(limit);
- return result;
- } finally {
- source.limit(originalLimit);
- }
- }
-
- private static Pair<String, ? extends AlgorithmParameterSpec>
- getSignatureAlgorithmJcaSignatureAlgorithm(int sigAlgorithm) {
- switch (sigAlgorithm) {
- case SIGNATURE_RSA_PSS_WITH_SHA256:
- return Pair.create(
- "SHA256withRSA/PSS",
- new PSSParameterSpec(
- "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 256 / 8, 1));
- case SIGNATURE_RSA_PSS_WITH_SHA512:
- return Pair.create(
- "SHA512withRSA/PSS",
- new PSSParameterSpec(
- "SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 512 / 8, 1));
- case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
- return Pair.create("SHA256withRSA", null);
- case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
- return Pair.create("SHA512withRSA", null);
- case SIGNATURE_ECDSA_WITH_SHA256:
- return Pair.create("SHA256withECDSA", null);
- case SIGNATURE_ECDSA_WITH_SHA512:
- return Pair.create("SHA512withECDSA", null);
- case SIGNATURE_DSA_WITH_SHA256:
- return Pair.create("SHA256withDSA", null);
- case SIGNATURE_DSA_WITH_SHA512:
- return Pair.create("SHA512withDSA", null);
- default:
- throw new IllegalArgumentException(
- "Unknown signature algorithm: 0x"
- + Long.toHexString(sigAlgorithm & 0xffffffff));
- }
- }
-
- private static int getSignatureAlgorithmContentDigestAlgorithm(int sigAlgorithm) {
- switch (sigAlgorithm) {
- case SIGNATURE_RSA_PSS_WITH_SHA256:
- case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
- case SIGNATURE_ECDSA_WITH_SHA256:
- case SIGNATURE_DSA_WITH_SHA256:
- return CONTENT_DIGEST_CHUNKED_SHA256;
- case SIGNATURE_RSA_PSS_WITH_SHA512:
- case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
- case SIGNATURE_ECDSA_WITH_SHA512:
- case SIGNATURE_DSA_WITH_SHA512:
- return CONTENT_DIGEST_CHUNKED_SHA512;
- default:
- throw new IllegalArgumentException(
- "Unknown signature algorithm: 0x"
- + Long.toHexString(sigAlgorithm & 0xffffffff));
- }
- }
-
- private static String getContentDigestAlgorithmJcaDigestAlgorithm(int digestAlgorithm) {
- switch (digestAlgorithm) {
- case CONTENT_DIGEST_CHUNKED_SHA256:
- return "SHA-256";
- case CONTENT_DIGEST_CHUNKED_SHA512:
- return "SHA-512";
- default:
- throw new IllegalArgumentException(
- "Unknown content digest algorthm: " + digestAlgorithm);
- }
- }
-
- private static int getContentDigestAlgorithmOutputSizeBytes(int digestAlgorithm) {
- switch (digestAlgorithm) {
- case CONTENT_DIGEST_CHUNKED_SHA256:
- return 256 / 8;
- case CONTENT_DIGEST_CHUNKED_SHA512:
- return 512 / 8;
- default:
- throw new IllegalArgumentException(
- "Unknown content digest algorthm: " + digestAlgorithm);
- }
- }
-
- /**
- * Indicates that APK file could not be parsed.
- */
- public static class ApkParseException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public ApkParseException(String message) {
- super(message);
- }
-
- public ApkParseException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-}
diff --git a/tools/signapk/src/com/android/signapk/Pair.java b/tools/signapk/src/com/android/signapk/Pair.java
deleted file mode 100644
index e4a6c92..0000000
--- a/tools/signapk/src/com/android/signapk/Pair.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.signapk;
-
-/**
- * Pair of two elements.
- */
-public final class Pair<A, B> {
- private final A mFirst;
- private final B mSecond;
-
- private Pair(A first, B second) {
- mFirst = first;
- mSecond = second;
- }
-
- public static <A, B> Pair<A, B> create(A first, B second) {
- return new Pair<A, B>(first, second);
- }
-
- public A getFirst() {
- return mFirst;
- }
-
- public B getSecond() {
- return mSecond;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((mFirst == null) ? 0 : mFirst.hashCode());
- result = prime * result + ((mSecond == null) ? 0 : mSecond.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- @SuppressWarnings("rawtypes")
- Pair other = (Pair) obj;
- if (mFirst == null) {
- if (other.mFirst != null) {
- return false;
- }
- } else if (!mFirst.equals(other.mFirst)) {
- return false;
- }
- if (mSecond == null) {
- if (other.mSecond != null) {
- return false;
- }
- } else if (!mSecond.equals(other.mSecond)) {
- return false;
- }
- return true;
- }
-}
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index ba84b42..3b00599 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -23,7 +23,6 @@
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
@@ -33,9 +32,16 @@
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
-import org.bouncycastle.util.encoders.Base64;
import org.conscrypt.OpenSSLProvider;
+import com.android.apksig.ApkSignerEngine;
+import com.android.apksig.DefaultApkSignerEngine;
+import com.android.apksig.apk.ApkUtils;
+import com.android.apksig.apk.MinSdkVersionException;
+import com.android.apksig.util.DataSink;
+import com.android.apksig.util.DataSources;
+import com.android.apksig.zip.ZipFormatException;
+
import java.io.Console;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@@ -49,18 +55,15 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.nio.ByteBuffer;
-import java.security.DigestOutputStream;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
-import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Provider;
-import java.security.PublicKey;
import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
@@ -70,18 +73,14 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
-import java.util.Iterator;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.TimeZone;
-import java.util.TreeMap;
-import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
import java.util.regex.Pattern;
+
import javax.crypto.Cipher;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.SecretKeyFactory;
@@ -111,39 +110,35 @@
* APK Signature Scheme v2.
*/
class SignApk {
- private static final String CERT_SF_NAME = "META-INF/CERT.SF";
- private static final String CERT_SIG_NAME = "META-INF/CERT.%s";
- private static final String CERT_SF_MULTI_NAME = "META-INF/CERT%d.SF";
- private static final String CERT_SIG_MULTI_NAME = "META-INF/CERT%d.%s";
-
private static final String OTACERT_NAME = "META-INF/com/android/otacert";
+ /**
+ * Extensible data block/field header ID used for storing information about alignment of
+ * uncompressed entries as well as for aligning the entries's data. See ZIP appnote.txt section
+ * 4.5 Extensible data fields.
+ */
+ private static final short ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID = (short) 0xd935;
+
+ /**
+ * Minimum size (in bytes) of the extensible data block/field used for alignment of uncompressed
+ * entries.
+ */
+ private static final short ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES = 6;
+
// bitmasks for which hash algorithms we need the manifest to include.
private static final int USE_SHA1 = 1;
private static final int USE_SHA256 = 2;
- /** Digest algorithm used when signing the APK using APK Signature Scheme v2. */
- private static final String APK_SIG_SCHEME_V2_DIGEST_ALGORITHM = "SHA-256";
-
/**
- * Minimum Android SDK API Level which accepts JAR signatures which use SHA-256. Older platform
- * versions accept only SHA-1 signatures.
+ * Returns the digest algorithm ID (one of {@code USE_SHA1} or {@code USE_SHA256}) to be used
+ * for signing an OTA update package using the private key corresponding to the provided
+ * certificate.
*/
- private static final int MIN_API_LEVEL_FOR_SHA256_JAR_SIGNATURES = 18;
-
- /**
- * Return one of USE_SHA1 or USE_SHA256 according to the signature
- * algorithm specified in the cert.
- */
- private static int getDigestAlgorithm(X509Certificate cert, int minSdkVersion) {
+ private static int getDigestAlgorithmForOta(X509Certificate cert) {
String sigAlg = cert.getSigAlgName().toUpperCase(Locale.US);
if ("SHA1WITHRSA".equals(sigAlg) || "MD5WITHRSA".equals(sigAlg)) {
// see "HISTORICAL NOTE" above.
- if (minSdkVersion < MIN_API_LEVEL_FOR_SHA256_JAR_SIGNATURES) {
- return USE_SHA1;
- } else {
- return USE_SHA256;
- }
+ return USE_SHA1;
} else if (sigAlg.startsWith("SHA256WITH")) {
return USE_SHA256;
} else {
@@ -152,28 +147,35 @@
}
}
- /** Returns the expected signature algorithm for this key type. */
- private static String getSignatureAlgorithm(X509Certificate cert, int minSdkVersion) {
- String keyType = cert.getPublicKey().getAlgorithm().toUpperCase(Locale.US);
- if ("RSA".equalsIgnoreCase(keyType)) {
- if ((minSdkVersion >= MIN_API_LEVEL_FOR_SHA256_JAR_SIGNATURES)
- || (getDigestAlgorithm(cert, minSdkVersion) == USE_SHA256)) {
- return "SHA256withRSA";
- } else {
- return "SHA1withRSA";
- }
- } else if ("EC".equalsIgnoreCase(keyType)) {
- return "SHA256withECDSA";
+ /**
+ * Returns the JCA {@link java.security.Signature} algorithm to be used for signing and OTA
+ * update package using the private key corresponding to the provided certificate and the
+ * provided digest algorithm (see {@code USE_SHA1} and {@code USE_SHA256} constants).
+ */
+ private static String getJcaSignatureAlgorithmForOta(
+ X509Certificate cert, int hash) {
+ String sigAlgDigestPrefix;
+ switch (hash) {
+ case USE_SHA1:
+ sigAlgDigestPrefix = "SHA1";
+ break;
+ case USE_SHA256:
+ sigAlgDigestPrefix = "SHA256";
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown hash ID: " + hash);
+ }
+
+ String keyAlgorithm = cert.getPublicKey().getAlgorithm();
+ if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
+ return sigAlgDigestPrefix + "withRSA";
+ } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
+ return sigAlgDigestPrefix + "withECDSA";
} else {
- throw new IllegalArgumentException("unsupported key type: " + keyType);
+ throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
}
}
- // Files matching this pattern are not copied to the output.
- private static Pattern stripPattern =
- Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA|EC)|com/android/otacert))|(" +
- Pattern.quote(JarFile.MANIFEST_NAME) + ")$");
-
private static X509Certificate readPublicKey(File file)
throws IOException, GeneralSecurityException {
FileInputStream input = new FileInputStream(file);
@@ -279,100 +281,16 @@
}
/**
- * Add the hash(es) of every file to the manifest, creating it if
- * necessary.
- */
- private static Manifest addDigestsToManifest(JarFile jar, int hashes)
- throws IOException, GeneralSecurityException {
- Manifest input = jar.getManifest();
- Manifest output = new Manifest();
- Attributes main = output.getMainAttributes();
- if (input != null) {
- main.putAll(input.getMainAttributes());
- } else {
- main.putValue("Manifest-Version", "1.0");
- main.putValue("Created-By", "1.0 (Android SignApk)");
- }
-
- MessageDigest md_sha1 = null;
- MessageDigest md_sha256 = null;
- if ((hashes & USE_SHA1) != 0) {
- md_sha1 = MessageDigest.getInstance("SHA1");
- }
- if ((hashes & USE_SHA256) != 0) {
- md_sha256 = MessageDigest.getInstance("SHA256");
- }
-
- byte[] buffer = new byte[4096];
- int num;
-
- // We sort the input entries by name, and add them to the
- // output manifest in sorted order. We expect that the output
- // map will be deterministic.
-
- TreeMap<String, JarEntry> byName = new TreeMap<String, JarEntry>();
-
- for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ) {
- JarEntry entry = e.nextElement();
- byName.put(entry.getName(), entry);
- }
-
- for (JarEntry entry: byName.values()) {
- String name = entry.getName();
- if (!entry.isDirectory() &&
- (stripPattern == null || !stripPattern.matcher(name).matches())) {
- InputStream data = jar.getInputStream(entry);
- while ((num = data.read(buffer)) > 0) {
- if (md_sha1 != null) md_sha1.update(buffer, 0, num);
- if (md_sha256 != null) md_sha256.update(buffer, 0, num);
- }
-
- Attributes attr = null;
- if (input != null) attr = input.getAttributes(name);
- attr = attr != null ? new Attributes(attr) : new Attributes();
- // Remove any previously computed digests from this entry's attributes.
- for (Iterator<Object> i = attr.keySet().iterator(); i.hasNext();) {
- Object key = i.next();
- if (!(key instanceof Attributes.Name)) {
- continue;
- }
- String attributeNameLowerCase =
- ((Attributes.Name) key).toString().toLowerCase(Locale.US);
- if (attributeNameLowerCase.endsWith("-digest")) {
- i.remove();
- }
- }
- // Add SHA-1 digest if requested
- if (md_sha1 != null) {
- attr.putValue("SHA1-Digest",
- new String(Base64.encode(md_sha1.digest()), "ASCII"));
- }
- // Add SHA-256 digest if requested
- if (md_sha256 != null) {
- attr.putValue("SHA-256-Digest",
- new String(Base64.encode(md_sha256.digest()), "ASCII"));
- }
- output.getEntries().put(name, attr);
- }
- }
-
- return output;
- }
-
- /**
* Add a copy of the public key to the archive; this should
* exactly match one of the files in
* /system/etc/security/otacerts.zip on the device. (The same
- * cert can be extracted from the CERT.RSA file but this is much
- * easier to get at.)
+ * cert can be extracted from the OTA update package's signature
+ * block but this is much easier to get at.)
*/
private static void addOtacert(JarOutputStream outputJar,
File publicKeyFile,
- long timestamp,
- Manifest manifest,
- int hash)
- throws IOException, GeneralSecurityException {
- MessageDigest md = MessageDigest.getInstance(hash == USE_SHA1 ? "SHA1" : "SHA256");
+ long timestamp)
+ throws IOException {
JarEntry je = new JarEntry(OTACERT_NAME);
je.setTime(timestamp);
@@ -382,108 +300,14 @@
int read;
while ((read = input.read(b)) != -1) {
outputJar.write(b, 0, read);
- md.update(b, 0, read);
}
input.close();
-
- Attributes attr = new Attributes();
- attr.putValue(hash == USE_SHA1 ? "SHA1-Digest" : "SHA-256-Digest",
- new String(Base64.encode(md.digest()), "ASCII"));
- manifest.getEntries().put(OTACERT_NAME, attr);
}
- /** Write to another stream and track how many bytes have been
- * written.
- */
- private static class CountOutputStream extends FilterOutputStream {
- private int mCount;
-
- public CountOutputStream(OutputStream out) {
- super(out);
- mCount = 0;
- }
-
- @Override
- public void write(int b) throws IOException {
- super.write(b);
- mCount++;
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- super.write(b, off, len);
- mCount += len;
- }
-
- public int size() {
- return mCount;
- }
- }
-
- /** Write a .SF file with a digest of the specified manifest. */
- private static void writeSignatureFile(Manifest manifest, OutputStream out,
- int hash, boolean additionallySignedUsingAnApkSignatureScheme)
- throws IOException, GeneralSecurityException {
- Manifest sf = new Manifest();
- Attributes main = sf.getMainAttributes();
- main.putValue("Signature-Version", "1.0");
- main.putValue("Created-By", "1.0 (Android SignApk)");
- if (additionallySignedUsingAnApkSignatureScheme) {
- // Add APK Signature Scheme v2 signature stripping protection.
- // This attribute indicates that this APK is supposed to have been signed using one or
- // more APK-specific signature schemes in addition to the standard JAR signature scheme
- // used by this code. APK signature verifier should reject the APK if it does not
- // contain a signature for the signature scheme the verifier prefers out of this set.
- main.putValue(
- ApkSignerV2.SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME,
- ApkSignerV2.SF_ATTRIBUTE_ANDROID_APK_SIGNED_VALUE);
- }
-
- MessageDigest md = MessageDigest.getInstance(
- hash == USE_SHA256 ? "SHA256" : "SHA1");
- PrintStream print = new PrintStream(
- new DigestOutputStream(new ByteArrayOutputStream(), md),
- true, "UTF-8");
-
- // Digest of the entire manifest
- manifest.write(print);
- print.flush();
- main.putValue(hash == USE_SHA256 ? "SHA-256-Digest-Manifest" : "SHA1-Digest-Manifest",
- new String(Base64.encode(md.digest()), "ASCII"));
-
- Map<String, Attributes> entries = manifest.getEntries();
- for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
- // Digest of the manifest stanza for this entry.
- print.print("Name: " + entry.getKey() + "\r\n");
- for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
- print.print(att.getKey() + ": " + att.getValue() + "\r\n");
- }
- print.print("\r\n");
- print.flush();
-
- Attributes sfAttr = new Attributes();
- sfAttr.putValue(hash == USE_SHA256 ? "SHA-256-Digest" : "SHA1-Digest",
- new String(Base64.encode(md.digest()), "ASCII"));
- sf.getEntries().put(entry.getKey(), sfAttr);
- }
-
- CountOutputStream cout = new CountOutputStream(out);
- sf.write(cout);
-
- // A bug in the java.util.jar implementation of Android platforms
- // up to version 1.6 will cause a spurious IOException to be thrown
- // if the length of the signature file is a multiple of 1024 bytes.
- // As a workaround, add an extra CRLF in this case.
- if ((cout.size() % 1024) == 0) {
- cout.write('\r');
- cout.write('\n');
- }
- }
-
/** Sign data and write the digital signature to 'out'. */
private static void writeSignatureBlock(
- CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey, int minSdkVersion,
+ CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey, int hash,
OutputStream out)
throws IOException,
CertificateEncodingException,
@@ -495,7 +319,8 @@
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner signer =
- new JcaContentSignerBuilder(getSignatureAlgorithm(publicKey, minSdkVersion))
+ new JcaContentSignerBuilder(
+ getJcaSignatureAlgorithmForOta(publicKey, hash))
.build(privateKey);
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
@@ -513,18 +338,58 @@
}
/**
- * Copy all the files in a manifest from input to output. We set
- * the modification times in the output to a fixed time, so as to
- * reduce variation in the output file and make incremental OTAs
- * more efficient.
+ * Adds ZIP entries which represent the v1 signature (JAR signature scheme).
*/
- private static void copyFiles(Manifest manifest, JarFile in, JarOutputStream out,
- long timestamp, int defaultAlignment) throws IOException {
+ private static void addV1Signature(
+ ApkSignerEngine apkSigner,
+ ApkSignerEngine.OutputJarSignatureRequest v1Signature,
+ JarOutputStream out,
+ long timestamp) throws IOException {
+ for (ApkSignerEngine.OutputJarSignatureRequest.JarEntry entry
+ : v1Signature.getAdditionalJarEntries()) {
+ String entryName = entry.getName();
+ JarEntry outEntry = new JarEntry(entryName);
+ outEntry.setTime(timestamp);
+ out.putNextEntry(outEntry);
+ byte[] entryData = entry.getData();
+ out.write(entryData);
+ ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+ apkSigner.outputJarEntry(entryName);
+ if (inspectEntryRequest != null) {
+ inspectEntryRequest.getDataSink().consume(entryData, 0, entryData.length);
+ inspectEntryRequest.done();
+ }
+ }
+ }
+
+ /**
+ * Copy all JAR entries from input to output. We set the modification times in the output to a
+ * fixed time, so as to reduce variation in the output file and make incremental OTAs more
+ * efficient.
+ */
+ private static void copyFiles(
+ JarFile in,
+ Pattern ignoredFilenamePattern,
+ ApkSignerEngine apkSigner,
+ JarOutputStream out,
+ long timestamp,
+ int defaultAlignment) throws IOException {
byte[] buffer = new byte[4096];
int num;
- Map<String, Attributes> entries = manifest.getEntries();
- ArrayList<String> names = new ArrayList<String>(entries.keySet());
+ ArrayList<String> names = new ArrayList<String>();
+ for (Enumeration<JarEntry> e = in.entries(); e.hasMoreElements();) {
+ JarEntry entry = e.nextElement();
+ if (entry.isDirectory()) {
+ continue;
+ }
+ String entryName = entry.getName();
+ if ((ignoredFilenamePattern != null)
+ && (ignoredFilenamePattern.matcher(entryName).matches())) {
+ continue;
+ }
+ names.add(entryName);
+ }
Collections.sort(names);
boolean firstEntry = true;
@@ -537,12 +402,21 @@
// the start of the file and makes it easier to do alignment
// on them (since only stored entries are aligned).
+ List<String> remainingNames = new ArrayList<>(names.size());
for (String name : names) {
JarEntry inEntry = in.getJarEntry(name);
- JarEntry outEntry = null;
- if (inEntry.getMethod() != JarEntry.STORED) continue;
+ if (inEntry.getMethod() != JarEntry.STORED) {
+ // Defer outputting this entry until we're ready to output compressed entries.
+ remainingNames.add(name);
+ continue;
+ }
+
+ if (!shouldOutputApkEntry(apkSigner, in, inEntry, buffer)) {
+ continue;
+ }
+
// Preserve the STORED method of the input entry.
- outEntry = new JarEntry(inEntry);
+ JarEntry outEntry = new JarEntry(inEntry);
outEntry.setTime(timestamp);
// Discard comment and extra fields of this entry to
// simplify alignment logic below and for consistency with
@@ -550,57 +424,134 @@
outEntry.setComment(null);
outEntry.setExtra(null);
- // 'offset' is the offset into the file at which we expect
- // the file data to begin. This is the value we need to
- // make a multiple of 'alignement'.
+ int alignment = getStoredEntryDataAlignment(name, defaultAlignment);
+ // Alignment of the entry's data is achieved by adding a data block to the entry's Local
+ // File Header extra field. The data block contains information about the alignment
+ // value and the necessary padding bytes (0x00) to achieve the alignment. This works
+ // because the entry's data will be located immediately after the extra field.
+ // See ZIP APPNOTE.txt section "4.5 Extensible data fields" for details about the format
+ // of the extra field.
+
+ // 'offset' is the offset into the file at which we expect the entry's data to begin.
+ // This is the value we need to make a multiple of 'alignment'.
offset += JarFile.LOCHDR + outEntry.getName().length();
if (firstEntry) {
- // The first entry in a jar file has an extra field of
- // four bytes that you can't get rid of; any extra
- // data you specify in the JarEntry is appended to
- // these forced four bytes. This is JAR_MAGIC in
- // JarOutputStream; the bytes are 0xfeca0000.
+ // The first entry in a jar file has an extra field of four bytes that you can't get
+ // rid of; any extra data you specify in the JarEntry is appended to these forced
+ // four bytes. This is JAR_MAGIC in JarOutputStream; the bytes are 0xfeca0000.
+ // See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6808540
+ // and http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4138619.
offset += 4;
firstEntry = false;
}
- int alignment = getStoredEntryDataAlignment(name, defaultAlignment);
- if (alignment > 0 && (offset % alignment != 0)) {
- // Set the "extra data" of the entry to between 1 and
- // alignment-1 bytes, to make the file data begin at
- // an aligned offset.
- int needed = alignment - (int)(offset % alignment);
- outEntry.setExtra(new byte[needed]);
- offset += needed;
+ int extraPaddingSizeBytes = 0;
+ if (alignment > 0) {
+ long paddingStartOffset = offset + ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES;
+ extraPaddingSizeBytes =
+ (alignment - (int) (paddingStartOffset % alignment)) % alignment;
}
+ byte[] extra =
+ new byte[ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES + extraPaddingSizeBytes];
+ ByteBuffer extraBuf = ByteBuffer.wrap(extra);
+ extraBuf.order(ByteOrder.LITTLE_ENDIAN);
+ extraBuf.putShort(ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID); // Header ID
+ extraBuf.putShort((short) (2 + extraPaddingSizeBytes)); // Data Size
+ extraBuf.putShort((short) alignment);
+ outEntry.setExtra(extra);
+ offset += extra.length;
out.putNextEntry(outEntry);
+ ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+ (apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
+ DataSink entryDataSink =
+ (inspectEntryRequest != null) ? inspectEntryRequest.getDataSink() : null;
- InputStream data = in.getInputStream(inEntry);
- while ((num = data.read(buffer)) > 0) {
- out.write(buffer, 0, num);
- offset += num;
+ try (InputStream data = in.getInputStream(inEntry)) {
+ while ((num = data.read(buffer)) > 0) {
+ out.write(buffer, 0, num);
+ if (entryDataSink != null) {
+ entryDataSink.consume(buffer, 0, num);
+ }
+ offset += num;
+ }
}
out.flush();
+ if (inspectEntryRequest != null) {
+ inspectEntryRequest.done();
+ }
}
// Copy all the non-STORED entries. We don't attempt to
// maintain the 'offset' variable past this point; we don't do
// alignment on these entries.
- for (String name : names) {
+ for (String name : remainingNames) {
JarEntry inEntry = in.getJarEntry(name);
- JarEntry outEntry = null;
- if (inEntry.getMethod() == JarEntry.STORED) continue;
+ if (!shouldOutputApkEntry(apkSigner, in, inEntry, buffer)) {
+ continue;
+ }
+
// Create a new entry so that the compressed len is recomputed.
- outEntry = new JarEntry(name);
+ JarEntry outEntry = new JarEntry(name);
outEntry.setTime(timestamp);
out.putNextEntry(outEntry);
+ ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+ (apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
+ DataSink entryDataSink =
+ (inspectEntryRequest != null) ? inspectEntryRequest.getDataSink() : null;
InputStream data = in.getInputStream(inEntry);
while ((num = data.read(buffer)) > 0) {
out.write(buffer, 0, num);
+ if (entryDataSink != null) {
+ entryDataSink.consume(buffer, 0, num);
+ }
}
out.flush();
+ if (inspectEntryRequest != null) {
+ inspectEntryRequest.done();
+ }
+ }
+ }
+
+ private static boolean shouldOutputApkEntry(
+ ApkSignerEngine apkSigner, JarFile inFile, JarEntry inEntry, byte[] tmpbuf)
+ throws IOException {
+ if (apkSigner == null) {
+ return true;
+ }
+
+ ApkSignerEngine.InputJarEntryInstructions instructions =
+ apkSigner.inputJarEntry(inEntry.getName());
+ ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+ instructions.getInspectJarEntryRequest();
+ if (inspectEntryRequest != null) {
+ provideJarEntry(inFile, inEntry, inspectEntryRequest, tmpbuf);
+ }
+ switch (instructions.getOutputPolicy()) {
+ case OUTPUT:
+ return true;
+ case SKIP:
+ case OUTPUT_BY_ENGINE:
+ return false;
+ default:
+ throw new RuntimeException(
+ "Unsupported output policy: " + instructions.getOutputPolicy());
+ }
+ }
+
+ private static void provideJarEntry(
+ JarFile jarFile,
+ JarEntry jarEntry,
+ ApkSignerEngine.InspectJarEntryRequest request,
+ byte[] tmpbuf) throws IOException {
+ DataSink dataSink = request.getDataSink();
+ try (InputStream in = jarFile.getInputStream(jarEntry)) {
+ int chunkSize;
+ while ((chunkSize = in.read(tmpbuf)) > 0) {
+ dataSink.consume(tmpbuf, 0, chunkSize);
+ }
+ request.done();
}
}
@@ -686,21 +637,26 @@
private final File publicKeyFile;
private final X509Certificate publicKey;
private final PrivateKey privateKey;
+ private final int hash;
private final long timestamp;
- private final int minSdkVersion;
private final OutputStream outputStream;
private final ASN1ObjectIdentifier type;
private WholeFileSignerOutputStream signer;
+ // Files matching this pattern are not copied to the output.
+ private static final Pattern STRIP_PATTERN =
+ Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA|EC)|com/android/otacert))|("
+ + Pattern.quote(JarFile.MANIFEST_NAME) + ")$");
+
public CMSSigner(JarFile inputJar, File publicKeyFile,
- X509Certificate publicKey, PrivateKey privateKey, long timestamp,
- int minSdkVersion, OutputStream outputStream) {
+ X509Certificate publicKey, PrivateKey privateKey, int hash,
+ long timestamp, OutputStream outputStream) {
this.inputJar = inputJar;
this.publicKeyFile = publicKeyFile;
this.publicKey = publicKey;
this.privateKey = privateKey;
+ this.hash = hash;
this.timestamp = timestamp;
- this.minSdkVersion = minSdkVersion;
this.outputStream = outputStream;
this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId());
}
@@ -725,19 +681,8 @@
signer = new WholeFileSignerOutputStream(out, outputStream);
JarOutputStream outputJar = new JarOutputStream(signer);
- int hash = getDigestAlgorithm(publicKey, minSdkVersion);
-
- Manifest manifest = addDigestsToManifest(inputJar, hash);
- copyFiles(manifest, inputJar, outputJar, timestamp, 0);
- addOtacert(outputJar, publicKeyFile, timestamp, manifest, hash);
-
- signFile(manifest,
- new X509Certificate[]{ publicKey },
- new PrivateKey[]{ privateKey },
- timestamp,
- minSdkVersion,
- false, // Don't sign using APK Signature Scheme v2
- outputJar);
+ copyFiles(inputJar, STRIP_PATTERN, null, outputJar, timestamp, 0);
+ addOtacert(outputJar, publicKeyFile, timestamp);
signer.notifyClosing();
outputJar.close();
@@ -753,7 +698,7 @@
CertificateEncodingException,
OperatorCreationException,
CMSException {
- SignApk.writeSignatureBlock(this, publicKey, privateKey, minSdkVersion, temp);
+ SignApk.writeSignatureBlock(this, publicKey, privateKey, hash, temp);
}
public WholeFileSignerOutputStream getSigner() {
@@ -763,10 +708,10 @@
private static void signWholeFile(JarFile inputJar, File publicKeyFile,
X509Certificate publicKey, PrivateKey privateKey,
- long timestamp, int minSdkVersion,
+ int hash, long timestamp,
OutputStream outputStream) throws Exception {
CMSSigner cmsOut = new CMSSigner(inputJar, publicKeyFile,
- publicKey, privateKey, timestamp, minSdkVersion, outputStream);
+ publicKey, privateKey, hash, timestamp, outputStream);
ByteArrayOutputStream temp = new ByteArrayOutputStream();
@@ -774,7 +719,7 @@
// archive comment, so that tools that display the comment
// (hopefully) show something sensible.
// TODO: anything more useful we can put in this message?
- byte[] message = "signed by SignApk".getBytes("UTF-8");
+ byte[] message = "signed by SignApk".getBytes(StandardCharsets.UTF_8);
temp.write(message);
temp.write(0);
@@ -830,48 +775,6 @@
temp.writeTo(outputStream);
}
- private static void signFile(Manifest manifest,
- X509Certificate[] publicKey, PrivateKey[] privateKey,
- long timestamp,
- int minSdkVersion,
- boolean additionallySignedUsingAnApkSignatureScheme,
- JarOutputStream outputJar)
- throws Exception {
-
- // MANIFEST.MF
- JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
- je.setTime(timestamp);
- outputJar.putNextEntry(je);
- manifest.write(outputJar);
-
- int numKeys = publicKey.length;
- for (int k = 0; k < numKeys; ++k) {
- // CERT.SF / CERT#.SF
- je = new JarEntry(numKeys == 1 ? CERT_SF_NAME :
- (String.format(CERT_SF_MULTI_NAME, k)));
- je.setTime(timestamp);
- outputJar.putNextEntry(je);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- writeSignatureFile(
- manifest,
- baos,
- getDigestAlgorithm(publicKey[k], minSdkVersion),
- additionallySignedUsingAnApkSignatureScheme);
- byte[] signedData = baos.toByteArray();
- outputJar.write(signedData);
-
- // CERT.{EC,RSA} / CERT#.{EC,RSA}
- final String keyType = publicKey[k].getPublicKey().getAlgorithm();
- je = new JarEntry(numKeys == 1 ?
- (String.format(CERT_SIG_NAME, keyType)) :
- (String.format(CERT_SIG_MULTI_NAME, k, keyType)));
- je.setTime(timestamp);
- outputJar.putNextEntry(je);
- writeSignatureBlock(new CMSProcessableByteArray(signedData),
- publicKey[k], privateKey[k], minSdkVersion, outputJar);
- }
- }
-
/**
* Tries to load a JSE Provider by class name. This is for custom PrivateKey
* types that might be stored in PKCS#11-like storage.
@@ -924,81 +827,99 @@
Security.insertProviderAt((Provider) o, 1);
}
- /**
- * Converts the provided lists of private keys, their X.509 certificates, and digest algorithms
- * into a list of APK Signature Scheme v2 {@code SignerConfig} instances.
- */
- public static List<ApkSignerV2.SignerConfig> createV2SignerConfigs(
- PrivateKey[] privateKeys, X509Certificate[] certificates, String[] digestAlgorithms)
- throws InvalidKeyException {
+ private static List<DefaultApkSignerEngine.SignerConfig> createSignerConfigs(
+ PrivateKey[] privateKeys, X509Certificate[] certificates) {
if (privateKeys.length != certificates.length) {
throw new IllegalArgumentException(
"The number of private keys must match the number of certificates: "
+ privateKeys.length + " vs" + certificates.length);
}
- List<ApkSignerV2.SignerConfig> result = new ArrayList<>(privateKeys.length);
+ List<DefaultApkSignerEngine.SignerConfig> signerConfigs = new ArrayList<>();
+ String signerNameFormat = (privateKeys.length == 1) ? "CERT" : "CERT%s";
for (int i = 0; i < privateKeys.length; i++) {
- PrivateKey privateKey = privateKeys[i];
- X509Certificate certificate = certificates[i];
- PublicKey publicKey = certificate.getPublicKey();
- String keyAlgorithm = privateKey.getAlgorithm();
- if (!keyAlgorithm.equalsIgnoreCase(publicKey.getAlgorithm())) {
- throw new InvalidKeyException(
- "Key algorithm of private key #" + (i + 1) + " does not match key"
- + " algorithm of public key #" + (i + 1) + ": " + keyAlgorithm
- + " vs " + publicKey.getAlgorithm());
- }
- ApkSignerV2.SignerConfig signerConfig = new ApkSignerV2.SignerConfig();
- signerConfig.privateKey = privateKey;
- signerConfig.certificates = Collections.singletonList(certificate);
- List<Integer> signatureAlgorithms = new ArrayList<>(digestAlgorithms.length);
- for (String digestAlgorithm : digestAlgorithms) {
- try {
- signatureAlgorithms.add(
- getV2SignatureAlgorithm(keyAlgorithm, digestAlgorithm));
- } catch (IllegalArgumentException e) {
- throw new InvalidKeyException(
- "Unsupported key and digest algorithm combination for signer #"
- + (i + 1),
- e);
- }
- }
- signerConfig.signatureAlgorithms = signatureAlgorithms;
- result.add(signerConfig);
+ String signerName = String.format(Locale.US, signerNameFormat, (i + 1));
+ DefaultApkSignerEngine.SignerConfig signerConfig =
+ new DefaultApkSignerEngine.SignerConfig.Builder(
+ signerName,
+ privateKeys[i],
+ Collections.singletonList(certificates[i]))
+ .build();
+ signerConfigs.add(signerConfig);
}
+ return signerConfigs;
+ }
+
+ private static class ZipSections {
+ ByteBuffer beforeCentralDir;
+ ByteBuffer centralDir;
+ ByteBuffer eocd;
+ }
+
+ private static ZipSections findMainZipSections(ByteBuffer apk)
+ throws IOException, ZipFormatException {
+ apk.slice();
+ ApkUtils.ZipSections sections = ApkUtils.findZipSections(DataSources.asDataSource(apk));
+ long centralDirStartOffset = sections.getZipCentralDirectoryOffset();
+ long centralDirSizeBytes = sections.getZipCentralDirectorySizeBytes();
+ long centralDirEndOffset = centralDirStartOffset + centralDirSizeBytes;
+ long eocdStartOffset = sections.getZipEndOfCentralDirectoryOffset();
+ if (centralDirEndOffset != eocdStartOffset) {
+ throw new ZipFormatException(
+ "ZIP Central Directory is not immediately followed by End of Central Directory"
+ + ". CD end: " + centralDirEndOffset
+ + ", EoCD start: " + eocdStartOffset);
+ }
+ apk.position(0);
+ apk.limit((int) centralDirStartOffset);
+ ByteBuffer beforeCentralDir = apk.slice();
+
+ apk.position((int) centralDirStartOffset);
+ apk.limit((int) centralDirEndOffset);
+ ByteBuffer centralDir = apk.slice();
+
+ apk.position((int) eocdStartOffset);
+ apk.limit(apk.capacity());
+ ByteBuffer eocd = apk.slice();
+
+ apk.position(0);
+ apk.limit(apk.capacity());
+
+ ZipSections result = new ZipSections();
+ result.beforeCentralDir = beforeCentralDir;
+ result.centralDir = centralDir;
+ result.eocd = eocd;
return result;
}
- private static int getV2SignatureAlgorithm(String keyAlgorithm, String digestAlgorithm) {
- if ("SHA-256".equalsIgnoreCase(digestAlgorithm)) {
- if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
- // Use RSASSA-PKCS1-v1_5 signature scheme instead of RSASSA-PSS to guarantee
- // deterministic signatures which make life easier for OTA updates (fewer files
- // changed when deterministic signature schemes are used).
- return ApkSignerV2.SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256;
- } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
- return ApkSignerV2.SIGNATURE_ECDSA_WITH_SHA256;
- } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
- return ApkSignerV2.SIGNATURE_DSA_WITH_SHA256;
- } else {
- throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
- }
- } else if ("SHA-512".equalsIgnoreCase(digestAlgorithm)) {
- if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
- // Use RSASSA-PKCS1-v1_5 signature scheme instead of RSASSA-PSS to guarantee
- // deterministic signatures which make life easier for OTA updates (fewer files
- // changed when deterministic signature schemes are used).
- return ApkSignerV2.SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512;
- } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
- return ApkSignerV2.SIGNATURE_ECDSA_WITH_SHA512;
- } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
- return ApkSignerV2.SIGNATURE_DSA_WITH_SHA512;
- } else {
- throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
- }
- } else {
- throw new IllegalArgumentException("Unsupported digest algorithm: " + digestAlgorithm);
+ /**
+ * Returns the API Level corresponding to the APK's minSdkVersion.
+ *
+ * @throws MinSdkVersionException if the API Level cannot be determined from the APK.
+ */
+ private static final int getMinSdkVersion(JarFile apk) throws MinSdkVersionException {
+ JarEntry manifestEntry = apk.getJarEntry("AndroidManifest.xml");
+ if (manifestEntry == null) {
+ throw new MinSdkVersionException("No AndroidManifest.xml in APK");
}
+ byte[] manifestBytes;
+ try {
+ try (InputStream manifestIn = apk.getInputStream(manifestEntry)) {
+ manifestBytes = toByteArray(manifestIn);
+ }
+ } catch (IOException e) {
+ throw new MinSdkVersionException("Failed to read AndroidManifest.xml", e);
+ }
+ return ApkUtils.getMinSdkVersionFromBinaryAndroidManifest(ByteBuffer.wrap(manifestBytes));
+ }
+
+ private static byte[] toByteArray(InputStream in) throws IOException {
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ byte[] buf = new byte[65536];
+ int chunkSize;
+ while ((chunkSize = in.read(buf)) != -1) {
+ result.write(buf, 0, chunkSize);
+ }
+ return result.toByteArray();
}
private static void usage() {
@@ -1027,7 +948,7 @@
boolean signWholeFile = false;
String providerClass = null;
int alignment = 4;
- int minSdkVersion = 0;
+ Integer minSdkVersionOverride = null;
boolean signUsingApkSignatureSchemeV2 = true;
int argstart = 0;
@@ -1047,7 +968,7 @@
} else if ("--min-sdk-version".equals(args[argstart])) {
String minSdkVersionString = args[++argstart];
try {
- minSdkVersion = Integer.parseInt(minSdkVersionString);
+ minSdkVersionOverride = Integer.parseInt(minSdkVersionString);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"--min-sdk-version must be a decimal number: " + minSdkVersionString);
@@ -1075,7 +996,6 @@
JarFile inputJar = null;
FileOutputStream outputFile = null;
- int hashes = 0;
try {
File firstPublicKeyFile = new File(args[argstart+0]);
@@ -1085,7 +1005,6 @@
for (int i = 0; i < numKeys; ++i) {
int argNum = argstart + i*2;
publicKey[i] = readPublicKey(new File(args[argNum]));
- hashes |= getDigestAlgorithm(publicKey[i], minSdkVersion);
}
} catch (IllegalArgumentException e) {
System.err.println(e);
@@ -1111,55 +1030,101 @@
// NOTE: Signing currently recompresses any compressed entries using Deflate (default
// compression level for OTA update files and maximum compession level for APKs).
if (signWholeFile) {
- SignApk.signWholeFile(inputJar, firstPublicKeyFile,
- publicKey[0], privateKey[0],
- timestamp, minSdkVersion,
- outputFile);
+ int digestAlgorithm = getDigestAlgorithmForOta(publicKey[0]);
+ signWholeFile(inputJar, firstPublicKeyFile,
+ publicKey[0], privateKey[0], digestAlgorithm,
+ timestamp,
+ outputFile);
} else {
- // Generate, in memory, an APK signed using standard JAR Signature Scheme.
- ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
- JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf);
- // Use maximum compression for compressed entries because the APK lives forever on
- // the system partition.
- outputJar.setLevel(9);
- Manifest manifest = addDigestsToManifest(inputJar, hashes);
- copyFiles(manifest, inputJar, outputJar, timestamp, alignment);
- signFile(
- manifest,
- publicKey, privateKey,
- timestamp, minSdkVersion, signUsingApkSignatureSchemeV2,
- outputJar);
- outputJar.close();
- ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray());
- v1SignedApkBuf.reset();
-
- ByteBuffer[] outputChunks;
- if (signUsingApkSignatureSchemeV2) {
- // Additionally sign the APK using the APK Signature Scheme v2.
- ByteBuffer apkContents = v1SignedApk;
- List<ApkSignerV2.SignerConfig> signerConfigs =
- createV2SignerConfigs(
- privateKey,
- publicKey,
- new String[] {APK_SIG_SCHEME_V2_DIGEST_ALGORITHM});
- outputChunks = ApkSignerV2.sign(apkContents, signerConfigs);
+ // Determine the value to use as minSdkVersion of the APK being signed
+ int minSdkVersion;
+ if (minSdkVersionOverride != null) {
+ minSdkVersion = minSdkVersionOverride;
} else {
- // Output the JAR-signed APK as is.
- outputChunks = new ByteBuffer[] {v1SignedApk};
+ try {
+ minSdkVersion = getMinSdkVersion(inputJar);
+ } catch (MinSdkVersionException e) {
+ throw new IllegalArgumentException(
+ "Cannot detect minSdkVersion. Use --min-sdk-version to override",
+ e);
+ }
}
- // This assumes outputChunks are array-backed. To avoid this assumption, the
- // code could be rewritten to use FileChannel.
- for (ByteBuffer outputChunk : outputChunks) {
- outputFile.write(
- outputChunk.array(),
- outputChunk.arrayOffset() + outputChunk.position(),
- outputChunk.remaining());
- outputChunk.position(outputChunk.limit());
+ try (ApkSignerEngine apkSigner =
+ new DefaultApkSignerEngine.Builder(
+ createSignerConfigs(privateKey, publicKey), minSdkVersion)
+ .setV1SigningEnabled(true)
+ .setV2SigningEnabled(signUsingApkSignatureSchemeV2)
+ .setOtherSignersSignaturesPreserved(false)
+ .setCreatedBy("1.0 (Android SignApk)")
+ .build()) {
+ // We don't preserve the input APK's APK Signing Block (which contains v2
+ // signatures)
+ apkSigner.inputApkSigningBlock(null);
+
+ // Build the output APK in memory, by copying input APK's ZIP entries across
+ // and then signing the output APK.
+ ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
+ JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf);
+ // Use maximum compression for compressed entries because the APK lives forever
+ // on the system partition.
+ outputJar.setLevel(9);
+ copyFiles(inputJar, null, apkSigner, outputJar, timestamp, alignment);
+ ApkSignerEngine.OutputJarSignatureRequest addV1SignatureRequest =
+ apkSigner.outputJarEntries();
+ if (addV1SignatureRequest != null) {
+ addV1Signature(apkSigner, addV1SignatureRequest, outputJar, timestamp);
+ addV1SignatureRequest.done();
+ }
+ outputJar.close();
+ ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray());
+ v1SignedApkBuf.reset();
+ ByteBuffer[] outputChunks = new ByteBuffer[] {v1SignedApk};
+
+ ZipSections zipSections = findMainZipSections(v1SignedApk);
+ ApkSignerEngine.OutputApkSigningBlockRequest addV2SignatureRequest =
+ apkSigner.outputZipSections(
+ DataSources.asDataSource(zipSections.beforeCentralDir),
+ DataSources.asDataSource(zipSections.centralDir),
+ DataSources.asDataSource(zipSections.eocd));
+ if (addV2SignatureRequest != null) {
+ // Need to insert the returned APK Signing Block before ZIP Central
+ // Directory.
+ byte[] apkSigningBlock = addV2SignatureRequest.getApkSigningBlock();
+ // Because the APK Signing Block is inserted before the Central Directory,
+ // we need to adjust accordingly the offset of Central Directory inside the
+ // ZIP End of Central Directory (EoCD) record.
+ ByteBuffer modifiedEocd = ByteBuffer.allocate(zipSections.eocd.remaining());
+ modifiedEocd.put(zipSections.eocd);
+ modifiedEocd.flip();
+ modifiedEocd.order(ByteOrder.LITTLE_ENDIAN);
+ ApkUtils.setZipEocdCentralDirectoryOffset(
+ modifiedEocd,
+ zipSections.beforeCentralDir.remaining() + apkSigningBlock.length);
+ outputChunks =
+ new ByteBuffer[] {
+ zipSections.beforeCentralDir,
+ ByteBuffer.wrap(apkSigningBlock),
+ zipSections.centralDir,
+ modifiedEocd};
+ addV2SignatureRequest.done();
+ }
+
+ // This assumes outputChunks are array-backed. To avoid this assumption, the
+ // code could be rewritten to use FileChannel.
+ for (ByteBuffer outputChunk : outputChunks) {
+ outputFile.write(
+ outputChunk.array(),
+ outputChunk.arrayOffset() + outputChunk.position(),
+ outputChunk.remaining());
+ outputChunk.position(outputChunk.limit());
+ }
+
+ outputFile.close();
+ outputFile = null;
+ apkSigner.outputDone();
}
- outputFile.close();
- outputFile = null;
return;
}
} catch (Exception e) {
diff --git a/tools/signapk/src/com/android/signapk/ZipUtils.java b/tools/signapk/src/com/android/signapk/ZipUtils.java
deleted file mode 100644
index 7575a77..0000000
--- a/tools/signapk/src/com/android/signapk/ZipUtils.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.signapk;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Assorted ZIP format helpers.
- *
- * <p>NOTE: Most helper methods operating on {@code ByteBuffer} instances expect that the byte
- * order of these buffers is little-endian.
- */
-public abstract class ZipUtils {
- private ZipUtils() {}
-
- private static final int ZIP_EOCD_REC_MIN_SIZE = 22;
- private static final int ZIP_EOCD_REC_SIG = 0x06054b50;
- private static final int ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET = 12;
- private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET = 16;
- private static final int ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET = 20;
-
- private static final int ZIP64_EOCD_LOCATOR_SIZE = 20;
- private static final int ZIP64_EOCD_LOCATOR_SIG = 0x07064b50;
-
- private static final int UINT16_MAX_VALUE = 0xffff;
-
- /**
- * Returns the position at which ZIP End of Central Directory record starts in the provided
- * buffer or {@code -1} if the record is not present.
- *
- * <p>NOTE: Byte order of {@code zipContents} must be little-endian.
- */
- public static int findZipEndOfCentralDirectoryRecord(ByteBuffer zipContents) {
- assertByteOrderLittleEndian(zipContents);
-
- // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive.
- // The record can be identified by its 4-byte signature/magic which is located at the very
- // beginning of the record. A complication is that the record is variable-length because of
- // the comment field.
- // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from
- // end of the buffer for the EOCD record signature. Whenever we find a signature, we check
- // the candidate record's comment length is such that the remainder of the record takes up
- // exactly the remaining bytes in the buffer. The search is bounded because the maximum
- // size of the comment field is 65535 bytes because the field is an unsigned 16-bit number.
-
- int archiveSize = zipContents.capacity();
- if (archiveSize < ZIP_EOCD_REC_MIN_SIZE) {
- return -1;
- }
- int maxCommentLength = Math.min(archiveSize - ZIP_EOCD_REC_MIN_SIZE, UINT16_MAX_VALUE);
- int eocdWithEmptyCommentStartPosition = archiveSize - ZIP_EOCD_REC_MIN_SIZE;
- for (int expectedCommentLength = 0; expectedCommentLength < maxCommentLength;
- expectedCommentLength++) {
- int eocdStartPos = eocdWithEmptyCommentStartPosition - expectedCommentLength;
- if (zipContents.getInt(eocdStartPos) == ZIP_EOCD_REC_SIG) {
- int actualCommentLength =
- getUnsignedInt16(
- zipContents, eocdStartPos + ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET);
- if (actualCommentLength == expectedCommentLength) {
- return eocdStartPos;
- }
- }
- }
-
- return -1;
- }
-
- /**
- * Returns {@code true} if the provided buffer contains a ZIP64 End of Central Directory
- * Locator.
- *
- * <p>NOTE: Byte order of {@code zipContents} must be little-endian.
- */
- public static final boolean isZip64EndOfCentralDirectoryLocatorPresent(
- ByteBuffer zipContents, int zipEndOfCentralDirectoryPosition) {
- assertByteOrderLittleEndian(zipContents);
-
- // ZIP64 End of Central Directory Locator immediately precedes the ZIP End of Central
- // Directory Record.
-
- int locatorPosition = zipEndOfCentralDirectoryPosition - ZIP64_EOCD_LOCATOR_SIZE;
- if (locatorPosition < 0) {
- return false;
- }
-
- return zipContents.getInt(locatorPosition) == ZIP64_EOCD_LOCATOR_SIG;
- }
-
- /**
- * Returns the offset of the start of the ZIP Central Directory in the archive.
- *
- * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
- */
- public static long getZipEocdCentralDirectoryOffset(ByteBuffer zipEndOfCentralDirectory) {
- assertByteOrderLittleEndian(zipEndOfCentralDirectory);
- return getUnsignedInt32(
- zipEndOfCentralDirectory,
- zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET);
- }
-
- /**
- * Sets the offset of the start of the ZIP Central Directory in the archive.
- *
- * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
- */
- public static void setZipEocdCentralDirectoryOffset(
- ByteBuffer zipEndOfCentralDirectory, long offset) {
- assertByteOrderLittleEndian(zipEndOfCentralDirectory);
- setUnsignedInt32(
- zipEndOfCentralDirectory,
- zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET,
- offset);
- }
-
- /**
- * Returns the size (in bytes) of the ZIP Central Directory.
- *
- * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
- */
- public static long getZipEocdCentralDirectorySizeBytes(ByteBuffer zipEndOfCentralDirectory) {
- assertByteOrderLittleEndian(zipEndOfCentralDirectory);
- return getUnsignedInt32(
- zipEndOfCentralDirectory,
- zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET);
- }
-
- private static void assertByteOrderLittleEndian(ByteBuffer buffer) {
- if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
- throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
- }
- }
-
- private static int getUnsignedInt16(ByteBuffer buffer, int offset) {
- return buffer.getShort(offset) & 0xffff;
- }
-
- private static long getUnsignedInt32(ByteBuffer buffer, int offset) {
- return buffer.getInt(offset) & 0xffffffffL;
- }
-
- private static void setUnsignedInt32(ByteBuffer buffer, int offset, long value) {
- if ((value < 0) || (value > 0xffffffffL)) {
- throw new IllegalArgumentException("uint32 value of out range: " + value);
- }
- buffer.putInt(buffer.position() + offset, (int) value);
- }
-}
diff --git a/tools/soong_to_convert.py b/tools/soong_to_convert.py
new file mode 100755
index 0000000..3d62d43
--- /dev/null
+++ b/tools/soong_to_convert.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# 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.
+
+"""Tool to prioritize which modules to convert to Soong.
+
+Generally, you'd use this through the make integration, which automatically
+generates the CSV input file that this tool expects:
+
+ $ m $OUT/soong_to_convert.txt
+ $ less $OUT/soong_to_convert.txt
+
+The output is a list of modules that are probably ready to convert to Soong:
+
+ # Blocked on Module (potential problems)
+ 283 libEGL (srcs_dotarm)
+ 246 libicuuc (dotdot_incs dotdot_srcs)
+ 221 libspeexresampler
+ 215 libcamera_metadata
+ ...
+ 0 zram-perf (dotdot_incs)
+
+The number at the beginning of the line shows how many native modules depend
+on that module.
+
+All of their dependencies have been satisfied, and any potential problems
+that Make can detect are listed in parenthesis after the module:
+
+ dotdot_srcs: LOCAL_SRC_FILES contains paths outside $(LOCAL_PATH)
+ dotdot_incs: LOCAL_C_INCLUDES contains paths include '..'
+ srcs_dotarm: LOCAL_SRC_FILES contains source files like <...>.c.arm
+ aidl: LOCAL_SRC_FILES contains .aidl sources
+ objc: LOCAL_SRC_FILES contains Objective-C sources
+ proto: LOCAL_SRC_FILES contains .proto sources
+ rs: LOCAL_SRC_FILES contains renderscript sources
+ vts: LOCAL_SRC_FILES contains .vts sources
+
+Not all problems can be discovered, but this is a starting point.
+
+"""
+
+from __future__ import print_function
+
+import csv
+import sys
+
+def count_deps(depsdb, module, seen):
+ """Based on the depsdb, count the number of transitive dependencies.
+
+ You can pass in an reversed dependency graph to conut the number of
+ modules that depend on the module."""
+ count = 0
+ seen.append(module)
+ if module in depsdb:
+ for dep in depsdb[module]:
+ if dep in seen:
+ continue
+ count += 1 + count_deps(depsdb, dep, seen)
+ return count
+
+def process(reader):
+ """Read the input file and produce a list of modules ready to move to Soong
+ """
+ problems = dict()
+ deps = dict()
+ reverse_deps = dict()
+
+ for (module, problem, dependencies) in reader:
+ problems[module] = problem
+ deps[module] = [d for d in dependencies.strip().split(' ') if d != ""]
+ for dep in deps[module]:
+ if not dep in reverse_deps:
+ reverse_deps[dep] = []
+ reverse_deps[dep].append(module)
+
+ results = []
+ for module in problems:
+ # Only display actionable conversions, ones without missing dependencies
+ if len(deps[module]) != 0:
+ continue
+
+ extra = ""
+ if len(problems[module]) > 0:
+ extra = " ({})".format(problems[module])
+ results.append((count_deps(reverse_deps, module, []), module + extra))
+
+ return sorted(results, key=lambda result: (-result[0], result[1]))
+
+def display(results):
+ """Displays the results"""
+ count_header = "# Blocked on"
+ count_width = len(count_header)
+ print("{} Module (potential problems)".format(count_header))
+ for (count, module) in results:
+ print("{:>{}} {}".format(count, count_width, module))
+
+def main(filename):
+ """Read the CSV file, print the results"""
+ with open(filename, 'rb') as csvfile:
+ results = process(csv.reader(csvfile))
+
+ display(results)
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ print("usage: soong_conversion.py <file>", file=sys.stderr)
+ sys.exit(1)
+
+ main(sys.argv[1])
diff --git a/tools/warn.py b/tools/warn.py
index 8097123..be659b8 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -1,563 +1,2750 @@
-#!/usr/bin/env python
+#!/usr/bin/python
# This file uses the following encoding: utf-8
-import sys
+"""Grep warnings messages and output HTML tables or warning counts in CSV.
+
+Default is to output warnings in HTML tables grouped by warning severity.
+Use option --byproject to output tables grouped by source file projects.
+Use option --gencsv to output warning counts in CSV format.
+"""
+
+# List of important data structures and functions in this script.
+#
+# To parse and keep warning message in the input file:
+# severity: classification of message severity
+# severity.range [0, 1, ... last_severity_level]
+# severity.colors for header background
+# severity.column_headers for the warning count table
+# severity.headers for warning message tables
+# warn_patterns:
+# warn_patterns[w]['category'] tool that issued the warning, not used now
+# warn_patterns[w]['description'] table heading
+# warn_patterns[w]['members'] matched warnings from input
+# warn_patterns[w]['option'] compiler flag to control the warning
+# warn_patterns[w]['patterns'] regular expressions to match warnings
+# warn_patterns[w]['projects'][p] number of warnings of pattern w in p
+# warn_patterns[w]['severity'] severity level
+# project_list[p][0] project name
+# project_list[p][1] regular expression to match a project path
+# project_patterns[p] re.compile(project_list[p][1])
+# project_names[p] project_list[p][0]
+# warning_messages array of each warning message, without source url
+# warning_records array of [idx to warn_patterns,
+# idx to project_names,
+# idx to warning_messages]
+# android_root
+# platform_version
+# target_product
+# target_variant
+# compile_patterns, parse_input_file
+#
+# To emit html page of warning messages:
+# flags: --byproject, --url, --separator
+# Old stuff for static html components:
+# html_script_style: static html scripts and styles
+# htmlbig:
+# dump_stats, dump_html_prologue, dump_html_epilogue:
+# emit_buttons:
+# dump_fixed
+# sort_warnings:
+# emit_stats_by_project:
+# all_patterns,
+# findproject, classify_warning
+# dump_html
+#
+# New dynamic HTML page's static JavaScript data:
+# Some data are copied from Python to JavaScript, to generate HTML elements.
+# FlagURL args.url
+# FlagSeparator args.separator
+# SeverityColors: severity.colors
+# SeverityHeaders: severity.headers
+# SeverityColumnHeaders: severity.column_headers
+# ProjectNames: project_names, or project_list[*][0]
+# WarnPatternsSeverity: warn_patterns[*]['severity']
+# WarnPatternsDescription: warn_patterns[*]['description']
+# WarnPatternsOption: warn_patterns[*]['option']
+# WarningMessages: warning_messages
+# Warnings: warning_records
+# StatsHeader: warning count table header row
+# StatsRows: array of warning count table rows
+#
+# New dynamic HTML page's dynamic JavaScript data:
+#
+# New dynamic HTML related function to emit data:
+# escape_string, strip_escape_string, emit_warning_arrays
+# emit_js_data():
+
+import argparse
+import csv
+import multiprocessing
+import os
import re
+import signal
+import sys
-if len(sys.argv) == 1:
- print 'usage: ' + sys.argv[0] + ' <build.log>'
- sys.exit()
+parser = argparse.ArgumentParser(description='Convert a build log into HTML')
+parser.add_argument('--csvpath',
+ help='Save CSV warning file to the passed absolute path',
+ default=None)
+parser.add_argument('--gencsv',
+ help='Generate a CSV file with number of various warnings',
+ action='store_true',
+ default=False)
+parser.add_argument('--byproject',
+ help='Separate warnings in HTML output by project names',
+ action='store_true',
+ default=False)
+parser.add_argument('--url',
+ help='Root URL of an Android source code tree prefixed '
+ 'before files in warnings')
+parser.add_argument('--separator',
+ help='Separator between the end of a URL and the line '
+ 'number argument. e.g. #')
+parser.add_argument('--processes',
+ type=int,
+ default=multiprocessing.cpu_count(),
+ help='Number of parallel processes to process warnings')
+parser.add_argument(dest='buildlog', metavar='build.log',
+ help='Path to build.log file')
+args = parser.parse_args()
-# if you add another level, don't forget to give it a color below
-class severity:
- UNKNOWN=0
- SKIP=100
- FIXMENOW=1
- HIGH=2
- MEDIUM=3
- LOW=4
- HARMLESS=5
-def colorforseverity(sev):
- if sev == severity.FIXMENOW:
- return 'fuchsia'
- if sev == severity.HIGH:
- return 'red'
- if sev == severity.MEDIUM:
- return 'orange'
- if sev == severity.LOW:
- return 'yellow'
- if sev == severity.HARMLESS:
- return 'limegreen'
- if sev == severity.UNKNOWN:
- return 'blue'
- return 'grey'
+class Severity(object):
+ """Severity levels and attributes."""
+ # numbered by dump order
+ FIXMENOW = 0
+ HIGH = 1
+ MEDIUM = 2
+ LOW = 3
+ ANALYZER = 4
+ TIDY = 5
+ HARMLESS = 6
+ UNKNOWN = 7
+ SKIP = 8
+ range = range(SKIP + 1)
+ attributes = [
+ # pylint:disable=bad-whitespace
+ ['fuchsia', 'FixNow', 'Critical warnings, fix me now'],
+ ['red', 'High', 'High severity warnings'],
+ ['orange', 'Medium', 'Medium severity warnings'],
+ ['yellow', 'Low', 'Low severity warnings'],
+ ['hotpink', 'Analyzer', 'Clang-Analyzer warnings'],
+ ['peachpuff', 'Tidy', 'Clang-Tidy warnings'],
+ ['limegreen', 'Harmless', 'Harmless warnings'],
+ ['lightblue', 'Unknown', 'Unknown warnings'],
+ ['grey', 'Unhandled', 'Unhandled warnings']
+ ]
+ colors = [a[0] for a in attributes]
+ column_headers = [a[1] for a in attributes]
+ headers = [a[2] for a in attributes]
-warnpatterns = [
- { 'category':'make', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'make: overriding commands/ignoring old commands',
- 'patterns':[r".*: warning: overriding commands for target .+",
- r".*: warning: ignoring old commands for target .+"] },
- { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wimplicit-function-declaration',
- 'description':'Implicit function declaration',
- 'patterns':[r".*: warning: implicit declaration of function .+"] },
- { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: conflicting types for '.+'"] },
- { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wtype-limits',
- 'description':'Expression always evaluates to true or false',
- 'patterns':[r".*: warning: comparison is always false due to limited range of data type",
- r".*: warning: comparison of unsigned expression >= 0 is always true",
- r".*: warning: comparison of unsigned expression < 0 is always false"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Incompatible pointer types',
- 'patterns':[r".*: warning: assignment from incompatible pointer type",
- r".*: warning: return from incompatible pointer type",
- r".*: warning: passing argument [0-9]+ of '.*' from incompatible pointer type",
- r".*: warning: initialization from incompatible pointer type"] },
- { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-fno-builtin',
- 'description':'Incompatible declaration of built in function',
- 'patterns':[r".*: warning: incompatible implicit declaration of built-in function .+"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-parameter',
- 'description':'Unused parameter',
- 'patterns':[r".*: warning: unused parameter '.*'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused',
- 'description':'Unused function, variable or label',
- 'patterns':[r".*: warning: '.+' defined but not used",
- r".*: warning: unused variable '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-value',
- 'description':'Statement with no effect',
- 'patterns':[r".*: warning: statement with no effect"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-field-initializers',
- 'description':'Missing initializer',
- 'patterns':[r".*: warning: missing initializer"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: \(near initialization for '.+'\)"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat',
- 'description':'Format string does not match arguments',
- 'patterns':[r".*: warning: format '.+' expects type '.+', but argument [0-9]+ has type '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat-extra-args',
- 'description':'Too many arguments for format string',
- 'patterns':[r".*: warning: too many arguments for format"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-compare',
- 'description':'Comparison between signed and unsigned',
- 'patterns':[r".*: warning: comparison between signed and unsigned",
- r".*: warning: comparison of promoted \~unsigned with unsigned",
- r".*: warning: signed and unsigned type in conditional expression"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Comparison between enum and non-enum',
- 'patterns':[r".*: warning: enumeral and non-enumeral type in conditional expression"] },
- { 'category':'libpng', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'libpng: zero area',
- 'patterns':[r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"] },
- { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'aapt: no comment for public symbol',
- 'patterns':[r".*: warning: No comment for public symbol .+"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-braces',
- 'description':'Missing braces around initializer',
- 'patterns':[r".*: warning: missing braces around initializer.*"] },
- { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'',
- 'description':'No newline at end of file',
- 'patterns':[r".*: warning: no newline at end of file"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wcast-qual',
- 'description':'Qualifier discarded',
- 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' discards qualifiers from pointer target type",
- r".*: warning: assignment discards qualifiers from pointer target type",
- r".*: warning: return discards qualifiers from pointer target type"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes',
- 'description':'Attribute ignored',
- 'patterns':[r".*: warning: '_*packed_*' attribute ignored"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes',
- 'description':'Visibility mismatch',
- 'patterns':[r".*: warning: '.+' declared with greater visibility than the type of its field '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Shift count greater than width of type',
- 'patterns':[r".*: warning: (left|right) shift count >= width of type"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'extern <foo> is initialized',
- 'patterns':[r".*: warning: '.+' initialized and declared 'extern'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wold-style-declaration',
- 'description':'Old style declaration',
- 'patterns':[r".*: warning: 'static' is not at beginning of declaration"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wuninitialized',
- 'description':'Variable may be used uninitialized',
- 'patterns':[r".*: warning: '.+' may be used uninitialized in this function"] },
- { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wuninitialized',
- 'description':'Variable is used uninitialized',
- 'patterns':[r".*: warning: '.+' is used uninitialized in this function"] },
- { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'-fshort-enums',
- 'description':'ld: possible enum size mismatch',
- 'patterns':[r".*: warning: .* uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-sign',
- 'description':'Pointer targets differ in signedness',
- 'patterns':[r".*: warning: pointer targets in initialization differ in signedness",
- r".*: warning: pointer targets in assignment differ in signedness",
- r".*: warning: pointer targets in return differ in signedness",
- r".*: warning: pointer targets in passing argument [0-9]+ of '.+' differ in signedness"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-overflow',
- 'description':'Assuming overflow does not occur',
- 'patterns':[r".*: warning: assuming signed overflow does not occur when assuming that .* is always (true|false)"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wempty-body',
- 'description':'Suggest adding braces around empty body',
- 'patterns':[r".*: warning: suggest braces around empty body in an 'if' statement",
- r".*: warning: empty body in an if-statement",
- r".*: warning: suggest braces around empty body in an 'else' statement",
- r".*: warning: empty body in an else-statement"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wparentheses',
- 'description':'Suggest adding parentheses',
- 'patterns':[r".*: warning: suggest explicit braces to avoid ambiguous 'else'",
- r".*: warning: suggest parentheses around arithmetic in operand of '.+'",
- r".*: warning: suggest parentheses around comparison in operand of '.+'",
- r".*: warning: suggest parentheses around '.+?' .+ '.+?'",
- r".*: warning: suggest parentheses around assignment used as truth value"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Static variable used in non-static inline function',
- 'patterns':[r".*: warning: '.+' is static but used in inline function '.+' which is not static"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wimplicit int',
- 'description':'No type or storage class (will default to int)',
- 'patterns':[r".*: warning: data definition has no type or storage class"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: type defaults to 'int' in declaration of '.+'"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: parameter names \(without types\) in function declaration"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-aliasing',
- 'description':'Dereferencing <foo> breaks strict aliasing rules',
- 'patterns':[r".*: warning: dereferencing .* break strict-aliasing rules"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-to-int-cast',
- 'description':'Cast from pointer to integer of different size',
- 'patterns':[r".*: warning: cast from pointer to integer of different size"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wint-to-pointer-cast',
- 'description':'Cast to pointer from integer of different size',
- 'patterns':[r".*: warning: cast to pointer from integer of different size"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Symbol redefined',
- 'patterns':[r".*: warning: "".+"" redefined"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: this is the location of the previous definition"] },
- { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'ld: type and size of dynamic symbol are not defined',
- 'patterns':[r".*: warning: type and size of dynamic symbol `.+' are not defined"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Pointer from integer without cast',
- 'patterns':[r".*: warning: assignment makes pointer from integer without a cast"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Pointer from integer without cast',
- 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes pointer from integer without a cast"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Integer from pointer without cast',
- 'patterns':[r".*: warning: assignment makes integer from pointer without a cast"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Integer from pointer without cast',
- 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes integer from pointer without a cast"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Integer from pointer without cast',
- 'patterns':[r".*: warning: return makes integer from pointer without a cast"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunknown-pragmas',
- 'description':'Ignoring pragma',
- 'patterns':[r".*: warning: ignoring #pragma .+"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered',
- 'description':'Variable might be clobbered by longjmp or vfork',
- 'patterns':[r".*: warning: variable '.+' might be clobbered by 'longjmp' or 'vfork'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered',
- 'description':'Argument might be clobbered by longjmp or vfork',
- 'patterns':[r".*: warning: argument '.+' might be clobbered by 'longjmp' or 'vfork'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wredundant-decls',
- 'description':'Redundant declaration',
- 'patterns':[r".*: warning: redundant redeclaration of '.+'"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: previous declaration of '.+' was here"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wswitch-enum',
- 'description':'Enum value not handled in switch',
- 'patterns':[r".*: warning: enumeration value '.+' not handled in switch"] },
- { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'-encoding',
- 'description':'Java: Non-ascii characters used, but ascii encoding specified',
- 'patterns':[r".*: warning: unmappable character for encoding ascii"] },
- { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Java: Non-varargs call of varargs method with inexact argument type for last parameter',
- 'patterns':[r".*: warning: non-varargs call of varargs method with inexact argument type for last parameter"] },
- { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'aapt: No default translation',
- 'patterns':[r".*: warning: string '.+' has no default translation in .*"] },
- { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'aapt: Missing default or required localization',
- 'patterns':[r".*: warning: \*\*\*\* string '.+' has no default or required localization for '.+' in .+"] },
- { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'aapt: String marked untranslatable, but translation exists',
- 'patterns':[r".*: warning: string '.+' in .* marked untranslatable but exists in locale '??_??'"] },
- { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'aapt: empty span in string',
- 'patterns':[r".*: warning: empty '.+' span found in text '.+"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Taking address of temporary',
- 'patterns':[r".*: warning: taking address of temporary"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Possible broken line continuation',
- 'patterns':[r".*: warning: backslash and newline separated by space"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Warray-bounds',
- 'description':'Array subscript out of bounds',
- 'patterns':[r".*: warning: array subscript is above array bounds",
- r".*: warning: array subscript is below array bounds"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Decimal constant is unsigned only in ISO C90',
- 'patterns':[r".*: warning: this decimal constant is unsigned only in ISO C90"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmain',
- 'description':'main is usually a function',
- 'patterns':[r".*: warning: 'main' is usually a function"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Typedef ignored',
- 'patterns':[r".*: warning: 'typedef' was ignored in this declaration"] },
- { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Waddress',
- 'description':'Address always evaluates to true',
- 'patterns':[r".*: warning: the address of '.+' will always evaluate as 'true'"] },
- { 'category':'C/C++', 'severity':severity.FIXMENOW, 'members':[], 'option':'',
- 'description':'Freeing a non-heap object',
- 'patterns':[r".*: warning: attempt to free a non-heap object '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wchar-subscripts',
- 'description':'Array subscript has type char',
- 'patterns':[r".*: warning: array subscript has type 'char'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Constant too large for type',
- 'patterns':[r".*: warning: integer constant is too large for '.+' type"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow',
- 'description':'Constant too large for type, truncated',
- 'patterns':[r".*: warning: large integer implicitly truncated to unsigned type"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow',
- 'description':'Overflow in implicit constant conversion',
- 'patterns':[r".*: warning: overflow in implicit constant conversion"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Declaration does not declare anything',
- 'patterns':[r".*: warning: declaration 'class .+' does not declare anything"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wreorder',
- 'description':'Initialization order will be different',
- 'patterns':[r".*: warning: '.+' will be initialized after"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: '.+'"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: base '.+'"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: when initialized here"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-parameter-type',
- 'description':'Parameter type not specified',
- 'patterns':[r".*: warning: type of '.+' defaults to 'int'"] },
- { 'category':'gcc', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Invalid option for C file',
- 'patterns':[r".*: warning: command line option "".+"" is valid for C\+\+\/ObjC\+\+ but not for C"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'User warning',
- 'patterns':[r".*: warning: #warning "".+"""] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra',
- 'description':'Dereferencing void*',
- 'patterns':[r".*: warning: dereferencing 'void \*' pointer"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra',
- 'description':'Comparison of pointer to zero',
- 'patterns':[r".*: warning: ordered comparison of pointer with integer zero"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wwrite-strings',
- 'description':'Conversion of string constant to non-const char*',
- 'patterns':[r".*: warning: deprecated conversion from string constant to '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-prototypes',
- 'description':'Function declaration isn''t a prototype',
- 'patterns':[r".*: warning: function declaration isn't a prototype"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wignored-qualifiers',
- 'description':'Type qualifiers ignored on function return value',
- 'patterns':[r".*: warning: type qualifiers ignored on function return type"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'<foo> declared inside parameter list, scope limited to this definition',
- 'patterns':[r".*: warning: '.+' declared inside parameter list"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: its scope is only this definition or declaration, which is probably not what you want"] },
- { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment',
- 'description':'Line continuation inside comment',
- 'patterns':[r".*: warning: multi-line comment"] },
- { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment',
- 'description':'Comment inside comment',
- 'patterns':[r".*: warning: "".+"" within comment"] },
- { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'',
- 'description':'Extra tokens after #endif',
- 'patterns':[r".*: warning: extra tokens at end of #endif directive"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wenum-compare',
- 'description':'Comparison between different enums',
- 'patterns':[r".*: warning: comparison between 'enum .+' and 'enum .+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wconversion',
- 'description':'Implicit conversion of negative number to unsigned type',
- 'patterns':[r".*: warning: converting negative value '.+' to '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Passing NULL as non-pointer argument',
- 'patterns':[r".*: warning: passing NULL to non-pointer argument [0-9]+ of '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy',
- 'description':'Class seems unusable because of private ctor/dtor' ,
- 'patterns':[r".*: warning: all member functions in class '.+' are private"] },
+
+def tidy_warn_pattern(description, pattern):
+ return {
+ 'category': 'C/C++',
+ 'severity': Severity.TIDY,
+ 'description': 'clang-tidy ' + description,
+ 'patterns': [r'.*: .+\[' + pattern + r'\]$']
+ }
+
+
+def simple_tidy_warn_pattern(description):
+ return tidy_warn_pattern(description, description)
+
+
+def group_tidy_warn_pattern(description):
+ return tidy_warn_pattern(description, description + r'-.+')
+
+
+warn_patterns = [
+ # pylint:disable=line-too-long,g-inconsistent-quotes
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Security warning',
+ 'patterns': [r".*: warning: .+\[clang-analyzer-security.*\]"]},
+ {'category': 'make', 'severity': Severity.MEDIUM,
+ 'description': 'make: overriding commands/ignoring old commands',
+ 'patterns': [r".*: warning: overriding commands for target .+",
+ r".*: warning: ignoring old commands for target .+"]},
+ {'category': 'make', 'severity': Severity.HIGH,
+ 'description': 'make: LOCAL_CLANG is false',
+ 'patterns': [r".*: warning: LOCAL_CLANG is set to false"]},
+ {'category': 'make', 'severity': Severity.HIGH,
+ 'description': 'SDK App using platform shared library',
+ 'patterns': [r".*: warning: .+ \(.*app:sdk.*\) should not link to .+ \(native:platform\)"]},
+ {'category': 'make', 'severity': Severity.HIGH,
+ 'description': 'System module linking to a vendor module',
+ 'patterns': [r".*: warning: .+ \(.+\) should not link to .+ \(partition:.+\)"]},
+ {'category': 'make', 'severity': Severity.MEDIUM,
+ 'description': 'Invalid SDK/NDK linking',
+ 'patterns': [r".*: warning: .+ \(.+\) should not link to .+ \(.+\)"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-Wimplicit-function-declaration',
+ 'description': 'Implicit function declaration',
+ 'patterns': [r".*: warning: implicit declaration of function .+",
+ r".*: warning: implicitly declaring library function"]},
+ {'category': 'C/C++', 'severity': Severity.SKIP,
+ 'description': 'skip, conflicting types for ...',
+ 'patterns': [r".*: warning: conflicting types for '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-Wtype-limits',
+ 'description': 'Expression always evaluates to true or false',
+ 'patterns': [r".*: warning: comparison is always .+ due to limited range of data type",
+ r".*: warning: comparison of unsigned .*expression .+ is always true",
+ r".*: warning: comparison of unsigned .*expression .+ is always false"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH,
+ 'description': 'Potential leak of memory, bad free, use after free',
+ 'patterns': [r".*: warning: Potential leak of memory",
+ r".*: warning: Potential memory leak",
+ r".*: warning: Memory allocated by alloca\(\) should not be deallocated",
+ r".*: warning: Memory allocated by .+ should be deallocated by .+ not .+",
+ r".*: warning: 'delete' applied to a pointer that was allocated",
+ r".*: warning: Use of memory after it is freed",
+ r".*: warning: Argument to .+ is the address of .+ variable",
+ r".*: warning: Argument to free\(\) is offset by .+ of memory allocated by",
+ r".*: warning: Attempt to .+ released memory"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH,
+ 'description': 'Use transient memory for control value',
+ 'patterns': [r".*: warning: .+Using such transient memory for the control value is .*dangerous."]},
+ {'category': 'C/C++', 'severity': Severity.HIGH,
+ 'description': 'Return address of stack memory',
+ 'patterns': [r".*: warning: Address of stack memory .+ returned to caller",
+ r".*: warning: Address of stack memory .+ will be a dangling reference"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH,
+ 'description': 'Problem with vfork',
+ 'patterns': [r".*: warning: This .+ is prohibited after a successful vfork",
+ r".*: warning: Call to function '.+' is insecure "]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': 'infinite-recursion',
+ 'description': 'Infinite recursion',
+ 'patterns': [r".*: warning: all paths through this function will call itself"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH,
+ 'description': 'Potential buffer overflow',
+ 'patterns': [r".*: warning: Size argument is greater than .+ the destination buffer",
+ r".*: warning: Potential buffer overflow.",
+ r".*: warning: String copy function overflows destination buffer"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Incompatible pointer types',
+ 'patterns': [r".*: warning: assignment from incompatible pointer type",
+ r".*: warning: return from incompatible pointer type",
+ r".*: warning: passing argument [0-9]+ of '.*' from incompatible pointer type",
+ r".*: warning: initialization from incompatible pointer type"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-fno-builtin',
+ 'description': 'Incompatible declaration of built in function',
+ 'patterns': [r".*: warning: incompatible implicit declaration of built-in function .+"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-Wincompatible-library-redeclaration',
+ 'description': 'Incompatible redeclaration of library function',
+ 'patterns': [r".*: warning: incompatible redeclaration of library function .+"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH,
+ 'description': 'Null passed as non-null argument',
+ 'patterns': [r".*: warning: Null passed to a callee that requires a non-null"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunused-parameter',
+ 'description': 'Unused parameter',
+ 'patterns': [r".*: warning: unused parameter '.*'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunused',
+ 'description': 'Unused function, variable or label',
+ 'patterns': [r".*: warning: '.+' defined but not used",
+ r".*: warning: unused function '.+'",
+ r".*: warning: lambda capture .* is not used",
+ r".*: warning: private field '.+' is not used",
+ r".*: warning: unused variable '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunused-value',
+ 'description': 'Statement with no effect or result unused',
+ 'patterns': [r".*: warning: statement with no effect",
+ r".*: warning: expression result unused"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunused-result',
+ 'description': 'Ignoreing return value of function',
+ 'patterns': [r".*: warning: ignoring return value of function .+Wunused-result"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmissing-field-initializers',
+ 'description': 'Missing initializer',
+ 'patterns': [r".*: warning: missing initializer"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wdelete-non-virtual-dtor',
+ 'description': 'Need virtual destructor',
+ 'patterns': [r".*: warning: delete called .* has virtual functions but non-virtual destructor"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, near initialization for ...',
+ 'patterns': [r".*: warning: \(near initialization for '.+'\)"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wdate-time',
+ 'description': 'Expansion of data or time macro',
+ 'patterns': [r".*: warning: expansion of date or time macro is not reproducible"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wformat',
+ 'description': 'Format string does not match arguments',
+ 'patterns': [r".*: warning: format '.+' expects type '.+', but argument [0-9]+ has type '.+'",
+ r".*: warning: more '%' conversions than data arguments",
+ r".*: warning: data argument not used by format string",
+ r".*: warning: incomplete format specifier",
+ r".*: warning: unknown conversion type .* in format",
+ r".*: warning: format .+ expects .+ but argument .+Wformat=",
+ r".*: warning: field precision should have .+ but argument has .+Wformat",
+ r".*: warning: format specifies type .+ but the argument has .*type .+Wformat"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wformat-extra-args',
+ 'description': 'Too many arguments for format string',
+ 'patterns': [r".*: warning: too many arguments for format"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Too many arguments in call',
+ 'patterns': [r".*: warning: too many arguments in call to "]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wformat-invalid-specifier',
+ 'description': 'Invalid format specifier',
+ 'patterns': [r".*: warning: invalid .+ specifier '.+'.+format-invalid-specifier"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wsign-compare',
+ 'description': 'Comparison between signed and unsigned',
+ 'patterns': [r".*: warning: comparison between signed and unsigned",
+ r".*: warning: comparison of promoted \~unsigned with unsigned",
+ r".*: warning: signed and unsigned type in conditional expression"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Comparison between enum and non-enum',
+ 'patterns': [r".*: warning: enumeral and non-enumeral type in conditional expression"]},
+ {'category': 'libpng', 'severity': Severity.MEDIUM,
+ 'description': 'libpng: zero area',
+ 'patterns': [r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"]},
+ {'category': 'aapt', 'severity': Severity.MEDIUM,
+ 'description': 'aapt: no comment for public symbol',
+ 'patterns': [r".*: warning: No comment for public symbol .+"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmissing-braces',
+ 'description': 'Missing braces around initializer',
+ 'patterns': [r".*: warning: missing braces around initializer.*"]},
+ {'category': 'C/C++', 'severity': Severity.HARMLESS,
+ 'description': 'No newline at end of file',
+ 'patterns': [r".*: warning: no newline at end of file"]},
+ {'category': 'C/C++', 'severity': Severity.HARMLESS,
+ 'description': 'Missing space after macro name',
+ 'patterns': [r".*: warning: missing whitespace after the macro name"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wcast-align',
+ 'description': 'Cast increases required alignment',
+ 'patterns': [r".*: warning: cast from .* to .* increases required alignment .*"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wcast-qual',
+ 'description': 'Qualifier discarded',
+ 'patterns': [r".*: warning: passing argument [0-9]+ of '.+' discards qualifiers from pointer target type",
+ r".*: warning: assignment discards qualifiers from pointer target type",
+ r".*: warning: passing .+ to parameter of type .+ discards qualifiers",
+ r".*: warning: assigning to .+ from .+ discards qualifiers",
+ r".*: warning: initializing .+ discards qualifiers .+types-discards-qualifiers",
+ r".*: warning: return discards qualifiers from pointer target type"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunknown-attributes',
+ 'description': 'Unknown attribute',
+ 'patterns': [r".*: warning: unknown attribute '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wignored-attributes',
+ 'description': 'Attribute ignored',
+ 'patterns': [r".*: warning: '_*packed_*' attribute ignored",
+ r".*: warning: attribute declaration must precede definition .+ignored-attributes"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wvisibility',
+ 'description': 'Visibility problem',
+ 'patterns': [r".*: warning: declaration of '.+' will not be visible outside of this function"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wattributes',
+ 'description': 'Visibility mismatch',
+ 'patterns': [r".*: warning: '.+' declared with greater visibility than the type of its field '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Shift count greater than width of type',
+ 'patterns': [r".*: warning: (left|right) shift count >= width of type"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wextern-initializer',
+ 'description': 'extern <foo> is initialized',
+ 'patterns': [r".*: warning: '.+' initialized and declared 'extern'",
+ r".*: warning: 'extern' variable has an initializer"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wold-style-declaration',
+ 'description': 'Old style declaration',
+ 'patterns': [r".*: warning: 'static' is not at beginning of declaration"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wreturn-type',
+ 'description': 'Missing return value',
+ 'patterns': [r".*: warning: control reaches end of non-void function"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wimplicit-int',
+ 'description': 'Implicit int type',
+ 'patterns': [r".*: warning: type specifier missing, defaults to 'int'",
+ r".*: warning: type defaults to 'int' in declaration of '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmain-return-type',
+ 'description': 'Main function should return int',
+ 'patterns': [r".*: warning: return type of 'main' is not 'int'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wuninitialized',
+ 'description': 'Variable may be used uninitialized',
+ 'patterns': [r".*: warning: '.+' may be used uninitialized in this function"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-Wuninitialized',
+ 'description': 'Variable is used uninitialized',
+ 'patterns': [r".*: warning: '.+' is used uninitialized in this function",
+ r".*: warning: variable '.+' is uninitialized when used here"]},
+ {'category': 'ld', 'severity': Severity.MEDIUM, 'option': '-fshort-enums',
+ 'description': 'ld: possible enum size mismatch',
+ 'patterns': [r".*: warning: .* uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wpointer-sign',
+ 'description': 'Pointer targets differ in signedness',
+ 'patterns': [r".*: warning: pointer targets in initialization differ in signedness",
+ r".*: warning: pointer targets in assignment differ in signedness",
+ r".*: warning: pointer targets in return differ in signedness",
+ r".*: warning: pointer targets in passing argument [0-9]+ of '.+' differ in signedness"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wstrict-overflow',
+ 'description': 'Assuming overflow does not occur',
+ 'patterns': [r".*: warning: assuming signed overflow does not occur when assuming that .* is always (true|false)"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wempty-body',
+ 'description': 'Suggest adding braces around empty body',
+ 'patterns': [r".*: warning: suggest braces around empty body in an 'if' statement",
+ r".*: warning: empty body in an if-statement",
+ r".*: warning: suggest braces around empty body in an 'else' statement",
+ r".*: warning: empty body in an else-statement"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wparentheses',
+ 'description': 'Suggest adding parentheses',
+ 'patterns': [r".*: warning: suggest explicit braces to avoid ambiguous 'else'",
+ r".*: warning: suggest parentheses around arithmetic in operand of '.+'",
+ r".*: warning: suggest parentheses around comparison in operand of '.+'",
+ r".*: warning: logical not is only applied to the left hand side of this comparison",
+ r".*: warning: using the result of an assignment as a condition without parentheses",
+ r".*: warning: .+ has lower precedence than .+ be evaluated first .+Wparentheses",
+ r".*: warning: suggest parentheses around '.+?' .+ '.+?'",
+ r".*: warning: suggest parentheses around assignment used as truth value"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Static variable used in non-static inline function',
+ 'patterns': [r".*: warning: '.+' is static but used in inline function '.+' which is not static"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wimplicit int',
+ 'description': 'No type or storage class (will default to int)',
+ 'patterns': [r".*: warning: data definition has no type or storage class"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Null pointer',
+ 'patterns': [r".*: warning: Dereference of null pointer",
+ r".*: warning: Called .+ pointer is null",
+ r".*: warning: Forming reference to null pointer",
+ r".*: warning: Returning null reference",
+ r".*: warning: Null pointer passed as an argument to a 'nonnull' parameter",
+ r".*: warning: .+ results in a null pointer dereference",
+ r".*: warning: Access to .+ results in a dereference of a null pointer",
+ r".*: warning: Null pointer argument in"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, parameter name (without types) in function declaration',
+ 'patterns': [r".*: warning: parameter names \(without types\) in function declaration"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wstrict-aliasing',
+ 'description': 'Dereferencing <foo> breaks strict aliasing rules',
+ 'patterns': [r".*: warning: dereferencing .* break strict-aliasing rules"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wpointer-to-int-cast',
+ 'description': 'Cast from pointer to integer of different size',
+ 'patterns': [r".*: warning: cast from pointer to integer of different size",
+ r".*: warning: initialization makes pointer from integer without a cast"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wint-to-pointer-cast',
+ 'description': 'Cast to pointer from integer of different size',
+ 'patterns': [r".*: warning: cast to pointer from integer of different size"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Symbol redefined',
+ 'patterns': [r".*: warning: "".+"" redefined"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, ... location of the previous definition',
+ 'patterns': [r".*: warning: this is the location of the previous definition"]},
+ {'category': 'ld', 'severity': Severity.MEDIUM,
+ 'description': 'ld: type and size of dynamic symbol are not defined',
+ 'patterns': [r".*: warning: type and size of dynamic symbol `.+' are not defined"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Pointer from integer without cast',
+ 'patterns': [r".*: warning: assignment makes pointer from integer without a cast"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Pointer from integer without cast',
+ 'patterns': [r".*: warning: passing argument [0-9]+ of '.+' makes pointer from integer without a cast"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Integer from pointer without cast',
+ 'patterns': [r".*: warning: assignment makes integer from pointer without a cast"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Integer from pointer without cast',
+ 'patterns': [r".*: warning: passing argument [0-9]+ of '.+' makes integer from pointer without a cast"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Integer from pointer without cast',
+ 'patterns': [r".*: warning: return makes integer from pointer without a cast"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunknown-pragmas',
+ 'description': 'Ignoring pragma',
+ 'patterns': [r".*: warning: ignoring #pragma .+"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-W#pragma-messages',
+ 'description': 'Pragma warning messages',
+ 'patterns': [r".*: warning: .+W#pragma-messages"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wclobbered',
+ 'description': 'Variable might be clobbered by longjmp or vfork',
+ 'patterns': [r".*: warning: variable '.+' might be clobbered by 'longjmp' or 'vfork'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wclobbered',
+ 'description': 'Argument might be clobbered by longjmp or vfork',
+ 'patterns': [r".*: warning: argument '.+' might be clobbered by 'longjmp' or 'vfork'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wredundant-decls',
+ 'description': 'Redundant declaration',
+ 'patterns': [r".*: warning: redundant redeclaration of '.+'"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, previous declaration ... was here',
+ 'patterns': [r".*: warning: previous declaration of '.+' was here"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wswitch-enum',
+ 'description': 'Enum value not handled in switch',
+ 'patterns': [r".*: warning: .*enumeration value.* not handled in switch.+Wswitch"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wuser-defined-warnings',
+ 'description': 'User defined warnings',
+ 'patterns': [r".*: warning: .* \[-Wuser-defined-warnings\]$"]},
+ {'category': 'java', 'severity': Severity.MEDIUM, 'option': '-encoding',
+ 'description': 'Java: Non-ascii characters used, but ascii encoding specified',
+ 'patterns': [r".*: warning: unmappable character for encoding ascii"]},
+ {'category': 'java', 'severity': Severity.MEDIUM,
+ 'description': 'Java: Non-varargs call of varargs method with inexact argument type for last parameter',
+ 'patterns': [r".*: warning: non-varargs call of varargs method with inexact argument type for last parameter"]},
+ {'category': 'java', 'severity': Severity.MEDIUM,
+ 'description': 'Java: Unchecked method invocation',
+ 'patterns': [r".*: warning: \[unchecked\] unchecked method invocation: .+ in class .+"]},
+ {'category': 'java', 'severity': Severity.MEDIUM,
+ 'description': 'Java: Unchecked conversion',
+ 'patterns': [r".*: warning: \[unchecked\] unchecked conversion"]},
+ {'category': 'java', 'severity': Severity.MEDIUM,
+ 'description': '_ used as an identifier',
+ 'patterns': [r".*: warning: '_' used as an identifier"]},
+ {'category': 'java', 'severity': Severity.HIGH,
+ 'description': 'Use of internal proprietary API',
+ 'patterns': [r".*: warning: .* is internal proprietary API and may be removed"]},
+
+ # Warnings from Javac
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description': 'Java: Use of deprecated member',
+ 'patterns': [r'.*: warning: \[deprecation\] .+']},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description': 'Java: Unchecked conversion',
+ 'patterns': [r'.*: warning: \[unchecked\] .+']},
+
+ # Begin warnings generated by Error Prone
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: @Multibinds is a more efficient and declarative mechanism for ensuring that a set multibinding is present in the graph.',
+ 'patterns': [r".*: warning: \[EmptySetMultibindingContributions\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Add a private constructor to modules that will not be instantiated by Dagger.',
+ 'patterns': [r".*: warning: \[PrivateConstructorForNoninstantiableModuleTest\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: @Binds is a more efficient and declarative mechanism for delegating a binding.',
+ 'patterns': [r".*: warning: \[UseBinds\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Field name is CONSTANT CASE, but field is not static and final',
+ 'patterns': [r".*: warning: \[ConstantField\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Deprecated item is not annotated with @Deprecated',
+ 'patterns': [r".*: warning: \[DepAnn\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Prefer \'L\' to \'l\' for the suffix to long literals',
+ 'patterns': [r".*: warning: \[LongLiteralLowerCaseSuffix\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: C-style array declarations should not be used',
+ 'patterns': [r".*: warning: \[MixedArrayDimensions\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Variable declarations should declare only one variable',
+ 'patterns': [r".*: warning: \[MultiVariableDeclaration\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Source files should not contain multiple top-level class declarations',
+ 'patterns': [r".*: warning: \[MultipleTopLevelClasses\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Package names should match the directory they are declared in',
+ 'patterns': [r".*: warning: \[PackageLocation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Utility classes (only static members) are not designed to be instantiated and should be made noninstantiable with a default constructor.',
+ 'patterns': [r".*: warning: \[PrivateConstructorForUtilityClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Unused imports',
+ 'patterns': [r".*: warning: \[RemoveUnusedImports\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Unchecked exceptions do not need to be declared in the method signature.',
+ 'patterns': [r".*: warning: \[ThrowsUncheckedException\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Using static imports for types is unnecessary',
+ 'patterns': [r".*: warning: \[UnnecessaryStaticImport\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.LOW,
+ 'description':
+ 'Java: Wildcard imports, static or otherwise, should not be used',
+ 'patterns': [r".*: warning: \[WildcardImport\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Subclasses of Fragment must be instantiable via Class#newInstance(): the class must be public, static and have a public nullary constructor',
+ 'patterns': [r".*: warning: \[FragmentNotInstantiable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Hardcoded reference to /sdcard',
+ 'patterns': [r".*: warning: \[HardCodedSdCardPath\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: @AssistedInject and @Inject should not be used on different constructors in the same class.',
+ 'patterns': [r".*: warning: \[AssistedInjectAndInjectOnConstructors\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Constructors on abstract classes are never directly @Injected, only the constructors of their subclasses can be @Inject\'ed.',
+ 'patterns': [r".*: warning: \[InjectOnConstructorOfAbstractClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Injection frameworks currently don\'t understand Qualifiers in TYPE PARAMETER or TYPE USE contexts.',
+ 'patterns': [r".*: warning: \[QualifierWithTypeUse\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: This code declares a binding for a common value type without a Qualifier annotation.',
+ 'patterns': [r".*: warning: \[BindingToUnqualifiedCommonType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: This method is not annotated with @Inject, but it overrides a method that is annotated with @com.google.inject.Inject. Guice will inject this method, and it is recommended to annotate it explicitly.',
+ 'patterns': [r".*: warning: \[OverridesGuiceInjectableMethod\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Double-checked locking on non-volatile fields is unsafe',
+ 'patterns': [r".*: warning: \[DoubleCheckedLocking\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Enums should always be immutable',
+ 'patterns': [r".*: warning: \[ImmutableEnumChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Writes to static fields should not be guarded by instance locks',
+ 'patterns': [r".*: warning: \[StaticGuardedByInstance\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Synchronizing on non-final fields is not safe: if the field is ever updated, different threads may end up locking on different objects.',
+ 'patterns': [r".*: warning: \[SynchronizeOnNonFinalField\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Method reference is ambiguous',
+ 'patterns': [r".*: warning: \[AmbiguousMethodReference\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: A different potential argument is more similar to the name of the parameter than the existing argument; this may be an error',
+ 'patterns': [r".*: warning: \[ArgumentParameterMismatch\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Assertions may be disabled at runtime and do not guarantee that execution will halt here; consider throwing an exception instead',
+ 'patterns': [r".*: warning: \[AssertFalse\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Classes that implement Annotation must override equals and hashCode. Consider using AutoAnnotation instead of implementing Annotation by hand.',
+ 'patterns': [r".*: warning: \[BadAnnotationImplementation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Possible sign flip from narrowing conversion',
+ 'patterns': [r".*: warning: \[BadComparable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: BigDecimal(double) and BigDecimal.valueOf(double) may lose precision, prefer BigDecimal(String) or BigDecimal(long)',
+ 'patterns': [r".*: warning: \[BigDecimalLiteralDouble\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: valueOf or autoboxing provides better time and space performance',
+ 'patterns': [r".*: warning: \[BoxedPrimitiveConstructor\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Mockito cannot mock final classes',
+ 'patterns': [r".*: warning: \[CannotMockFinalClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Inner class is non-static but does not reference enclosing class',
+ 'patterns': [r".*: warning: \[ClassCanBeStatic\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Class.newInstance() bypasses exception checking; prefer getConstructor().newInstance()',
+ 'patterns': [r".*: warning: \[ClassNewInstance\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Implicit use of the platform default charset, which can result in e.g. non-ASCII characters being silently replaced with \'?\' in many environments',
+ 'patterns': [r".*: warning: \[DefaultCharset\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: This code, which counts elements using a loop, can be replaced by a simpler library method',
+ 'patterns': [r".*: warning: \[ElementsCountedInLoop\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Empty top-level type declaration',
+ 'patterns': [r".*: warning: \[EmptyTopLevelDeclaration\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Classes that override equals should also override hashCode.',
+ 'patterns': [r".*: warning: \[EqualsHashCode\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: An equality test between objects with incompatible types always returns false',
+ 'patterns': [r".*: warning: \[EqualsIncompatibleType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: If you return or throw from a finally, then values returned or thrown from the try-catch block will be ignored. Consider using try-with-resources instead.',
+ 'patterns': [r".*: warning: \[Finally\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Overloads will be ambiguous when passing lambda arguments',
+ 'patterns': [r".*: warning: \[FunctionalInterfaceClash\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Calling getClass() on an enum may return a subclass of the enum type',
+ 'patterns': [r".*: warning: \[GetClassOnEnum\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: This annotation has incompatible modifiers as specified by its @IncompatibleModifiers annotation',
+ 'patterns': [r".*: warning: \[IncompatibleModifiers\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Please also override int read(byte[], int, int), otherwise multi-byte reads from this input stream are likely to be slow.',
+ 'patterns': [r".*: warning: \[InputStreamSlowMultibyteRead\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Class should not implement both `Iterable` and `Iterator`',
+ 'patterns': [r".*: warning: \[IterableAndIterator\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Floating-point comparison without error tolerance',
+ 'patterns': [r".*: warning: \[JUnit3FloatingPointComparisonWithoutDelta\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Test class inherits from JUnit 3\'s TestCase but has JUnit 4 @Test annotations.',
+ 'patterns': [r".*: warning: \[JUnitAmbiguousTestClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: The Google Java Style Guide requires switch statements to have an explicit default',
+ 'patterns': [r".*: warning: \[MissingCasesInEnumSwitch\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Not calling fail() when expecting an exception masks bugs',
+ 'patterns': [r".*: warning: \[MissingFail\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: method overrides method in supertype; expected @Override',
+ 'patterns': [r".*: warning: \[MissingOverride\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Compound assignments to bytes, shorts, chars, and floats hide dangerous casts',
+ 'patterns': [r".*: warning: \[NarrowingCompoundAssignment\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: This update of a volatile variable is non-atomic',
+ 'patterns': [r".*: warning: \[NonAtomicVolatileUpdate\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Static import of member uses non-canonical name',
+ 'patterns': [r".*: warning: \[NonCanonicalStaticMemberImport\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: equals method doesn\'t override Object.equals',
+ 'patterns': [r".*: warning: \[NonOverridingEquals\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Constructors should not be annotated with @Nullable since they cannot return null',
+ 'patterns': [r".*: warning: \[NullableConstructor\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: @Nullable should not be used for primitive types since they cannot be null',
+ 'patterns': [r".*: warning: \[NullablePrimitive\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: void-returning methods should not be annotated with @Nullable, since they cannot return null',
+ 'patterns': [r".*: warning: \[NullableVoid\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Use grouping parenthesis to make the operator precedence explicit',
+ 'patterns': [r".*: warning: \[OperatorPrecedence\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Preconditions only accepts the %s placeholder in error message strings',
+ 'patterns': [r".*: warning: \[PreconditionsInvalidPlaceholder\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Passing a primitive array to a varargs method is usually wrong',
+ 'patterns': [r".*: warning: \[PrimitiveArrayPassedToVarargsMethod\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Protobuf fields cannot be null, so this check is redundant',
+ 'patterns': [r".*: warning: \[ProtoFieldPreconditionsCheckNotNull\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Thrown exception is a subtype of another',
+ 'patterns': [r".*: warning: \[RedundantThrows\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Comparison using reference equality instead of value equality',
+ 'patterns': [r".*: warning: \[ReferenceEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: This annotation is missing required modifiers as specified by its @RequiredModifiers annotation',
+ 'patterns': [r".*: warning: \[RequiredModifiers\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: A static variable or method should not be accessed from an object instance',
+ 'patterns': [r".*: warning: \[StaticAccessedFromInstance\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: String comparison using reference equality instead of value equality',
+ 'patterns': [r".*: warning: \[StringEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Truth Library assert is called on a constant.',
+ 'patterns': [r".*: warning: \[TruthConstantAsserts\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: An object is tested for equality to itself using Truth Libraries.',
+ 'patterns': [r".*: warning: \[TruthSelfEquals\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Declaring a type parameter that is only used in the return type is a misuse of generics: operations on the type parameter are unchecked, it hides unsafe casts at invocations of the method, and it interacts badly with method overload resolution.',
+ 'patterns': [r".*: warning: \[TypeParameterUnusedInFormals\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Unsynchronized method overrides a synchronized method.',
+ 'patterns': [r".*: warning: \[UnsynchronizedOverridesSynchronized\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Non-constant variable missing @Var annotation',
+ 'patterns': [r".*: warning: \[Var\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.MEDIUM,
+ 'description':
+ 'Java: Because of spurious wakeups, Object.wait() and Condition.await() must always be called in a loop',
+ 'patterns': [r".*: warning: \[WaitNotInLoop\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Log tag too long, cannot exceed 23 characters.',
+ 'patterns': [r".*: warning: \[IsLoggableTagLength\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Certain resources in `android.R.string` have names that do not match their content',
+ 'patterns': [r".*: warning: \[MislabeledAndroidString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Return value of android.graphics.Rect.intersect() must be checked',
+ 'patterns': [r".*: warning: \[RectIntersectReturnValueIgnored\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Static and default methods in interfaces are not allowed in android builds.',
+ 'patterns': [r".*: warning: \[StaticOrDefaultInterfaceMethod\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Incompatible type as argument to Object-accepting Java collections method',
+ 'patterns': [r".*: warning: \[CollectionIncompatibleType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @CompatibleWith\'s value is not a type argument.',
+ 'patterns': [r".*: warning: \[CompatibleWithAnnotationMisuse\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Passing argument to a generic method with an incompatible type.',
+ 'patterns': [r".*: warning: \[IncompatibleArgumentType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Invalid printf-style format string',
+ 'patterns': [r".*: warning: \[FormatString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Invalid format string passed to formatting method.',
+ 'patterns': [r".*: warning: \[FormatStringAnnotation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @AssistedInject and @Inject cannot be used on the same constructor.',
+ 'patterns': [r".*: warning: \[AssistedInjectAndInjectOnSameConstructor\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @AutoFactory and @Inject should not be used in the same type.',
+ 'patterns': [r".*: warning: \[AutoFactoryAtInject\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Injected constructors cannot be optional nor have binding annotations',
+ 'patterns': [r".*: warning: \[InjectedConstructorAnnotations\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: A scoping annotation\'s Target should include TYPE and METHOD.',
+ 'patterns': [r".*: warning: \[InjectInvalidTargetingOnScopingAnnotation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Abstract and default methods are not injectable with javax.inject.Inject',
+ 'patterns': [r".*: warning: \[JavaxInjectOnAbstractMethod\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @javax.inject.Inject cannot be put on a final field.',
+ 'patterns': [r".*: warning: \[JavaxInjectOnFinalField\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: This class has more than one @Inject-annotated constructor. Please remove the @Inject annotation from all but one of them.',
+ 'patterns': [r".*: warning: \[MoreThanOneInjectableConstructor\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Using more than one qualifier annotation on the same element is not allowed.',
+ 'patterns': [r".*: warning: \[InjectMoreThanOneQualifier\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: A class can be annotated with at most one scope annotation.',
+ 'patterns': [r".*: warning: \[InjectMoreThanOneScopeAnnotationOnClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Annotations cannot be both Scope annotations and Qualifier annotations: this causes confusion when trying to use them.',
+ 'patterns': [r".*: warning: \[OverlappingQualifierAndScopeAnnotation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Qualifier applied to a method that isn\'t a @Provides method. This method won\'t be used for dependency injection',
+ 'patterns': [r".*: warning: \[QualifierOnMethodWithoutProvides\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Scope annotation on an interface or abstact class is not allowed',
+ 'patterns': [r".*: warning: \[InjectScopeAnnotationOnInterfaceOrAbstractClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Scoping and qualifier annotations must have runtime retention.',
+ 'patterns': [r".*: warning: \[InjectScopeOrQualifierAnnotationRetention\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: `@Multibinds` is the new way to declare multibindings.',
+ 'patterns': [r".*: warning: \[MultibindsInsteadOfMultibindings\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Dagger @Provides methods may not return null unless annotated with @Nullable',
+ 'patterns': [r".*: warning: \[DaggerProvidesNull\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Scope annotation on implementation class of AssistedInject factory is not allowed',
+ 'patterns': [r".*: warning: \[GuiceAssistedInjectScoping\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: A constructor cannot have two @Assisted parameters of the same type unless they are disambiguated with named @Assisted annotations.',
+ 'patterns': [r".*: warning: \[GuiceAssistedParameters\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Although Guice allows injecting final fields, doing so is disallowed because the injected value may not be visible to other threads.',
+ 'patterns': [r".*: warning: \[GuiceInjectOnFinalField\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: This method is not annotated with @Inject, but it overrides a method that is annotated with @javax.inject.Inject. The method will not be Injected.',
+ 'patterns': [r".*: warning: \[OverridesJavaxInjectableMethod\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @Provides methods need to be declared in a Module to have any effect.',
+ 'patterns': [r".*: warning: \[ProvidesMethodOutsideOfModule\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Checks for unguarded accesses to fields and methods with @GuardedBy annotations',
+ 'patterns': [r".*: warning: \[GuardedByChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Invalid @GuardedBy expression',
+ 'patterns': [r".*: warning: \[GuardedByValidator\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Type declaration annotated with @Immutable is not immutable',
+ 'patterns': [r".*: warning: \[Immutable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: This method does not acquire the locks specified by its @LockMethod annotation',
+ 'patterns': [r".*: warning: \[LockMethodChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: This method does not acquire the locks specified by its @UnlockMethod annotation',
+ 'patterns': [r".*: warning: \[UnlockMethod\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: An argument is more similar to a different parameter; the arguments may have been swapped.',
+ 'patterns': [r".*: warning: \[ArgumentParameterSwap\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Reference equality used to compare arrays',
+ 'patterns': [r".*: warning: \[ArrayEquals\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: hashcode method on array does not hash array contents',
+ 'patterns': [r".*: warning: \[ArrayHashCode\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Calling toString on an array does not provide useful information',
+ 'patterns': [r".*: warning: \[ArrayToString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Arrays.asList does not autobox primitive arrays, as one might expect.',
+ 'patterns': [r".*: warning: \[ArraysAsListPrimitiveArray\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: AsyncCallable should not return a null Future, only a Future whose result is null.',
+ 'patterns': [r".*: warning: \[AsyncCallableReturnsNull\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: AsyncFunction should not return a null Future, only a Future whose result is null.',
+ 'patterns': [r".*: warning: \[AsyncFunctionReturnsNull\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Shift by an amount that is out of range',
+ 'patterns': [r".*: warning: \[BadShiftAmount\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: The called constructor accepts a parameter with the same name and type as one of its caller\'s parameters, but its caller doesn\'t pass that parameter to it. It\'s likely that it was intended to.',
+ 'patterns': [r".*: warning: \[ChainingConstructorIgnoresParameter\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Ignored return value of method that is annotated with @CheckReturnValue',
+ 'patterns': [r".*: warning: \[CheckReturnValue\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: The source file name should match the name of the top-level class it contains',
+ 'patterns': [r".*: warning: \[ClassName\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: This comparison method violates the contract',
+ 'patterns': [r".*: warning: \[ComparisonContractViolated\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Comparison to value that is out of range for the compared type',
+ 'patterns': [r".*: warning: \[ComparisonOutOfRange\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Non-compile-time constant expression passed to parameter with @CompileTimeConstant type annotation.',
+ 'patterns': [r".*: warning: \[CompileTimeConstant\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Compile-time constant expression overflows',
+ 'patterns': [r".*: warning: \[ConstantOverflow\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Exception created but not thrown',
+ 'patterns': [r".*: warning: \[DeadException\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Division by integer literal zero',
+ 'patterns': [r".*: warning: \[DivZero\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Empty statement after if',
+ 'patterns': [r".*: warning: \[EmptyIf\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: == NaN always returns false; use the isNaN methods instead',
+ 'patterns': [r".*: warning: \[EqualsNaN\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Method annotated @ForOverride must be protected or package-private and only invoked from declaring class',
+ 'patterns': [r".*: warning: \[ForOverride\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Casting a lambda to this @FunctionalInterface can cause a behavior change from casting to a functional superinterface, which is surprising to users. Prefer decorator methods to this surprising behavior.',
+ 'patterns': [r".*: warning: \[FunctionalInterfaceMethodChanged\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Futures.getChecked requires a checked exception type with a standard constructor.',
+ 'patterns': [r".*: warning: \[FuturesGetCheckedIllegalExceptionType\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Calling getClass() on an annotation may return a proxy class',
+ 'patterns': [r".*: warning: \[GetClassOnAnnotation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Calling getClass() on an object of type Class returns the Class object for java.lang.Class; you probably meant to operate on the object directly',
+ 'patterns': [r".*: warning: \[GetClassOnClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: An object is tested for equality to itself using Guava Libraries',
+ 'patterns': [r".*: warning: \[GuavaSelfEquals\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: contains() is a legacy method that is equivalent to containsValue()',
+ 'patterns': [r".*: warning: \[HashtableContains\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Writing "a && a", "a || a", "a & a", or "a | a" is equivalent to "a".',
+ 'patterns': [r".*: warning: \[IdentityBinaryExpression\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Modifying an immutable collection is guaranteed to throw an exception and leave the collection unmodified',
+ 'patterns': [r".*: warning: \[ImmutableModification\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: This method always recurses, and will cause a StackOverflowError',
+ 'patterns': [r".*: warning: \[InfiniteRecursion\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: A standard cryptographic operation is used in a mode that is prone to vulnerabilities',
+ 'patterns': [r".*: warning: \[InsecureCryptoUsage\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Invalid syntax used for a regular expression',
+ 'patterns': [r".*: warning: \[InvalidPatternSyntax\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: The argument to Class#isInstance(Object) should not be a Class',
+ 'patterns': [r".*: warning: \[IsInstanceOfClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: jMock tests must have a @RunWith(JMock.class) annotation, or the Mockery field must have a @Rule JUnit annotation',
+ 'patterns': [r".*: warning: \[JMockTestWithoutRunWithOrRuleAnnotation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Test method will not be run; please prefix name with "test"',
+ 'patterns': [r".*: warning: \[JUnit3TestNotRun\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: setUp() method will not be run; Please add a @Before annotation',
+ 'patterns': [r".*: warning: \[JUnit4SetUpNotRun\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: tearDown() method will not be run; Please add an @After annotation',
+ 'patterns': [r".*: warning: \[JUnit4TearDownNotRun\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Test method will not be run; please add @Test annotation',
+ 'patterns': [r".*: warning: \[JUnit4TestNotRun\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use of "YYYY" (week year) in a date pattern without "ww" (week in year). You probably meant to use "yyyy" (year) instead.',
+ 'patterns': [r".*: warning: \[MisusedWeekYear\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: A bug in Mockito will cause this test to fail at runtime with a ClassCastException',
+ 'patterns': [r".*: warning: \[MockitoCast\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Missing method call for verify(mock) here',
+ 'patterns': [r".*: warning: \[MockitoUsage\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Using a collection function with itself as the argument.',
+ 'patterns': [r".*: warning: \[ModifyingCollectionWithItself\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @NoAllocation was specified on this method, but something was found that would trigger an allocation',
+ 'patterns': [r".*: warning: \[NoAllocation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Static import of type uses non-canonical name',
+ 'patterns': [r".*: warning: \[NonCanonicalStaticImport\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: @CompileTimeConstant parameters should be final or effectively final',
+ 'patterns': [r".*: warning: \[NonFinalCompileTimeConstant\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Calling getAnnotation on an annotation that is not retained at runtime.',
+ 'patterns': [r".*: warning: \[NonRuntimeAnnotation\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Numeric comparison using reference equality instead of value equality',
+ 'patterns': [r".*: warning: \[NumericEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Comparison using reference equality instead of value equality',
+ 'patterns': [r".*: warning: \[OptionalEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Varargs doesn\'t agree for overridden method',
+ 'patterns': [r".*: warning: \[Overrides\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Declaring types inside package-info.java files is very bad form',
+ 'patterns': [r".*: warning: \[PackageInfo\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Literal passed as first argument to Preconditions.checkNotNull() can never be null',
+ 'patterns': [r".*: warning: \[PreconditionsCheckNotNull\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: First argument to `Preconditions.checkNotNull()` is a primitive rather than an object reference',
+ 'patterns': [r".*: warning: \[PreconditionsCheckNotNullPrimitive\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Protobuf fields cannot be null',
+ 'patterns': [r".*: warning: \[ProtoFieldNullComparison\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Comparing protobuf fields of type String using reference equality',
+ 'patterns': [r".*: warning: \[ProtoStringFieldReferenceEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Use Random.nextInt(int). Random.nextInt() % n can have negative results',
+ 'patterns': [r".*: warning: \[RandomModInteger\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Check for non-whitelisted callers to RestrictedApiChecker.',
+ 'patterns': [r".*: warning: \[RestrictedApiChecker\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Return value of this method must be used',
+ 'patterns': [r".*: warning: \[ReturnValueIgnored\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Variable assigned to itself',
+ 'patterns': [r".*: warning: \[SelfAssignment\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: An object is compared to itself',
+ 'patterns': [r".*: warning: \[SelfComparison\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Variable compared to itself',
+ 'patterns': [r".*: warning: \[SelfEquality\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: An object is tested for equality to itself',
+ 'patterns': [r".*: warning: \[SelfEquals\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Comparison of a size >= 0 is always true, did you intend to check for non-emptiness?',
+ 'patterns': [r".*: warning: \[SizeGreaterThanOrEqualsZero\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Calling toString on a Stream does not provide useful information',
+ 'patterns': [r".*: warning: \[StreamToString\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: StringBuilder does not have a char constructor; this invokes the int constructor.',
+ 'patterns': [r".*: warning: \[StringBuilderInitWithChar\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Suppressing "deprecated" is probably a typo for "deprecation"',
+ 'patterns': [r".*: warning: \[SuppressWarningsDeprecated\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: throwIfUnchecked(knownCheckedException) is a no-op.',
+ 'patterns': [r".*: warning: \[ThrowIfUncheckedKnownChecked\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Catching Throwable/Error masks failures from fail() or assert*() in the try block',
+ 'patterns': [r".*: warning: \[TryFailThrowable\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Type parameter used as type qualifier',
+ 'patterns': [r".*: warning: \[TypeParameterQualifier\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Non-generic methods should not be invoked with type arguments',
+ 'patterns': [r".*: warning: \[UnnecessaryTypeArgument\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Instance created but never used',
+ 'patterns': [r".*: warning: \[UnusedAnonymousClass\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Collection is modified in place, but the result is not used',
+ 'patterns': [r".*: warning: \[UnusedCollectionModifiedInPlace\] .+"]},
+ {'category': 'java',
+ 'severity': Severity.HIGH,
+ 'description':
+ 'Java: Method parameter has wrong package',
+ 'patterns': [r".*: warning: \[ParameterPackage\] .+"]},
+
+ # End warnings generated by Error Prone
+
+ {'category': 'java',
+ 'severity': Severity.UNKNOWN,
+ 'description': 'Java: Unclassified/unrecognized warnings',
+ 'patterns': [r".*: warning: \[.+\] .+"]},
+
+ {'category': 'aapt', 'severity': Severity.MEDIUM,
+ 'description': 'aapt: No default translation',
+ 'patterns': [r".*: warning: string '.+' has no default translation in .*"]},
+ {'category': 'aapt', 'severity': Severity.MEDIUM,
+ 'description': 'aapt: Missing default or required localization',
+ 'patterns': [r".*: warning: \*\*\*\* string '.+' has no default or required localization for '.+' in .+"]},
+ {'category': 'aapt', 'severity': Severity.MEDIUM,
+ 'description': 'aapt: String marked untranslatable, but translation exists',
+ 'patterns': [r".*: warning: string '.+' in .* marked untranslatable but exists in locale '??_??'"]},
+ {'category': 'aapt', 'severity': Severity.MEDIUM,
+ 'description': 'aapt: empty span in string',
+ 'patterns': [r".*: warning: empty '.+' span found in text '.+"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Taking address of temporary',
+ 'patterns': [r".*: warning: taking address of temporary"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Taking address of packed member',
+ 'patterns': [r".*: warning: taking address of packed member"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Possible broken line continuation',
+ 'patterns': [r".*: warning: backslash and newline separated by space"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wundefined-var-template',
+ 'description': 'Undefined variable template',
+ 'patterns': [r".*: warning: instantiation of variable .* no definition is available"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wundefined-inline',
+ 'description': 'Inline function is not defined',
+ 'patterns': [r".*: warning: inline function '.*' is not defined"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Warray-bounds',
+ 'description': 'Array subscript out of bounds',
+ 'patterns': [r".*: warning: array subscript is above array bounds",
+ r".*: warning: Array subscript is undefined",
+ r".*: warning: array subscript is below array bounds"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Excess elements in initializer',
+ 'patterns': [r".*: warning: excess elements in .+ initializer"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Decimal constant is unsigned only in ISO C90',
+ 'patterns': [r".*: warning: this decimal constant is unsigned only in ISO C90"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmain',
+ 'description': 'main is usually a function',
+ 'patterns': [r".*: warning: 'main' is usually a function"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Typedef ignored',
+ 'patterns': [r".*: warning: 'typedef' was ignored in this declaration"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-Waddress',
+ 'description': 'Address always evaluates to true',
+ 'patterns': [r".*: warning: the address of '.+' will always evaluate as 'true'"]},
+ {'category': 'C/C++', 'severity': Severity.FIXMENOW,
+ 'description': 'Freeing a non-heap object',
+ 'patterns': [r".*: warning: attempt to free a non-heap object '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wchar-subscripts',
+ 'description': 'Array subscript has type char',
+ 'patterns': [r".*: warning: array subscript .+ type 'char'.+Wchar-subscripts"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Constant too large for type',
+ 'patterns': [r".*: warning: integer constant is too large for '.+' type"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Woverflow',
+ 'description': 'Constant too large for type, truncated',
+ 'patterns': [r".*: warning: large integer implicitly truncated to unsigned type"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Winteger-overflow',
+ 'description': 'Overflow in expression',
+ 'patterns': [r".*: warning: overflow in expression; .*Winteger-overflow"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Woverflow',
+ 'description': 'Overflow in implicit constant conversion',
+ 'patterns': [r".*: warning: overflow in implicit constant conversion"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Declaration does not declare anything',
+ 'patterns': [r".*: warning: declaration 'class .+' does not declare anything"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wreorder',
+ 'description': 'Initialization order will be different',
+ 'patterns': [r".*: warning: '.+' will be initialized after",
+ r".*: warning: field .+ will be initialized after .+Wreorder"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, ....',
+ 'patterns': [r".*: warning: '.+'"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, base ...',
+ 'patterns': [r".*: warning: base '.+'"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, when initialized here',
+ 'patterns': [r".*: warning: when initialized here"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmissing-parameter-type',
+ 'description': 'Parameter type not specified',
+ 'patterns': [r".*: warning: type of '.+' defaults to 'int'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmissing-declarations',
+ 'description': 'Missing declarations',
+ 'patterns': [r".*: warning: declaration does not declare anything"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wmissing-noreturn',
+ 'description': 'Missing noreturn',
+ 'patterns': [r".*: warning: function '.*' could be declared with attribute 'noreturn'"]},
+ # pylint:disable=anomalous-backslash-in-string
+ # TODO(chh): fix the backslash pylint warning.
+ {'category': 'gcc', 'severity': Severity.MEDIUM,
+ 'description': 'Invalid option for C file',
+ 'patterns': [r".*: warning: command line option "".+"" is valid for C\+\+\/ObjC\+\+ but not for C"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'User warning',
+ 'patterns': [r".*: warning: #warning "".+"""]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wvexing-parse',
+ 'description': 'Vexing parsing problem',
+ 'patterns': [r".*: warning: empty parentheses interpreted as a function declaration"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wextra',
+ 'description': 'Dereferencing void*',
+ 'patterns': [r".*: warning: dereferencing 'void \*' pointer"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Comparison of pointer and integer',
+ 'patterns': [r".*: warning: ordered comparison of pointer with integer zero",
+ r".*: warning: .*comparison between pointer and integer"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Use of error-prone unary operator',
+ 'patterns': [r".*: warning: use of unary operator that may be intended as compound assignment"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wwrite-strings',
+ 'description': 'Conversion of string constant to non-const char*',
+ 'patterns': [r".*: warning: deprecated conversion from string constant to '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wstrict-prototypes',
+ 'description': 'Function declaration isn''t a prototype',
+ 'patterns': [r".*: warning: function declaration isn't a prototype"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wignored-qualifiers',
+ 'description': 'Type qualifiers ignored on function return value',
+ 'patterns': [r".*: warning: type qualifiers ignored on function return type",
+ r".*: warning: .+ type qualifier .+ has no effect .+Wignored-qualifiers"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': '<foo> declared inside parameter list, scope limited to this definition',
+ 'patterns': [r".*: warning: '.+' declared inside parameter list"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, its scope is only this ...',
+ 'patterns': [r".*: warning: its scope is only this definition or declaration, which is probably not what you want"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wcomment',
+ 'description': 'Line continuation inside comment',
+ 'patterns': [r".*: warning: multi-line comment"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wcomment',
+ 'description': 'Comment inside comment',
+ 'patterns': [r".*: warning: "".+"" within comment"]},
+ # Warning "value stored is never read" could be from clang-tidy or clang static analyzer.
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Value stored is never read',
+ 'patterns': [r".*: warning: Value stored to .+ is never read.*clang-analyzer-deadcode.DeadStores"]},
+ {'category': 'C/C++', 'severity': Severity.LOW,
+ 'description': 'Value stored is never read',
+ 'patterns': [r".*: warning: Value stored to .+ is never read"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wdeprecated-declarations',
+ 'description': 'Deprecated declarations',
+ 'patterns': [r".*: warning: .+ is deprecated.+deprecated-declarations"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wdeprecated-register',
+ 'description': 'Deprecated register',
+ 'patterns': [r".*: warning: 'register' storage class specifier is deprecated"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wpointer-sign',
+ 'description': 'Converts between pointers to integer types with different sign',
+ 'patterns': [r".*: warning: .+ converts between pointers to integer types with different sign"]},
+ {'category': 'C/C++', 'severity': Severity.HARMLESS,
+ 'description': 'Extra tokens after #endif',
+ 'patterns': [r".*: warning: extra tokens at end of #endif directive"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wenum-compare',
+ 'description': 'Comparison between different enums',
+ 'patterns': [r".*: warning: comparison between '.+' and '.+'.+Wenum-compare"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wconversion',
+ 'description': 'Conversion may change value',
+ 'patterns': [r".*: warning: converting negative value '.+' to '.+'",
+ r".*: warning: conversion to '.+' .+ may (alter|change)"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wconversion-null',
+ 'description': 'Converting to non-pointer type from NULL',
+ 'patterns': [r".*: warning: converting to non-pointer type '.+' from NULL"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wsign-conversion',
+ 'description': 'Implicit sign conversion',
+ 'patterns': [r".*: warning: implicit conversion changes signedness"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wnull-conversion',
+ 'description': 'Converting NULL to non-pointer type',
+ 'patterns': [r".*: warning: implicit conversion of NULL constant to '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wnon-literal-null-conversion',
+ 'description': 'Zero used as null pointer',
+ 'patterns': [r".*: warning: expression .* zero treated as a null pointer constant"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Implicit conversion changes value',
+ 'patterns': [r".*: warning: implicit conversion .* changes value from .* to .*-conversion"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Passing NULL as non-pointer argument',
+ 'patterns': [r".*: warning: passing NULL to non-pointer argument [0-9]+ of '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wctor-dtor-privacy',
+ 'description': 'Class seems unusable because of private ctor/dtor',
+ 'patterns': [r".*: warning: all member functions in class '.+' are private"]},
# skip this next one, because it only points out some RefBase-based classes where having a private destructor is perfectly fine
- { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'-Wctor-dtor-privacy',
- 'description':'Class seems unusable because of private ctor/dtor' ,
- 'patterns':[r".*: warning: 'class .+' only defines a private destructor and has no friends"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy',
- 'description':'Class seems unusable because of private ctor/dtor' ,
- 'patterns':[r".*: warning: 'class .+' only defines private constructors and has no friends"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-arith',
- 'description':'void* used in arithmetic' ,
- 'patterns':[r".*: warning: pointer of type 'void \*' used in (arithmetic|subtraction)",
- r".*: warning: wrong type argument to increment"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-promo',
- 'description':'Overload resolution chose to promote from unsigned or enum to signed type' ,
- 'patterns':[r".*: warning: passing '.+' chooses 'int' over '.* int'"] },
- { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: in call to '.+'"] },
- { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wextra',
- 'description':'Base should be explicitly initialized in copy constructor',
- 'patterns':[r".*: warning: base class '.+' should be explicitly initialized in the copy constructor"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Converting from <type> to <other type>',
- 'patterns':[r".*: warning: converting to '.+' from '.+'"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Return value from void function',
- 'patterns':[r".*: warning: 'return' with a value, in function returning void"] },
- { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'',
- 'description':'Useless specifier',
- 'patterns':[r".*: warning: useless storage class specifier in empty declaration"] },
- { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'',
- 'description':'Duplicate logtag',
- 'patterns':[r".*: warning: tag "".+"" \(None\) duplicated in .+"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Operator new returns NULL',
- 'patterns':[r".*: warning: 'operator new' must not return NULL unless it is declared 'throw\(\)' .+"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'NULL used in arithmetic',
- 'patterns':[r".*: warning: NULL used in arithmetic"] },
- { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'',
- 'description':'Use of deprecated method',
- 'patterns':[r".*: warning: '.+' is deprecated .+"] },
+ {'category': 'C/C++', 'severity': Severity.SKIP, 'option': '-Wctor-dtor-privacy',
+ 'description': 'Class seems unusable because of private ctor/dtor',
+ 'patterns': [r".*: warning: 'class .+' only defines a private destructor and has no friends"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wctor-dtor-privacy',
+ 'description': 'Class seems unusable because of private ctor/dtor',
+ 'patterns': [r".*: warning: 'class .+' only defines private constructors and has no friends"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wgnu-static-float-init',
+ 'description': 'In-class initializer for static const float/double',
+ 'patterns': [r".*: warning: in-class initializer for static data member of .+const (float|double)"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wpointer-arith',
+ 'description': 'void* used in arithmetic',
+ 'patterns': [r".*: warning: pointer of type 'void \*' used in (arithmetic|subtraction)",
+ r".*: warning: arithmetic on .+ to void is a GNU extension.*Wpointer-arith",
+ r".*: warning: wrong type argument to increment"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wsign-promo',
+ 'description': 'Overload resolution chose to promote from unsigned or enum to signed type',
+ 'patterns': [r".*: warning: passing '.+' chooses '.+' over '.+'.*Wsign-promo"]},
+ {'category': 'cont.', 'severity': Severity.SKIP,
+ 'description': 'skip, in call to ...',
+ 'patterns': [r".*: warning: in call to '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.HIGH, 'option': '-Wextra',
+ 'description': 'Base should be explicitly initialized in copy constructor',
+ 'patterns': [r".*: warning: base class '.+' should be explicitly initialized in the copy constructor"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'VLA has zero or negative size',
+ 'patterns': [r".*: warning: Declared variable-length array \(VLA\) has .+ size"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Return value from void function',
+ 'patterns': [r".*: warning: 'return' with a value, in function returning void"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': 'multichar',
+ 'description': 'Multi-character character constant',
+ 'patterns': [r".*: warning: multi-character character constant"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': 'writable-strings',
+ 'description': 'Conversion from string literal to char*',
+ 'patterns': [r".*: warning: .+ does not allow conversion from string literal to 'char \*'"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wextra-semi',
+ 'description': 'Extra \';\'',
+ 'patterns': [r".*: warning: extra ';' .+extra-semi"]},
+ {'category': 'C/C++', 'severity': Severity.LOW,
+ 'description': 'Useless specifier',
+ 'patterns': [r".*: warning: useless storage class specifier in empty declaration"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wduplicate-decl-specifier',
+ 'description': 'Duplicate declaration specifier',
+ 'patterns': [r".*: warning: duplicate '.+' declaration specifier"]},
+ {'category': 'logtags', 'severity': Severity.LOW,
+ 'description': 'Duplicate logtag',
+ 'patterns': [r".*: warning: tag \".+\" \(.+\) duplicated in .+"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'typedef-redefinition',
+ 'description': 'Typedef redefinition',
+ 'patterns': [r".*: warning: redefinition of typedef '.+' is a C11 feature"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'gnu-designator',
+ 'description': 'GNU old-style field designator',
+ 'patterns': [r".*: warning: use of GNU old-style field designator extension"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'missing-field-initializers',
+ 'description': 'Missing field initializers',
+ 'patterns': [r".*: warning: missing field '.+' initializer"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'missing-braces',
+ 'description': 'Missing braces',
+ 'patterns': [r".*: warning: suggest braces around initialization of",
+ r".*: warning: too many braces around scalar initializer .+Wmany-braces-around-scalar-init",
+ r".*: warning: braces around scalar initializer"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'sign-compare',
+ 'description': 'Comparison of integers of different signs',
+ 'patterns': [r".*: warning: comparison of integers of different signs.+sign-compare"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'dangling-else',
+ 'description': 'Add braces to avoid dangling else',
+ 'patterns': [r".*: warning: add explicit braces to avoid dangling else"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'initializer-overrides',
+ 'description': 'Initializer overrides prior initialization',
+ 'patterns': [r".*: warning: initializer overrides prior initialization of this subobject"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'self-assign',
+ 'description': 'Assigning value to self',
+ 'patterns': [r".*: warning: explicitly assigning value of .+ to itself"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'gnu-variable-sized-type-not-at-end',
+ 'description': 'GNU extension, variable sized type not at end',
+ 'patterns': [r".*: warning: field '.+' with variable sized type '.+' not at the end of a struct or class"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'tautological-constant-out-of-range-compare',
+ 'description': 'Comparison of constant is always false/true',
+ 'patterns': [r".*: comparison of .+ is always .+Wtautological-constant-out-of-range-compare"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'overloaded-virtual',
+ 'description': 'Hides overloaded virtual function',
+ 'patterns': [r".*: '.+' hides overloaded virtual function"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'incompatible-pointer-types',
+ 'description': 'Incompatible pointer types',
+ 'patterns': [r".*: warning: incompatible pointer types .+Wincompatible-pointer-types"]},
+ {'category': 'logtags', 'severity': Severity.LOW, 'option': 'asm-operand-widths',
+ 'description': 'ASM value size does not match register size',
+ 'patterns': [r".*: warning: value size does not match register size specified by the constraint and modifier"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': 'tautological-compare',
+ 'description': 'Comparison of self is always false',
+ 'patterns': [r".*: self-comparison always evaluates to false"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': 'constant-logical-operand',
+ 'description': 'Logical op with constant operand',
+ 'patterns': [r".*: use of logical '.+' with constant operand"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': 'literal-suffix',
+ 'description': 'Needs a space between literal and string macro',
+ 'patterns': [r".*: warning: invalid suffix on literal.+ requires a space .+Wliteral-suffix"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '#warnings',
+ 'description': 'Warnings from #warning',
+ 'patterns': [r".*: warning: .+-W#warnings"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': 'absolute-value',
+ 'description': 'Using float/int absolute value function with int/float argument',
+ 'patterns': [r".*: warning: using .+ absolute value function .+ when argument is .+ type .+Wabsolute-value",
+ r".*: warning: absolute value function '.+' given .+ which may cause truncation .+Wabsolute-value"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Wc++11-extensions',
+ 'description': 'Using C++11 extensions',
+ 'patterns': [r".*: warning: 'auto' type specifier is a C\+\+11 extension"]},
+ {'category': 'C/C++', 'severity': Severity.LOW,
+ 'description': 'Refers to implicitly defined namespace',
+ 'patterns': [r".*: warning: using directive refers to implicitly-defined namespace .+"]},
+ {'category': 'C/C++', 'severity': Severity.LOW, 'option': '-Winvalid-pp-token',
+ 'description': 'Invalid pp token',
+ 'patterns': [r".*: warning: missing .+Winvalid-pp-token"]},
+ {'category': 'link', 'severity': Severity.LOW,
+ 'description': 'need glibc to link',
+ 'patterns': [r".*: warning: .* requires at runtime .* glibc .* for linking"]},
+
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Operator new returns NULL',
+ 'patterns': [r".*: warning: 'operator new' must not return NULL unless it is declared 'throw\(\)' .+"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wnull-arithmetic',
+ 'description': 'NULL used in arithmetic',
+ 'patterns': [r".*: warning: NULL used in arithmetic",
+ r".*: warning: comparison between NULL and non-pointer"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': 'header-guard',
+ 'description': 'Misspelled header guard',
+ 'patterns': [r".*: warning: '.+' is used as a header guard .+ followed by .+ different macro"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': 'empty-body',
+ 'description': 'Empty loop body',
+ 'patterns': [r".*: warning: .+ loop has empty body"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': 'enum-conversion',
+ 'description': 'Implicit conversion from enumeration type',
+ 'patterns': [r".*: warning: implicit conversion from enumeration type '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': 'switch',
+ 'description': 'case value not in enumerated type',
+ 'patterns': [r".*: warning: case value not in enumerated type '.+'"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Undefined result',
+ 'patterns': [r".*: warning: The result of .+ is undefined",
+ r".*: warning: passing an object that .+ has undefined behavior \[-Wvarargs\]",
+ r".*: warning: 'this' pointer cannot be null in well-defined C\+\+ code;",
+ r".*: warning: shifting a negative signed value is undefined"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Division by zero',
+ 'patterns': [r".*: warning: Division by zero"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Use of deprecated method',
+ 'patterns': [r".*: warning: '.+' is deprecated .+"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Use of garbage or uninitialized value',
+ 'patterns': [r".*: warning: .+ is a garbage value",
+ r".*: warning: Function call argument is an uninitialized value",
+ r".*: warning: Undefined or garbage value returned to caller",
+ r".*: warning: Called .+ pointer is.+uninitialized",
+ r".*: warning: Called .+ pointer is.+uninitalized", # match a typo in compiler message
+ r".*: warning: Use of zero-allocated memory",
+ r".*: warning: Dereference of undefined pointer value",
+ r".*: warning: Passed-by-value .+ contains uninitialized data",
+ r".*: warning: Branch condition evaluates to a garbage value",
+ r".*: warning: The .+ of .+ is an uninitialized value.",
+ r".*: warning: .+ is used uninitialized whenever .+sometimes-uninitialized",
+ r".*: warning: Assigned value is garbage or undefined"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Result of malloc type incompatible with sizeof operand type',
+ 'patterns': [r".*: warning: Result of '.+' is converted to .+ incompatible with sizeof operand type"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wsizeof-array-argument',
+ 'description': 'Sizeof on array argument',
+ 'patterns': [r".*: warning: sizeof on array function parameter will return"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wsizeof-pointer-memacces',
+ 'description': 'Bad argument size of memory access functions',
+ 'patterns': [r".*: warning: .+\[-Wsizeof-pointer-memaccess\]"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Return value not checked',
+ 'patterns': [r".*: warning: The return value from .+ is not checked"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Possible heap pollution',
+ 'patterns': [r".*: warning: .*Possible heap pollution from .+ type .+"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Allocation size of 0 byte',
+ 'patterns': [r".*: warning: Call to .+ has an allocation size of 0 byte"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Result of malloc type incompatible with sizeof operand type',
+ 'patterns': [r".*: warning: Result of '.+' is converted to .+ incompatible with sizeof operand type"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wfor-loop-analysis',
+ 'description': 'Variable used in loop condition not modified in loop body',
+ 'patterns': [r".*: warning: variable '.+' used in loop condition.*Wfor-loop-analysis"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM,
+ 'description': 'Closing a previously closed file',
+ 'patterns': [r".*: warning: Closing a previously closed file"]},
+ {'category': 'C/C++', 'severity': Severity.MEDIUM, 'option': '-Wunnamed-type-template-args',
+ 'description': 'Unnamed template type argument',
+ 'patterns': [r".*: warning: template argument.+Wunnamed-type-template-args"]},
+
+ {'category': 'C/C++', 'severity': Severity.HARMLESS,
+ 'description': 'Discarded qualifier from pointer target type',
+ 'patterns': [r".*: warning: .+ discards '.+' qualifier from pointer target type"]},
+ {'category': 'C/C++', 'severity': Severity.HARMLESS,
+ 'description': 'Use snprintf instead of sprintf',
+ 'patterns': [r".*: warning: .*sprintf is often misused; please use snprintf"]},
+ {'category': 'C/C++', 'severity': Severity.HARMLESS,
+ 'description': 'Unsupported optimizaton flag',
+ 'patterns': [r".*: warning: optimization flag '.+' is not supported"]},
+ {'category': 'C/C++', 'severity': Severity.HARMLESS,
+ 'description': 'Extra or missing parentheses',
+ 'patterns': [r".*: warning: equality comparison with extraneous parentheses",
+ r".*: warning: .+ within .+Wlogical-op-parentheses"]},
+ {'category': 'C/C++', 'severity': Severity.HARMLESS, 'option': 'mismatched-tags',
+ 'description': 'Mismatched class vs struct tags',
+ 'patterns': [r".*: warning: '.+' defined as a .+ here but previously declared as a .+mismatched-tags",
+ r".*: warning: .+ was previously declared as a .+mismatched-tags"]},
+ {'category': 'FindEmulator', 'severity': Severity.HARMLESS,
+ 'description': 'FindEmulator: No such file or directory',
+ 'patterns': [r".*: warning: FindEmulator: .* No such file or directory"]},
+ {'category': 'google_tests', 'severity': Severity.HARMLESS,
+ 'description': 'google_tests: unknown installed file',
+ 'patterns': [r".*: warning: .*_tests: Unknown installed file for module"]},
+ {'category': 'make', 'severity': Severity.HARMLESS,
+ 'description': 'unusual tags debug eng',
+ 'patterns': [r".*: warning: .*: unusual tags debug eng"]},
# these next ones are to deal with formatting problems resulting from the log being mixed up by 'make -j'
- { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: ,$"] },
- { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: $"] },
- { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'',
- 'description':'',
- 'patterns':[r".*: warning: In file included from .+,"] },
+ {'category': 'C/C++', 'severity': Severity.SKIP,
+ 'description': 'skip, ,',
+ 'patterns': [r".*: warning: ,$"]},
+ {'category': 'C/C++', 'severity': Severity.SKIP,
+ 'description': 'skip,',
+ 'patterns': [r".*: warning: $"]},
+ {'category': 'C/C++', 'severity': Severity.SKIP,
+ 'description': 'skip, In file included from ...',
+ 'patterns': [r".*: warning: In file included from .+,"]},
+
+ # warnings from clang-tidy
+ group_tidy_warn_pattern('cert'),
+ group_tidy_warn_pattern('clang-diagnostic'),
+ group_tidy_warn_pattern('cppcoreguidelines'),
+ group_tidy_warn_pattern('llvm'),
+ simple_tidy_warn_pattern('google-default-arguments'),
+ simple_tidy_warn_pattern('google-runtime-int'),
+ simple_tidy_warn_pattern('google-runtime-operator'),
+ simple_tidy_warn_pattern('google-runtime-references'),
+ group_tidy_warn_pattern('google-build'),
+ group_tidy_warn_pattern('google-explicit'),
+ group_tidy_warn_pattern('google-redability'),
+ group_tidy_warn_pattern('google-global'),
+ group_tidy_warn_pattern('google-redability'),
+ group_tidy_warn_pattern('google-redability'),
+ group_tidy_warn_pattern('google'),
+ simple_tidy_warn_pattern('hicpp-explicit-conversions'),
+ simple_tidy_warn_pattern('hicpp-function-size'),
+ simple_tidy_warn_pattern('hicpp-invalid-access-moved'),
+ simple_tidy_warn_pattern('hicpp-member-init'),
+ simple_tidy_warn_pattern('hicpp-delete-operators'),
+ simple_tidy_warn_pattern('hicpp-special-member-functions'),
+ simple_tidy_warn_pattern('hicpp-use-equals-default'),
+ simple_tidy_warn_pattern('hicpp-use-equals-delete'),
+ simple_tidy_warn_pattern('hicpp-no-assembler'),
+ 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('misc'),
+ 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'),
+ simple_tidy_warn_pattern('performance-inefficient-string-concatenation'),
+ simple_tidy_warn_pattern('performance-type-promotion-in-math-fn'),
+ simple_tidy_warn_pattern('performance-unnecessary-copy-initialization'),
+ simple_tidy_warn_pattern('performance-unnecessary-value-param'),
+ group_tidy_warn_pattern('performance'),
+ group_tidy_warn_pattern('readability'),
+
+ # warnings from clang-tidy's clang-analyzer checks
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Unreachable code',
+ 'patterns': [r".*: warning: This statement is never executed.*UnreachableCode"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Size of malloc may overflow',
+ 'patterns': [r".*: warning: .* size of .* may overflow .*MallocOverflow"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Stream pointer might be NULL',
+ 'patterns': [r".*: warning: Stream pointer might be NULL .*unix.Stream"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Opened file never closed',
+ 'patterns': [r".*: warning: Opened File never closed.*unix.Stream"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer sozeof() on a pointer type',
+ 'patterns': [r".*: warning: .*calls sizeof.* on a pointer type.*SizeofPtr"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Pointer arithmetic on non-array variables',
+ 'patterns': [r".*: warning: Pointer arithmetic on non-array variables .*PointerArithm"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Subtraction of pointers of different memory chunks',
+ 'patterns': [r".*: warning: Subtraction of two pointers .*PointerSub"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Access out-of-bound array element',
+ 'patterns': [r".*: warning: Access out-of-bound array element .*ArrayBound"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Out of bound memory access',
+ 'patterns': [r".*: warning: Out of bound memory access .*ArrayBoundV2"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Possible lock order reversal',
+ 'patterns': [r".*: warning: .* Possible lock order reversal.*PthreadLock"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer Argument is a pointer to uninitialized value',
+ 'patterns': [r".*: warning: .* argument is a pointer to uninitialized value .*CallAndMessage"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer cast to struct',
+ 'patterns': [r".*: warning: Casting a non-structure type to a structure type .*CastToStruct"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer call path problems',
+ 'patterns': [r".*: warning: Call Path : .+"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer excessive padding',
+ 'patterns': [r".*: warning: Excessive padding in '.*'"]},
+ {'category': 'C/C++', 'severity': Severity.ANALYZER,
+ 'description': 'clang-analyzer other',
+ 'patterns': [r".*: .+\[clang-analyzer-.+\]$",
+ r".*: Call Path : .+$"]},
# catch-all for warnings this script doesn't know about yet
- { 'category':'C/C++', 'severity':severity.UNKNOWN, 'members':[], 'option':'',
- 'description':'Unclassified/unrecognized warnings',
- 'patterns':[r".*: warning: .+"] },
+ {'category': 'C/C++', 'severity': Severity.UNKNOWN,
+ 'description': 'Unclassified/unrecognized warnings',
+ 'patterns': [r".*: warning: .+"]},
]
-anchor = 0
-cur_row_color = 0
-row_colors = [ 'e0e0e0', 'd0d0d0' ]
-def output(text):
- print text,
-
-def htmlbig(param):
- return '<font size="+2">' + param + '</font>'
-
-def dumphtmlprologue(title):
- output('<html>\n<head>\n<title>' + title + '</title>\n<body>\n')
- output(htmlbig(title))
- output('<p>\n')
-
-def tablerow(text):
- global cur_row_color
- output('<tr bgcolor="' + row_colors[cur_row_color] + '"><td colspan="2">',)
- cur_row_color = 1 - cur_row_color
- output(text,)
- output('</td></tr>')
-
-def begintable(text, backgroundcolor):
- global anchor
- output('<table border="1" rules="cols" frame="box" width="100%" bgcolor="black"><tr bgcolor="' +
- backgroundcolor + '"><a name="anchor' + str(anchor) + '"><td>')
- output(htmlbig(text[0]) + '<br>')
- for i in text[1:]:
- output(i + '<br>')
- output('</td>')
- output('<td width="100" bgcolor="grey"><a align="right" href="#anchor' + str(anchor-1) +
- '">previous</a><br><a align="right" href="#anchor' + str(anchor+1) + '">next</a>')
- output('</td></a></tr>')
- anchor += 1
-
-def endtable():
- output('</table><p>')
+def project_name_and_pattern(name, pattern):
+ return [name, '(^|.*/)' + pattern + '/.*: warning:']
-# dump some stats about total number of warnings and such
-def dumpstats():
- known = 0
- unknown = 0
- for i in warnpatterns:
- if i['severity'] == severity.UNKNOWN:
- unknown += len(i['members'])
- elif i['severity'] != severity.SKIP:
- known += len(i['members'])
- output('Number of classified warnings: <b>' + str(known) + '</b><br>' )
- output('Number of unclassified warnings: <b>' + str(unknown) + '</b><br>')
- total = unknown + known
- output('Total number of warnings: <b>' + str(total) + '</b>')
- if total < 1000:
- output('(low count may indicate incremental build)')
- output('<p>')
-
-def allpatterns(cat):
- pats = ''
- for i in cat['patterns']:
- pats += i
- pats += ' / '
- return pats
-
-def descriptionfor(cat):
- if cat['description'] != '':
- return cat['description']
- return allpatterns(cat)
+def simple_project_pattern(pattern):
+ return project_name_and_pattern(pattern, pattern)
-# show which warnings no longer occur
-def dumpfixed():
- tablestarted = False
- for i in warnpatterns:
- if len(i['members']) == 0 and i['severity'] != severity.SKIP:
- if tablestarted == False:
- tablestarted = True
- begintable(['Fixed warnings', 'No more occurences. Please consider turning these in to errors if possible, before they are reintroduced in to the build'], 'blue')
- tablerow(i['description'] + ' (' + allpatterns(i) + ') ' + i['option'])
- if tablestarted:
- endtable()
+# A list of [project_name, file_path_pattern].
+# project_name should not contain comma, to be used in CSV output.
+project_list = [
+ simple_project_pattern('art'),
+ simple_project_pattern('bionic'),
+ simple_project_pattern('bootable'),
+ simple_project_pattern('build'),
+ simple_project_pattern('cts'),
+ simple_project_pattern('dalvik'),
+ simple_project_pattern('developers'),
+ simple_project_pattern('development'),
+ simple_project_pattern('device'),
+ simple_project_pattern('doc'),
+ # match external/google* before external/
+ project_name_and_pattern('external/google', 'external/google.*'),
+ project_name_and_pattern('external/non-google', 'external'),
+ simple_project_pattern('frameworks/av/camera'),
+ simple_project_pattern('frameworks/av/cmds'),
+ simple_project_pattern('frameworks/av/drm'),
+ simple_project_pattern('frameworks/av/include'),
+ simple_project_pattern('frameworks/av/media/common_time'),
+ simple_project_pattern('frameworks/av/media/img_utils'),
+ simple_project_pattern('frameworks/av/media/libcpustats'),
+ simple_project_pattern('frameworks/av/media/libeffects'),
+ simple_project_pattern('frameworks/av/media/libmediaplayerservice'),
+ simple_project_pattern('frameworks/av/media/libmedia'),
+ simple_project_pattern('frameworks/av/media/libstagefright'),
+ simple_project_pattern('frameworks/av/media/mtp'),
+ simple_project_pattern('frameworks/av/media/ndk'),
+ simple_project_pattern('frameworks/av/media/utils'),
+ project_name_and_pattern('frameworks/av/media/Other',
+ 'frameworks/av/media'),
+ simple_project_pattern('frameworks/av/radio'),
+ simple_project_pattern('frameworks/av/services'),
+ simple_project_pattern('frameworks/av/soundtrigger'),
+ project_name_and_pattern('frameworks/av/Other', 'frameworks/av'),
+ simple_project_pattern('frameworks/base/cmds'),
+ simple_project_pattern('frameworks/base/core'),
+ simple_project_pattern('frameworks/base/drm'),
+ simple_project_pattern('frameworks/base/media'),
+ simple_project_pattern('frameworks/base/libs'),
+ simple_project_pattern('frameworks/base/native'),
+ simple_project_pattern('frameworks/base/packages'),
+ simple_project_pattern('frameworks/base/rs'),
+ simple_project_pattern('frameworks/base/services'),
+ simple_project_pattern('frameworks/base/tests'),
+ simple_project_pattern('frameworks/base/tools'),
+ project_name_and_pattern('frameworks/base/Other', 'frameworks/base'),
+ simple_project_pattern('frameworks/compile/libbcc'),
+ simple_project_pattern('frameworks/compile/mclinker'),
+ simple_project_pattern('frameworks/compile/slang'),
+ project_name_and_pattern('frameworks/compile/Other', 'frameworks/compile'),
+ simple_project_pattern('frameworks/minikin'),
+ simple_project_pattern('frameworks/ml'),
+ simple_project_pattern('frameworks/native/cmds'),
+ simple_project_pattern('frameworks/native/include'),
+ simple_project_pattern('frameworks/native/libs'),
+ simple_project_pattern('frameworks/native/opengl'),
+ simple_project_pattern('frameworks/native/services'),
+ simple_project_pattern('frameworks/native/vulkan'),
+ project_name_and_pattern('frameworks/native/Other', 'frameworks/native'),
+ simple_project_pattern('frameworks/opt'),
+ simple_project_pattern('frameworks/rs'),
+ simple_project_pattern('frameworks/webview'),
+ simple_project_pattern('frameworks/wilhelm'),
+ project_name_and_pattern('frameworks/Other', 'frameworks'),
+ simple_project_pattern('hardware/akm'),
+ simple_project_pattern('hardware/broadcom'),
+ simple_project_pattern('hardware/google'),
+ simple_project_pattern('hardware/intel'),
+ simple_project_pattern('hardware/interfaces'),
+ simple_project_pattern('hardware/libhardware'),
+ simple_project_pattern('hardware/libhardware_legacy'),
+ simple_project_pattern('hardware/qcom'),
+ simple_project_pattern('hardware/ril'),
+ project_name_and_pattern('hardware/Other', 'hardware'),
+ simple_project_pattern('kernel'),
+ simple_project_pattern('libcore'),
+ simple_project_pattern('libnativehelper'),
+ simple_project_pattern('ndk'),
+ # match vendor/unbungled_google/packages before other packages
+ simple_project_pattern('unbundled_google'),
+ simple_project_pattern('packages'),
+ simple_project_pattern('pdk'),
+ simple_project_pattern('prebuilts'),
+ simple_project_pattern('system/bt'),
+ simple_project_pattern('system/connectivity'),
+ simple_project_pattern('system/core/adb'),
+ simple_project_pattern('system/core/base'),
+ simple_project_pattern('system/core/debuggerd'),
+ simple_project_pattern('system/core/fastboot'),
+ simple_project_pattern('system/core/fingerprintd'),
+ simple_project_pattern('system/core/fs_mgr'),
+ simple_project_pattern('system/core/gatekeeperd'),
+ simple_project_pattern('system/core/healthd'),
+ simple_project_pattern('system/core/include'),
+ simple_project_pattern('system/core/init'),
+ simple_project_pattern('system/core/libbacktrace'),
+ simple_project_pattern('system/core/liblog'),
+ simple_project_pattern('system/core/libpixelflinger'),
+ simple_project_pattern('system/core/libprocessgroup'),
+ simple_project_pattern('system/core/libsysutils'),
+ simple_project_pattern('system/core/logcat'),
+ simple_project_pattern('system/core/logd'),
+ simple_project_pattern('system/core/run-as'),
+ simple_project_pattern('system/core/sdcard'),
+ simple_project_pattern('system/core/toolbox'),
+ project_name_and_pattern('system/core/Other', 'system/core'),
+ simple_project_pattern('system/extras/ANRdaemon'),
+ simple_project_pattern('system/extras/cpustats'),
+ simple_project_pattern('system/extras/crypto-perf'),
+ simple_project_pattern('system/extras/ext4_utils'),
+ simple_project_pattern('system/extras/f2fs_utils'),
+ simple_project_pattern('system/extras/iotop'),
+ simple_project_pattern('system/extras/libfec'),
+ simple_project_pattern('system/extras/memory_replay'),
+ simple_project_pattern('system/extras/micro_bench'),
+ simple_project_pattern('system/extras/mmap-perf'),
+ simple_project_pattern('system/extras/multinetwork'),
+ simple_project_pattern('system/extras/perfprofd'),
+ simple_project_pattern('system/extras/procrank'),
+ simple_project_pattern('system/extras/runconuid'),
+ simple_project_pattern('system/extras/showmap'),
+ simple_project_pattern('system/extras/simpleperf'),
+ simple_project_pattern('system/extras/su'),
+ simple_project_pattern('system/extras/tests'),
+ simple_project_pattern('system/extras/verity'),
+ project_name_and_pattern('system/extras/Other', 'system/extras'),
+ simple_project_pattern('system/gatekeeper'),
+ simple_project_pattern('system/keymaster'),
+ simple_project_pattern('system/libhidl'),
+ simple_project_pattern('system/libhwbinder'),
+ simple_project_pattern('system/media'),
+ simple_project_pattern('system/netd'),
+ simple_project_pattern('system/nvram'),
+ simple_project_pattern('system/security'),
+ simple_project_pattern('system/sepolicy'),
+ simple_project_pattern('system/tools'),
+ simple_project_pattern('system/update_engine'),
+ simple_project_pattern('system/vold'),
+ project_name_and_pattern('system/Other', 'system'),
+ simple_project_pattern('toolchain'),
+ simple_project_pattern('test'),
+ simple_project_pattern('tools'),
+ # match vendor/google* before vendor/
+ project_name_and_pattern('vendor/google', 'vendor/google.*'),
+ project_name_and_pattern('vendor/non-google', 'vendor'),
+ # keep out/obj and other patterns at the end.
+ ['out/obj',
+ '.*/(gen|obj[^/]*)/(include|EXECUTABLES|SHARED_LIBRARIES|'
+ 'STATIC_LIBRARIES|NATIVE_TESTS)/.*: warning:'],
+ ['other', '.*'] # all other unrecognized patterns
+]
+
+project_patterns = []
+project_names = []
+warning_messages = []
+warning_records = []
-# dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences
-def dumpcategory(cat):
- if cat['severity'] != severity.SKIP and len(cat['members']) != 0:
- header = [descriptionfor(cat),str(len(cat['members'])) + ' occurences:']
- if cat['option'] != '':
- header[1:1] = [' (related option: ' + cat['option'] +')']
- begintable(header, colorforseverity(cat['severity']))
- for i in cat['members']:
- tablerow(i)
- endtable()
+def initialize_arrays():
+ """Complete global arrays before they are used."""
+ global project_names, project_patterns
+ project_names = [p[0] for p in project_list]
+ project_patterns = [re.compile(p[1]) for p in project_list]
+ for w in warn_patterns:
+ w['members'] = []
+ if 'option' not in w:
+ w['option'] = ''
+ # Each warning pattern has a 'projects' dictionary, that
+ # maps a project name to number of warnings in that project.
+ w['projects'] = {}
-# dump everything for a given severity
-def dumpseverity(sev):
- for i in warnpatterns:
- if i['severity'] == sev:
- dumpcategory(i)
+initialize_arrays()
-def classifywarning(line):
- for i in warnpatterns:
- for cpat in i['compiledpatterns']:
- if cpat.match(line):
- i['members'].append(line)
- return
+android_root = ''
+platform_version = 'unknown'
+target_product = 'unknown'
+target_variant = 'unknown'
+
+
+##### Data and functions to dump html file. ##################################
+
+html_head_scripts = """\
+ <script type="text/javascript">
+ function expand(id) {
+ var e = document.getElementById(id);
+ var f = document.getElementById(id + "_mark");
+ if (e.style.display == 'block') {
+ e.style.display = 'none';
+ f.innerHTML = '⊕';
+ }
+ else {
+ e.style.display = 'block';
+ f.innerHTML = '⊖';
+ }
+ };
+ function expandCollapse(show) {
+ for (var id = 1; ; id++) {
+ var e = document.getElementById(id + "");
+ var f = document.getElementById(id + "_mark");
+ if (!e || !f) break;
+ e.style.display = (show ? 'block' : 'none');
+ f.innerHTML = (show ? '⊖' : '⊕');
+ }
+ };
+ </script>
+ <style type="text/css">
+ th,td{border-collapse:collapse; border:1px solid black;}
+ .button{color:blue;font-size:110%;font-weight:bolder;}
+ .bt{color:black;background-color:transparent;border:none;outline:none;
+ font-size:140%;font-weight:bolder;}
+ .c0{background-color:#e0e0e0;}
+ .c1{background-color:#d0d0d0;}
+ .t1{border-collapse:collapse; width:100%; border:1px solid black;}
+ </style>
+ <script src="https://www.gstatic.com/charts/loader.js"></script>
+"""
+
+
+def html_big(param):
+ return '<font size="+2">' + param + '</font>'
+
+
+def dump_html_prologue(title):
+ print '<html>\n<head>'
+ print '<title>' + title + '</title>'
+ print html_head_scripts
+ emit_stats_by_project()
+ print '</head>\n<body>'
+ print html_big(title)
+ print '<p>'
+
+
+def dump_html_epilogue():
+ print '</body>\n</head>\n</html>'
+
+
+def sort_warnings():
+ for i in warn_patterns:
+ i['members'] = sorted(set(i['members']))
+
+
+def emit_stats_by_project():
+ """Dump a google chart table of warnings per project and severity."""
+ # warnings[p][s] is number of warnings in project p of severity s.
+ warnings = {p: {s: 0 for s in Severity.range} for p in project_names}
+ for i in warn_patterns:
+ s = i['severity']
+ for p in i['projects']:
+ warnings[p][s] += i['projects'][p]
+
+ # total_by_project[p] is number of warnings in project p.
+ total_by_project = {p: sum(warnings[p][s] for s in Severity.range)
+ for p in project_names}
+
+ # total_by_severity[s] is number of warnings of severity s.
+ total_by_severity = {s: sum(warnings[p][s] for p in project_names)
+ for s in Severity.range}
+
+ # emit table header
+ stats_header = ['Project']
+ for s in Severity.range:
+ if total_by_severity[s]:
+ stats_header.append("<span style='background-color:{}'>{}</span>".
+ format(Severity.colors[s],
+ Severity.column_headers[s]))
+ stats_header.append('TOTAL')
+
+ # emit a row of warning counts per project, skip no-warning projects
+ total_all_projects = 0
+ stats_rows = []
+ for p in project_names:
+ if total_by_project[p]:
+ one_row = [p]
+ for s in Severity.range:
+ if total_by_severity[s]:
+ one_row.append(warnings[p][s])
+ one_row.append(total_by_project[p])
+ stats_rows.append(one_row)
+ total_all_projects += total_by_project[p]
+
+ # emit a row of warning counts per severity
+ total_all_severities = 0
+ one_row = ['<b>TOTAL</b>']
+ for s in Severity.range:
+ if total_by_severity[s]:
+ one_row.append(total_by_severity[s])
+ total_all_severities += total_by_severity[s]
+ one_row.append(total_all_projects)
+ stats_rows.append(one_row)
+ print '<script>'
+ emit_const_string_array('StatsHeader', stats_header)
+ emit_const_object_array('StatsRows', stats_rows)
+ print draw_table_javascript
+ print '</script>'
+
+
+def dump_stats():
+ """Dump some stats about total number of warnings and such."""
+ known = 0
+ skipped = 0
+ unknown = 0
+ sort_warnings()
+ for i in warn_patterns:
+ if i['severity'] == Severity.UNKNOWN:
+ unknown += len(i['members'])
+ elif i['severity'] == Severity.SKIP:
+ skipped += len(i['members'])
else:
+ known += len(i['members'])
+ print 'Number of classified warnings: <b>' + str(known) + '</b><br>'
+ print 'Number of skipped warnings: <b>' + str(skipped) + '</b><br>'
+ print 'Number of unclassified warnings: <b>' + str(unknown) + '</b><br>'
+ total = unknown + known + skipped
+ extra_msg = ''
+ if total < 1000:
+ extra_msg = ' (low count may indicate incremental build)'
+ print 'Total number of warnings: <b>' + str(total) + '</b>' + extra_msg
+
+
+# New base table of warnings, [severity, warn_id, project, warning_message]
+# Need buttons to show warnings in different grouping options.
+# (1) Current, group by severity, id for each warning pattern
+# sort by severity, warn_id, warning_message
+# (2) Current --byproject, group by severity,
+# id for each warning pattern + project name
+# sort by severity, warn_id, project, warning_message
+# (3) New, group by project + severity,
+# id for each warning pattern
+# sort by project, severity, warn_id, warning_message
+def emit_buttons():
+ print ('<button class="button" onclick="expandCollapse(1);">'
+ 'Expand all warnings</button>\n'
+ '<button class="button" onclick="expandCollapse(0);">'
+ 'Collapse all warnings</button>\n'
+ '<button class="button" onclick="groupBySeverity();">'
+ 'Group warnings by severity</button>\n'
+ '<button class="button" onclick="groupByProject();">'
+ 'Group warnings by project</button><br>')
+
+
+def all_patterns(category):
+ patterns = ''
+ for i in category['patterns']:
+ patterns += i
+ patterns += ' / '
+ return patterns
+
+
+def dump_fixed():
+ """Show which warnings no longer occur."""
+ anchor = 'fixed_warnings'
+ mark = anchor + '_mark'
+ print ('\n<br><p style="background-color:lightblue"><b>'
+ '<button id="' + mark + '" '
+ 'class="bt" onclick="expand(\'' + anchor + '\');">'
+ '⊕</button> Fixed warnings. '
+ 'No more occurrences. Please consider turning these into '
+ 'errors if possible, before they are reintroduced in to the build'
+ ':</b></p>')
+ print '<blockquote>'
+ fixed_patterns = []
+ for i in warn_patterns:
+ if not i['members']:
+ fixed_patterns.append(i['description'] + ' (' +
+ all_patterns(i) + ')')
+ if i['option']:
+ fixed_patterns.append(' ' + i['option'])
+ fixed_patterns.sort()
+ print '<div id="' + anchor + '" style="display:none;"><table>'
+ cur_row_class = 0
+ for text in fixed_patterns:
+ cur_row_class = 1 - cur_row_class
+ # remove last '\n'
+ t = text[:-1] if text[-1] == '\n' else text
+ print '<tr><td class="c' + str(cur_row_class) + '">' + t + '</td></tr>'
+ print '</table></div>'
+ print '</blockquote>'
+
+
+def find_project_index(line):
+ for p in range(len(project_patterns)):
+ if project_patterns[p].match(line):
+ return p
+ return -1
+
+
+def classify_one_warning(line, results):
+ for i in range(len(warn_patterns)):
+ w = warn_patterns[i]
+ for cpat in w['compiled_patterns']:
+ if cpat.match(line):
+ p = find_project_index(line)
+ results.append([line, i, p])
+ return
+ else:
# If we end up here, there was a problem parsing the log
# probably caused by 'make -j' mixing the output from
# 2 or more concurrent compiles
pass
-# precompiling every pattern speeds up parsing by about 30x
-def compilepatterns():
- for i in warnpatterns:
- i['compiledpatterns'] = []
- for pat in i['patterns']:
- i['compiledpatterns'].append(re.compile(pat))
-infile = open(sys.argv[1], 'r')
-warnings = []
+def classify_warnings(lines):
+ results = []
+ for line in lines:
+ classify_one_warning(line, results)
+ # After the main work, ignore all other signals to a child process,
+ # to avoid bad warning/error messages from the exit clean-up process.
+ if args.processes > 1:
+ signal.signal(signal.SIGTERM, lambda *args: sys.exit(-signal.SIGTERM))
+ return results
-platformversion = 'unknown'
-targetproduct = 'unknown'
-targetvariant = 'unknown'
-linecounter = 0
-warningpattern = re.compile('.* warning:.*')
-compilepatterns()
+def parallel_classify_warnings(warning_lines):
+ """Classify all warning lines with num_cpu parallel processes."""
+ compile_patterns()
+ num_cpu = args.processes
+ if num_cpu > 1:
+ groups = [[] for x in range(num_cpu)]
+ i = 0
+ for x in warning_lines:
+ groups[i].append(x)
+ i = (i + 1) % num_cpu
+ pool = multiprocessing.Pool(num_cpu)
+ group_results = pool.map(classify_warnings, groups)
+ else:
+ group_results = [classify_warnings(warning_lines)]
-# read the log file and classify all the warnings
-lastmatchedline = ''
-for line in infile:
- # replace fancy quotes with plain ol' quotes
- line = line.replace("‘", "'");
- line = line.replace("’", "'");
- if warningpattern.match(line):
- if line != lastmatchedline:
- classifywarning(line)
- lastmatchedline = line
+ for result in group_results:
+ for line, pattern_idx, project_idx in result:
+ pattern = warn_patterns[pattern_idx]
+ pattern['members'].append(line)
+ message_idx = len(warning_messages)
+ warning_messages.append(line)
+ warning_records.append([pattern_idx, project_idx, message_idx])
+ pname = '???' if project_idx < 0 else project_names[project_idx]
+ # Count warnings by project.
+ if pname in pattern['projects']:
+ pattern['projects'][pname] += 1
+ else:
+ pattern['projects'][pname] = 1
+
+
+def compile_patterns():
+ """Precompiling every pattern speeds up parsing by about 30x."""
+ for i in warn_patterns:
+ i['compiled_patterns'] = []
+ for pat in i['patterns']:
+ i['compiled_patterns'].append(re.compile(pat))
+
+
+def find_android_root(path):
+ """Set and return android_root path if it is found."""
+ global android_root
+ parts = path.split('/')
+ for idx in reversed(range(2, len(parts))):
+ root_path = '/'.join(parts[:idx])
+ # Android root directory should contain this script.
+ if os.path.exists(root_path + '/build/tools/warn.py'):
+ android_root = root_path
+ return root_path
+ return ''
+
+
+def remove_android_root_prefix(path):
+ """Remove android_root prefix from path if it is found."""
+ if path.startswith(android_root):
+ return path[1 + len(android_root):]
+ else:
+ return path
+
+
+def normalize_path(path):
+ """Normalize file path relative to android_root."""
+ # If path is not an absolute path, just normalize it.
+ path = os.path.normpath(path)
+ if path[0] != '/':
+ return path
+ # Remove known prefix of root path and normalize the suffix.
+ if android_root or find_android_root(path):
+ return remove_android_root_prefix(path)
+ else:
+ return path
+
+
+def normalize_warning_line(line):
+ """Normalize file path relative to android_root in a warning line."""
+ # replace fancy quotes with plain ol' quotes
+ line = line.replace('‘', "'")
+ line = line.replace('’', "'")
+ line = line.strip()
+ first_column = line.find(':')
+ if first_column > 0:
+ return normalize_path(line[:first_column]) + line[first_column:]
+ else:
+ return line
+
+
+def parse_input_file(infile):
+ """Parse input file, collect parameters and warning lines."""
+ global android_root
+ global platform_version
+ global target_product
+ global target_variant
+ line_counter = 0
+
+ # handle only warning messages with a file path
+ warning_pattern = re.compile('^[^ ]*/[^ ]*: warning: .*')
+
+ # Collect all warnings into the warning_lines set.
+ warning_lines = set()
+ for line in infile:
+ if warning_pattern.match(line):
+ line = normalize_warning_line(line)
+ warning_lines.add(line)
+ elif line_counter < 50:
+ # save a little bit of time by only doing this for the first few lines
+ line_counter += 1
+ m = re.search('(?<=^PLATFORM_VERSION=).*', line)
+ if m is not None:
+ platform_version = m.group(0)
+ m = re.search('(?<=^TARGET_PRODUCT=).*', line)
+ if m is not None:
+ target_product = m.group(0)
+ m = re.search('(?<=^TARGET_BUILD_VARIANT=).*', line)
+ if m is not None:
+ target_variant = m.group(0)
+ m = re.search('.* TOP=([^ ]*) .*', line)
+ if m is not None:
+ android_root = m.group(1)
+ return warning_lines
+
+
+# Return s with escaped backslash and quotation characters.
+def escape_string(s):
+ return s.replace('\\', '\\\\').replace('"', '\\"')
+
+
+# Return s without trailing '\n' and escape the quotation characters.
+def strip_escape_string(s):
+ if not s:
+ return s
+ s = s[:-1] if s[-1] == '\n' else s
+ return escape_string(s)
+
+
+def emit_warning_array(name):
+ print 'var warning_{} = ['.format(name)
+ for i in range(len(warn_patterns)):
+ print '{},'.format(warn_patterns[i][name])
+ print '];'
+
+
+def emit_warning_arrays():
+ emit_warning_array('severity')
+ print 'var warning_description = ['
+ for i in range(len(warn_patterns)):
+ if warn_patterns[i]['members']:
+ print '"{}",'.format(escape_string(warn_patterns[i]['description']))
else:
- # save a little bit of time by only doing this for the first few lines
- if linecounter < 50:
- linecounter +=1
- m = re.search('(?<=^PLATFORM_VERSION=).*', line)
- if m != None:
- platformversion = m.group(0)
- m = re.search('(?<=^TARGET_PRODUCT=).*', line)
- if m != None:
- targetproduct = m.group(0)
- m = re.search('(?<=^TARGET_BUILD_VARIANT=).*', line)
- if m != None:
- targetvariant = m.group(0)
+ print '"",' # no such warning
+ print '];'
+
+scripts_for_warning_groups = """
+ function compareMessages(x1, x2) { // of the same warning type
+ return (WarningMessages[x1[2]] <= WarningMessages[x2[2]]) ? -1 : 1;
+ }
+ function byMessageCount(x1, x2) {
+ return x2[2] - x1[2]; // reversed order
+ }
+ function bySeverityMessageCount(x1, x2) {
+ // orer by severity first
+ if (x1[1] != x2[1])
+ return x1[1] - x2[1];
+ return byMessageCount(x1, x2);
+ }
+ const ParseLinePattern = /^([^ :]+):(\\d+):(.+)/;
+ function addURL(line) {
+ if (FlagURL == "") return line;
+ if (FlagSeparator == "") {
+ return line.replace(ParseLinePattern,
+ "<a target='_blank' href='" + FlagURL + "/$1'>$1</a>:$2:$3");
+ }
+ return line.replace(ParseLinePattern,
+ "<a target='_blank' href='" + FlagURL + "/$1" + FlagSeparator +
+ "$2'>$1:$2</a>:$3");
+ }
+ function createArrayOfDictionaries(n) {
+ var result = [];
+ for (var i=0; i<n; i++) result.push({});
+ return result;
+ }
+ function groupWarningsBySeverity() {
+ // groups is an array of dictionaries,
+ // each dictionary maps from warning type to array of warning messages.
+ var groups = createArrayOfDictionaries(SeverityColors.length);
+ for (var i=0; i<Warnings.length; i++) {
+ var w = Warnings[i][0];
+ var s = WarnPatternsSeverity[w];
+ var k = w.toString();
+ if (!(k in groups[s]))
+ groups[s][k] = [];
+ groups[s][k].push(Warnings[i]);
+ }
+ return groups;
+ }
+ function groupWarningsByProject() {
+ var groups = createArrayOfDictionaries(ProjectNames.length);
+ for (var i=0; i<Warnings.length; i++) {
+ var w = Warnings[i][0];
+ var p = Warnings[i][1];
+ var k = w.toString();
+ if (!(k in groups[p]))
+ groups[p][k] = [];
+ groups[p][k].push(Warnings[i]);
+ }
+ return groups;
+ }
+ var GlobalAnchor = 0;
+ function createWarningSection(header, color, group) {
+ var result = "";
+ var groupKeys = [];
+ var totalMessages = 0;
+ for (var k in group) {
+ totalMessages += group[k].length;
+ groupKeys.push([k, WarnPatternsSeverity[parseInt(k)], group[k].length]);
+ }
+ groupKeys.sort(bySeverityMessageCount);
+ for (var idx=0; idx<groupKeys.length; idx++) {
+ var k = groupKeys[idx][0];
+ var messages = group[k];
+ var w = parseInt(k);
+ var wcolor = SeverityColors[WarnPatternsSeverity[w]];
+ var description = WarnPatternsDescription[w];
+ if (description.length == 0)
+ description = "???";
+ GlobalAnchor += 1;
+ result += "<table class='t1'><tr bgcolor='" + wcolor + "'><td>" +
+ "<button class='bt' id='" + GlobalAnchor + "_mark" +
+ "' onclick='expand(\\"" + GlobalAnchor + "\\");'>" +
+ "⊕</button> " +
+ description + " (" + messages.length + ")</td></tr></table>";
+ result += "<div id='" + GlobalAnchor +
+ "' style='display:none;'><table class='t1'>";
+ var c = 0;
+ messages.sort(compareMessages);
+ for (var i=0; i<messages.length; i++) {
+ result += "<tr><td class='c" + c + "'>" +
+ addURL(WarningMessages[messages[i][2]]) + "</td></tr>";
+ c = 1 - c;
+ }
+ result += "</table></div>";
+ }
+ if (result.length > 0) {
+ return "<br><span style='background-color:" + color + "'><b>" +
+ header + ": " + totalMessages +
+ "</b></span><blockquote><table class='t1'>" +
+ result + "</table></blockquote>";
+
+ }
+ return ""; // empty section
+ }
+ function generateSectionsBySeverity() {
+ var result = "";
+ var groups = groupWarningsBySeverity();
+ for (s=0; s<SeverityColors.length; s++) {
+ result += createWarningSection(SeverityHeaders[s], SeverityColors[s], groups[s]);
+ }
+ return result;
+ }
+ function generateSectionsByProject() {
+ var result = "";
+ var groups = groupWarningsByProject();
+ for (i=0; i<groups.length; i++) {
+ result += createWarningSection(ProjectNames[i], 'lightgrey', groups[i]);
+ }
+ return result;
+ }
+ function groupWarnings(generator) {
+ GlobalAnchor = 0;
+ var e = document.getElementById("warning_groups");
+ e.innerHTML = generator();
+ }
+ function groupBySeverity() {
+ groupWarnings(generateSectionsBySeverity);
+ }
+ function groupByProject() {
+ groupWarnings(generateSectionsByProject);
+ }
+"""
-# dump the html output to stdout
-dumphtmlprologue('Warnings for ' + platformversion + ' - ' + targetproduct + ' - ' + targetvariant)
-dumpstats()
-dumpseverity(severity.FIXMENOW)
-dumpseverity(severity.HIGH)
-dumpseverity(severity.MEDIUM)
-dumpseverity(severity.LOW)
-dumpseverity(severity.HARMLESS)
-dumpseverity(severity.UNKNOWN)
-dumpfixed()
+# Emit a JavaScript const string
+def emit_const_string(name, value):
+ print 'const ' + name + ' = "' + escape_string(value) + '";'
+
+# Emit a JavaScript const integer array.
+def emit_const_int_array(name, array):
+ print 'const ' + name + ' = ['
+ for n in array:
+ print str(n) + ','
+ print '];'
+
+
+# Emit a JavaScript const string array.
+def emit_const_string_array(name, array):
+ print 'const ' + name + ' = ['
+ for s in array:
+ print '"' + strip_escape_string(s) + '",'
+ print '];'
+
+
+# Emit a JavaScript const object array.
+def emit_const_object_array(name, array):
+ print 'const ' + name + ' = ['
+ for x in array:
+ print str(x) + ','
+ print '];'
+
+
+def emit_js_data():
+ """Dump dynamic HTML page's static JavaScript data."""
+ emit_const_string('FlagURL', args.url if args.url else '')
+ emit_const_string('FlagSeparator', args.separator if args.separator else '')
+ emit_const_string_array('SeverityColors', Severity.colors)
+ emit_const_string_array('SeverityHeaders', Severity.headers)
+ emit_const_string_array('SeverityColumnHeaders', Severity.column_headers)
+ emit_const_string_array('ProjectNames', project_names)
+ emit_const_int_array('WarnPatternsSeverity',
+ [w['severity'] for w in warn_patterns])
+ emit_const_string_array('WarnPatternsDescription',
+ [w['description'] for w in warn_patterns])
+ emit_const_string_array('WarnPatternsOption',
+ [w['option'] for w in warn_patterns])
+ emit_const_string_array('WarningMessages', warning_messages)
+ emit_const_object_array('Warnings', warning_records)
+
+draw_table_javascript = """
+google.charts.load('current', {'packages':['table']});
+google.charts.setOnLoadCallback(drawTable);
+function drawTable() {
+ var data = new google.visualization.DataTable();
+ data.addColumn('string', StatsHeader[0]);
+ for (var i=1; i<StatsHeader.length; i++) {
+ data.addColumn('number', StatsHeader[i]);
+ }
+ data.addRows(StatsRows);
+ for (var i=0; i<StatsRows.length; i++) {
+ for (var j=0; j<StatsHeader.length; j++) {
+ data.setProperty(i, j, 'style', 'border:1px solid black;');
+ }
+ }
+ var table = new google.visualization.Table(document.getElementById('stats_table'));
+ table.draw(data, {allowHtml: true, alternatingRowStyle: true});
+}
+"""
+
+
+def dump_html():
+ """Dump the html output to stdout."""
+ dump_html_prologue('Warnings for ' + platform_version + ' - ' +
+ target_product + ' - ' + target_variant)
+ dump_stats()
+ print '<br><div id="stats_table"></div><br>'
+ print '\n<script>'
+ emit_js_data()
+ print scripts_for_warning_groups
+ print '</script>'
+ emit_buttons()
+ # Warning messages are grouped by severities or project names.
+ print '<br><div id="warning_groups"></div>'
+ if args.byproject:
+ print '<script>groupByProject();</script>'
+ else:
+ print '<script>groupBySeverity();</script>'
+ dump_fixed()
+ dump_html_epilogue()
+
+
+##### Functions to count warnings and dump csv file. #########################
+
+
+def description_for_csv(category):
+ if not category['description']:
+ return '?'
+ return category['description']
+
+
+def count_severity(writer, sev, kind):
+ """Count warnings of given severity."""
+ total = 0
+ for i in warn_patterns:
+ if i['severity'] == sev and i['members']:
+ n = len(i['members'])
+ total += n
+ warning = kind + ': ' + description_for_csv(i)
+ writer.writerow([n, '', warning])
+ # print number of warnings for each project, ordered by project name.
+ projects = i['projects'].keys()
+ projects.sort()
+ for p in projects:
+ writer.writerow([i['projects'][p], p, warning])
+ writer.writerow([total, '', kind + ' warnings'])
+
+ return total
+
+
+# dump number of warnings in csv format to stdout
+def dump_csv(writer):
+ """Dump number of warnings in csv format to stdout."""
+ sort_warnings()
+ total = 0
+ for s in Severity.range:
+ total += count_severity(writer, s, Severity.column_headers[s])
+ writer.writerow([total, '', 'All warnings'])
+
+
+def main():
+ warning_lines = parse_input_file(open(args.buildlog, 'r'))
+ parallel_classify_warnings(warning_lines)
+ # If a user pases a csv path, save the fileoutput to the path
+ # If the user also passed gencsv write the output to stdout
+ # If the user did not pass gencsv flag dump the html report to stdout.
+ if args.csvpath:
+ with open(args.csvpath, 'w') as f:
+ dump_csv(csv.writer(f, lineterminator='\n'))
+ if args.gencsv:
+ dump_csv(csv.writer(sys.stdout, lineterminator='\n'))
+ else:
+ dump_html()
+
+
+# Run main function if warn.py is the main program.
+if __name__ == '__main__':
+ main()
diff --git a/tools/zipalign/ZipAlign.cpp b/tools/zipalign/ZipAlign.cpp
index a2dfd02..d56ac29 100644
--- a/tools/zipalign/ZipAlign.cpp
+++ b/tools/zipalign/ZipAlign.cpp
@@ -19,8 +19,9 @@
*/
#include "ZipFile.h"
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
using namespace android;
@@ -33,12 +34,12 @@
fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
fprintf(stderr,
"Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
- " zipalign -c [-v] <align> infile.zip\n\n" );
+ " zipalign -c [-p] [-v] <align> infile.zip\n\n" );
fprintf(stderr,
" <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
fprintf(stderr, " -c: check alignment only (does not modify file)\n");
fprintf(stderr, " -f: overwrite existing outfile.zip\n");
- fprintf(stderr, " -p: page align stored shared object files\n");
+ fprintf(stderr, " -p: memory page alignment for stored shared object files\n");
fprintf(stderr, " -v: verbose output\n");
fprintf(stderr, " -z: recompress using Zopfli\n");
}
diff --git a/tools/zipalign/ZipEntry.cpp b/tools/zipalign/ZipEntry.cpp
index 2f33e23..63d75d1 100644
--- a/tools/zipalign/ZipEntry.cpp
+++ b/tools/zipalign/ZipEntry.cpp
@@ -23,10 +23,11 @@
#include "ZipEntry.h"
#include <utils/Log.h>
-#include <stdio.h>
-#include <string.h>
#include <assert.h>
#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
using namespace android;
@@ -130,6 +131,7 @@
if (mCDE.mFileCommentLength > 0) {
/* TODO: stop assuming null-terminated ASCII here? */
mCDE.mFileComment = new uint8_t[mCDE.mFileCommentLength+1];
+ assert(comment != NULL);
strcpy((char*) mCDE.mFileComment, comment);
}
diff --git a/tools/zipalign/ZipEntry.h b/tools/zipalign/ZipEntry.h
index e06567d..431b6db 100644
--- a/tools/zipalign/ZipEntry.h
+++ b/tools/zipalign/ZipEntry.h
@@ -290,7 +290,7 @@
mExtraField(NULL),
mFileComment(NULL)
{}
- virtual ~CentralDirEntry(void) {
+ ~CentralDirEntry(void) {
delete[] mFileName;
delete[] mExtraField;
delete[] mFileComment;
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index 4edf0aa..1b39902 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -359,8 +359,7 @@
* safely written. Not really a concern for us.
*/
status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
- const char* storageName, int sourceType, int compressionMethod,
- ZipEntry** ppEntry)
+ const char* storageName, int compressionMethod, ZipEntry** ppEntry)
{
ZipEntry* pEntry = NULL;
status_t result = NO_ERROR;
@@ -414,81 +413,51 @@
/*
* Copy the data in, possibly compressing it as we go.
*/
- if (sourceType == ZipEntry::kCompressStored) {
- if (compressionMethod == ZipEntry::kCompressDeflated) {
- bool failed = false;
- result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
- if (result != NO_ERROR) {
- ALOGD("compression failed, storing\n");
- failed = true;
- } else {
- /*
- * Make sure it has compressed "enough". This probably ought
- * to be set through an API call, but I don't expect our
- * criteria to change over time.
- */
- long src = inputFp ? ftell(inputFp) : size;
- long dst = ftell(mZipFp) - startPosn;
- if (dst + (dst / 10) > src) {
- ALOGD("insufficient compression (src=%ld dst=%ld), storing\n",
- src, dst);
- failed = true;
- }
- }
-
- if (failed) {
- compressionMethod = ZipEntry::kCompressStored;
- if (inputFp) rewind(inputFp);
- fseek(mZipFp, startPosn, SEEK_SET);
- /* fall through to kCompressStored case */
- }
- }
- /* handle "no compression" request, or failed compression from above */
- if (compressionMethod == ZipEntry::kCompressStored) {
- if (inputFp) {
- result = copyFpToFp(mZipFp, inputFp, &crc);
- } else {
- result = copyDataToFp(mZipFp, data, size, &crc);
- }
- if (result != NO_ERROR) {
- // don't need to truncate; happens in CDE rewrite
- ALOGD("failed copying data in\n");
- goto bail;
- }
- }
-
- // currently seeked to end of file
- uncompressedLen = inputFp ? ftell(inputFp) : size;
- } else if (sourceType == ZipEntry::kCompressDeflated) {
- /* we should support uncompressed-from-compressed, but it's not
- * important right now */
- assert(compressionMethod == ZipEntry::kCompressDeflated);
-
- bool scanResult;
- int method;
- long compressedLen;
- unsigned long longcrc;
-
- scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,
- &compressedLen, &longcrc);
- if (!scanResult || method != ZipEntry::kCompressDeflated) {
- ALOGD("this isn't a deflated gzip file?");
- result = UNKNOWN_ERROR;
- goto bail;
- }
- crc = longcrc;
-
- result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);
+ if (compressionMethod == ZipEntry::kCompressDeflated) {
+ bool failed = false;
+ result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
if (result != NO_ERROR) {
- ALOGD("failed copying gzip data in\n");
+ ALOGD("compression failed, storing\n");
+ failed = true;
+ } else {
+ /*
+ * Make sure it has compressed "enough". This probably ought
+ * to be set through an API call, but I don't expect our
+ * criteria to change over time.
+ */
+ long src = inputFp ? ftell(inputFp) : size;
+ long dst = ftell(mZipFp) - startPosn;
+ if (dst + (dst / 10) > src) {
+ ALOGD("insufficient compression (src=%ld dst=%ld), storing\n",
+ src, dst);
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ compressionMethod = ZipEntry::kCompressStored;
+ if (inputFp) rewind(inputFp);
+ fseek(mZipFp, startPosn, SEEK_SET);
+ /* fall through to kCompressStored case */
+ }
+ }
+ /* handle "no compression" request, or failed compression from above */
+ if (compressionMethod == ZipEntry::kCompressStored) {
+ if (inputFp) {
+ result = copyFpToFp(mZipFp, inputFp, &crc);
+ } else {
+ result = copyDataToFp(mZipFp, data, size, &crc);
+ }
+ if (result != NO_ERROR) {
+ // don't need to truncate; happens in CDE rewrite
+ ALOGD("failed copying data in\n");
goto bail;
}
- } else {
- assert(false);
- result = UNKNOWN_ERROR;
- goto bail;
}
+ // currently seeked to end of file
+ uncompressedLen = inputFp ? ftell(inputFp) : size;
+
/*
* We could write the "Data Descriptor", but there doesn't seem to
* be any point since we're going to go back and write the LFH.
@@ -919,6 +888,7 @@
getSize = fread(inBuf, 1, kBufSize, srcFp);
if (ferror(srcFp)) {
ALOGD("deflate read failed (errno=%d)\n", errno);
+ result = UNKNOWN_ERROR;
delete[] inBuf;
goto bail;
}
@@ -937,6 +907,7 @@
ALOGV("+++ writing %d bytes\n", (int)outSize);
if (fwrite(outBuf, 1, outSize, dstFp) != outSize) {
ALOGD("write %d failed in deflate\n", (int)outSize);
+ result = UNKNOWN_ERROR;
goto bail;
}
diff --git a/tools/zipalign/ZipFile.h b/tools/zipalign/ZipFile.h
index b0bafe9..d5ace7c 100644
--- a/tools/zipalign/ZipFile.h
+++ b/tools/zipalign/ZipFile.h
@@ -86,24 +86,10 @@
int compressionMethod, ZipEntry** ppEntry)
{
return addCommon(fileName, NULL, 0, storageName,
- ZipEntry::kCompressStored,
compressionMethod, ppEntry);
}
/*
- * Add a file that is already compressed with gzip.
- *
- * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
- */
- status_t addGzip(const char* fileName, const char* storageName,
- ZipEntry** ppEntry)
- {
- return addCommon(fileName, NULL, 0, storageName,
- ZipEntry::kCompressDeflated,
- ZipEntry::kCompressDeflated, ppEntry);
- }
-
- /*
* Add a file from an in-memory data buffer.
*
* If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
@@ -112,7 +98,6 @@
int compressionMethod, ZipEntry** ppEntry)
{
return addCommon(NULL, data, size, storageName,
- ZipEntry::kCompressStored,
compressionMethod, ppEntry);
}
@@ -231,8 +216,7 @@
/* common handler for all "add" functions */
status_t addCommon(const char* fileName, const void* data, size_t size,
- const char* storageName, int sourceType, int compressionMethod,
- ZipEntry** ppEntry);
+ const char* storageName, int compressionMethod, ZipEntry** ppEntry);
/* copy all of "srcFp" into "dstFp" */
status_t copyFpToFp(FILE* dstFp, FILE* srcFp, uint32_t* pCRC32);
diff --git a/tools/ziptime/Android.bp b/tools/ziptime/Android.bp
new file mode 100644
index 0000000..874d346
--- /dev/null
+++ b/tools/ziptime/Android.bp
@@ -0,0 +1,36 @@
+//
+// Copyright 2015 The Android Open Source Project
+//
+// 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.
+//
+
+//
+// Zip timestamp removal tool
+//
+
+cc_binary_host {
+
+ srcs: [
+ "ZipTime.cpp",
+ "ZipEntry.cpp",
+ "ZipFile.cpp",
+ ],
+
+ name: "ziptime",
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+
+}
diff --git a/tools/ziptime/Android.mk b/tools/ziptime/Android.mk
deleted file mode 100644
index 3575229..0000000
--- a/tools/ziptime/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright 2015 The Android Open Source Project
-#
-# 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.
-#
-
-#
-# Zip timestamp removal tool
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- ZipTime.cpp \
- ZipEntry.cpp \
- ZipFile.cpp
-
-LOCAL_MODULE := ziptime
-LOCAL_MODULE_HOST_OS := darwin linux windows
-
-include $(BUILD_HOST_EXECUTABLE)