Merge changes from topic 'ab_sideload'

* changes:
  Replace OTA sideload verification key when signing A/B devices.
  Install the update-payload-key in the recovery image as well.
diff --git a/core/Makefile b/core/Makefile
index d6dae0a..e763c73 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -284,7 +284,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)
@@ -400,6 +400,15 @@
 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))
+
+# -----------------------------------------------------------------
 
 # The dev key is used to sign this package, and as the key required
 # for future OTA packages installed by this system.  Actual product
diff --git a/core/aux_config.mk b/core/aux_config.mk
new file mode 100644
index 0000000..decff34
--- /dev/null
+++ b/core/aux_config.mk
@@ -0,0 +1,183 @@
+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
+
+all_configs := $(shell find device vendor -maxdepth 4 -name '*$(variant_sfx)' -o -name '*$(os_sfx)' | sort)
+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 8a1c5ee..aac551a 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
 
@@ -192,9 +206,13 @@
 my_register_name := $(my_register_name)$($(my_prefix)2ND_ARCH_MODULE_SUFFIX)
 endif
 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
@@ -289,6 +307,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)
 
@@ -333,21 +352,22 @@
 	$(copy-file-to-new-target)
 	$(PRIVATE_POST_INSTALL_CMD)
 
+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))
-ifneq ($(my_init_rc),)
-my_init_rc_pairs += $(LOCAL_PATH)/$(my_init_rc):$(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(my_init_rc))
-endif
-ifneq ($(LOCAL_INIT_RC),)
-my_init_rc_pairs += $(LOCAL_PATH)/$(LOCAL_INIT_RC):$(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir $(LOCAL_INIT_RC))
-# Make sure we don't define the rule twice in multilib module.
-LOCAL_INIT_RC :=
-endif
-ifneq ($(my_init_rc_pairs),)
-my_init_rc_installed := $(call copy-many-files,$(my_init_rc_pairs))
+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)))
+
+# 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_register_name) : $(my_init_rc_installed)
-endif # my_init_rc_pairs
+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)))
diff --git a/core/binary.mk b/core/binary.mk
index 85d084f..e71507c 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -71,7 +71,7 @@
   endif
 
   # Make sure we've built the NDK.
-  my_additional_dependencies += 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 :(
@@ -99,6 +99,11 @@
     $(shell if [ $(LOCAL_SDK_VERSION) -lt $(my_min_sdk_version) ]; then \
         echo $(my_min_sdk_version); else echo $(LOCAL_SDK_VERSION); fi)
 
+  # 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)
+
   my_ndk_source_root := \
       $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources
   my_ndk_sysroot := \
@@ -210,16 +215,43 @@
   endif
   endif
   endif
+endif
 
-  my_generated_ndk_shared_libraries := \
-      $(filter $(NDK_MIGRATED_LIBS),$(my_system_shared_libraries))
+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
+
+ifdef 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 $(NDK_MIGRATED_LIBS),$(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)
 ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
 my_cflags += -fpie
@@ -227,6 +259,7 @@
 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))
@@ -266,6 +299,20 @@
 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
@@ -329,15 +376,17 @@
 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))
   my_static_libraries += $(COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES)
 endif
+endif
 
 ####################################################
 ## Add FDO flags if FDO is turned on and supported
@@ -377,24 +426,24 @@
 my_target_global_cppflags := $(my_ndk_stl_cppflags)
 else
 my_target_global_c_includes := $(SRC_HEADERS) \
-    $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_PROJECT_INCLUDES) \
-    $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_C_INCLUDES)
+    $($(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)TARGET_PROJECT_SYSTEM_INCLUDES) \
-    $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_C_SYSTEM_INCLUDES)
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_SYSTEM_INCLUDES) \
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_SYSTEM_INCLUDES)
 my_target_global_cppflags :=
 endif # LOCAL_SDK_VERSION
 
 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_target_global_cppflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_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_target_global_cppflags += $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_CPPFLAGS)
+my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)GLOBAL_LDFLAGS)
 endif # my_clang
 
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_GLOBAL_C_INCLUDES := $(my_target_global_c_includes)
@@ -453,9 +502,9 @@
 endif
 
 ifeq ($(my_clang),true)
-    my_coverage_lib := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBPROFILE_RT)
+    my_coverage_lib := $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)LIBPROFILE_RT)
 else
-    my_coverage_lib := $(call intermediates-dir-for,STATIC_LIBRARIES,libgcov,,,$(LOCAL_2ND_ARCH_VAR_PREFIX))/libgcov.a
+    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)
@@ -483,7 +532,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)),)
@@ -1180,34 +1229,6 @@
 endif
 
 
-####################################################
-## For NDK-built libraries, move LOCAL_SHARED_LIBRARY
-## references to my_ldlibs, so that we use the NDK
-## prebuilt library and headers for linking.
-####################################################
-ifndef LOCAL_IS_HOST_MODULE
-my_allowed_ldlibs :=
-ifdef LOCAL_SDK_VERSION
-  my_ndk_shared_libraries := $(filter $(addprefix lib,$(NDK_PREBUILT_SHARED_LIBRARIES)),$(my_shared_libraries))
-  my_shared_libraries := $(filter-out $(my_ndk_shared_libraries),$(my_shared_libraries))
-  my_ldlibs += $(patsubst lib%,-l%,$(my_ndk_shared_libraries))
-  my_ndk_shared_libraries :=
-  my_allowed_ldlibs := $(addprefix -l,$(NDK_PREBUILT_SHARED_LIBRARIES))
-endif
-
-# 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
-
-
 ##########################################################
 ## Set up installed module dependency
 ## We cannot compute the full path of the LOCAL_SHARED_LIBRARIES for
@@ -1238,9 +1259,9 @@
 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))
 $(import_includes): PRIVATE_IMPORT_EXPORT_INCLUDES := $(import_includes_deps)
 $(import_includes) : $(import_includes_deps)
 	@echo Import includes file: $@
@@ -1253,7 +1274,6 @@
 	$(hide) touch $@
 endif
 
-
 ####################################################
 ## Verify that NDK-built libraries only link against
 ## other NDK-built libraries
@@ -1269,11 +1289,11 @@
 endif
 my_link_type_deps := $(strip \
    $(foreach l,$(my_whole_static_libraries) $(my_static_libraries), \
-     $(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/link_type))
+     $(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/link_type))
 ifneq ($(LOCAL_MODULE_CLASS),STATIC_LIBRARIES)
 my_link_type_deps += $(strip \
    $(foreach l,$(my_shared_libraries), \
-     $(call intermediates-dir-for,SHARED_LIBRARIES,$(l),$(LOCAL_IS_HOST_MODULE),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/link_type))
+     $(call intermediates-dir-for,SHARED_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/link_type))
 endif
 $(my_link_type): PRIVATE_DEPS := $(my_link_type_deps)
 $(my_link_type): PRIVATE_MODULE := $(LOCAL_MODULE)
@@ -1400,12 +1420,17 @@
     $(addprefix $(my_ndk_sysroot_lib)/, \
         $(addsuffix $(so_suffix), $(my_system_shared_libraries)))
 
-my_built_ndk_shared_libraries_fullpath := \
-    $(addprefix $(my_built_ndk_libs)/,\
-        $(addsuffix $(so_suffix),$(my_generated_ndk_shared_libraries)))
+# 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_built_ndk_shared_libraries_fullpath) \
+    $(my_ndk_shared_libraries_fullpath) \
     $(my_system_shared_libraries_fullpath) \
 
 else
@@ -1426,7 +1451,7 @@
 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)
@@ -1435,7 +1460,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.
@@ -1614,15 +1639,15 @@
 # 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),$(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))
 # 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),$(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))
 # 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),$(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))
 $(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.
diff --git a/core/clang/config.mk b/core/clang/config.mk
index 4685514..7113892 100644
--- a/core/clang/config.mk
+++ b/core/clang/config.mk
@@ -143,4 +143,24 @@
 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/ \
+  external/valgrind/ \
+  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/tidy.mk b/core/clang/tidy.mk
index d50b43d..860257f 100644
--- a/core/clang/tidy.mk
+++ b/core/clang/tidy.mk
@@ -19,30 +19,30 @@
 # and misc-macro-parentheses, but not google-readability*
 # or google-runtime-references.
 DEFAULT_GLOBAL_TIDY_CHECKS := \
-  -*,google*,performance*,misc-macro-parentheses \
-  ,-google-readability*,-google-runtime-references
+  $(subst $(space),, \
+    -*,google*,performance*,misc-macro-parentheses \
+    ,-google-readability*,-google-runtime-references \
+  )
 
-# Disable style rules usually not followed by external projects.
+# There are too many clang-tidy warnings in external and vendor projects.
+# Enable only some google checks for these projects.
+DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS := \
+  $(subst $(space),, \
+    -*,google*,-google-build-using-namespace \
+    ,-google-readability*,-google-runtime-references \
+    ,-google-explicit-constructor,-google-runtime-int \
+  )
+
 # Every word in DEFAULT_LOCAL_TIDY_CHECKS list has the following format:
-#   <local_path_prefix>:,<tidy-check-pattern>
-# The tidy-check-patterns of all matching local_path_prefixes will be used.
-# For example, external/google* projects will have:
-#   ,-google-build-using-namespace,-google-explicit-constructor
-#   ,-google-runtime-int,-misc-macro-parentheses,
-#   ,google-runtime-int,misc-macro-parentheses
-# where google-runtime-int and misc-macro-parentheses are enabled at the end.
+#   <local_path_prefix>:,<tidy-checks>
+# The last matched local_path_prefix should be the most specific to be used.
 DEFAULT_LOCAL_TIDY_CHECKS := \
-  external/:,-google-build-using-namespace \
-  external/:,-google-explicit-constructor,-google-runtime-int \
-  external/:,-misc-macro-parentheses \
-  external/google:,google-runtime-int,misc-macro-parentheses \
-  external/webrtc/:,google-runtime-int \
-  hardware/qcom:,-google-build-using-namespace \
-  hardware/qcom:,-google-explicit-constructor,-google-runtime-int \
-  vendor/lge:,-google-build-using-namespace,-misc-macro-parentheses \
-  vendor/lge:,-google-explicit-constructor,-google-runtime-int \
-  vendor/widevine:,-google-build-using-namespace,-misc-macro-parentheses \
-  vendor/widevine:,-google-explicit-constructor,-google-runtime-int \
+  external/:$(DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS) \
+  external/google:$(DEFAULT_GLOBAL_TIDY_CHECKS) \
+  external/webrtc:$(DEFAULT_GLOBAL_TIDY_CHECKS) \
+  hardware/qcom:$(DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS) \
+  vendor/:$(DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS) \
+  vendor/google:$(DEFAULT_GLOBAL_TIDY_CHECKS) \
 
 # Returns 2nd word of $(1) if $(2) has prefix of the 1st word of $(1).
 define find_default_local_tidy_check2
@@ -54,11 +54,11 @@
 $(call find_default_local_tidy_check2,$(subst :,$(space),$(1)),$(2))
 endef
 
-# Returns concatenated tidy check patterns from the
-# DEFAULT_GLOBAL_TIDY_CHECKS and all matched patterns
-# in DEFAULT_LOCAL_TIDY_CHECKS based on given directory path $(1).
+# 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
-$(subst $(space),, \
+$(lastword \
   $(DEFAULT_GLOBAL_TIDY_CHECKS) \
   $(foreach pattern,$(DEFAULT_LOCAL_TIDY_CHECKS), \
     $(call find_default_local_tidy_check,$(pattern),$(1)) \
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index f61e3f7..de6a5eb 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -152,16 +152,12 @@
 
 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)}
+    $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)
 current_sanitize_target := $(strip $(SANITIZE_TARGET))
 ifeq (,$(current_sanitize_target))
   current_sanitize_target := false
 endif
-aapt_config_list :=
 force_installclean := false
 force_objclean := false
 
@@ -236,7 +232,6 @@
 	$(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 \
@@ -244,8 +239,6 @@
 	$(PRODUCT_OUT)/system \
 	$(PRODUCT_OUT)/vendor \
 	$(PRODUCT_OUT)/oem \
-	$(PRODUCT_OUT)/dex_bootjars \
-	$(PRODUCT_OUT)/obj/JAVA_LIBRARIES \
 	$(PRODUCT_OUT)/obj/FAKE
 
 # The files/dirs to delete during a dataclean, which removes any files
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 562a272..55d0021 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -142,7 +142,9 @@
 LOCAL_PROTOC_FLAGS:=
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS:=
 LOCAL_NO_CRT:=
+LOCAL_NO_LIBCOMPILER_RT:=
 LOCAL_NO_LIBGCC:=
+LOCAL_NO_PIC:=
 LOCAL_PROPRIETARY_MODULE:=
 LOCAL_OEM_MODULE:=
 LOCAL_ODM_MODULE:=
@@ -201,6 +203,7 @@
 LOCAL_NDK_VERSION:=current
 LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES:=
 LOCAL_LOGTAGS_FILES:=
+LOCAL_RECORDED_MODULE_TYPE:=
 
 # arch specific variables
 LOCAL_SRC_FILES_$(TARGET_ARCH):=
@@ -362,6 +365,16 @@
 LOCAL_JAVA_LANGUAGE_VERSION:=
 LOCAL_CTS_GTEST_LIST_EXECUTABLE:=
 
+LOCAL_IS_AUX_MODULE :=
+LOCAL_AUX_TOOLCHAIN :=
+LOCAL_AUX_OS :=
+LOCAL_AUX_ARCH :=
+LOCAL_AUX_SUBARCH :=
+LOCAL_AUX_CPU :=
+LOCAL_AUX_OS_VARIANT :=
+LOCAL_CUSTOM_BUILD_STEP_INPUT:=
+LOCAL_CUSTOM_BUILD_STEP_OUTPUT:=
+
 # Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
 # iterate over thousands of entries every time.
 # Leave the current makefile to make sure we don't break anything
diff --git a/core/config.mk b/core/config.mk
index 594c273..4ad212f 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -70,6 +70,8 @@
 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_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
diff --git a/core/copy_headers.mk b/core/copy_headers.mk
index 7d5a5d9..417a76c 100644
--- a/core/copy_headers.mk
+++ b/core/copy_headers.mk
@@ -1,6 +1,7 @@
 ###########################################################
 ## Copy headers to the install tree
 ###########################################################
+$(call record-module-type,COPY_HEADERS)
 ifneq ($(strip $(LOCAL_IS_HOST_MODULE)),)
   my_prefix := HOST_
 else
diff --git a/core/definitions.mk b/core/definitions.mk
index d3c113e..d1284e6 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -92,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
 ###########################################################
@@ -453,6 +457,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
@@ -463,7 +489,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
@@ -475,7 +501,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)) \
@@ -500,7 +526,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
 
@@ -515,7 +541,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 \
@@ -525,7 +551,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)) \
       , \
@@ -545,7 +571,7 @@
         $(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
 
@@ -1193,12 +1219,12 @@
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
 define transform-cpp-to-o
 $(if $(PRIVATE_TIDY_CHECKS),
-  @echo "target tidy $(PRIVATE_ARM_MODE) C++: $<"
+  @echo "$($(PRIVATE_PREFIX)DISPLAY) tidy $(PRIVATE_ARM_MODE) C++: $<"
   $(clang-tidy-cpp))
 endef
 else
 define transform-cpp-to-o
-@echo "target $(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"
+@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) \
@@ -1242,12 +1268,12 @@
 ifneq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
 define transform-c-to-o
 $(if $(PRIVATE_TIDY_CHECKS),
-  @echo "target tidy $(PRIVATE_ARM_MODE) C: $<"
+  @echo "$($(PRIVATE_PREFIX)DISPLAY) tidy $(PRIVATE_ARM_MODE) C: $<"
   $(clang-tidy-c))
 endef
 else
 define transform-c-to-o
-@echo "target $(PRIVATE_ARM_MODE) C: $(PRIVATE_MODULE) <= $<"
+@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) \
@@ -1258,7 +1284,7 @@
 endif
 
 define transform-s-to-o-no-deps
-@echo "target asm: $(PRIVATE_MODULE) <= $<"
+@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)) \
@@ -1287,7 +1313,7 @@
 ###########################################################
 
 define transform-m-to-o-no-deps
-@echo "target ObjC: $(PRIVATE_MODULE) <= $<"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) ObjC: $(PRIVATE_MODULE) <= $<"
 $(call transform-c-or-s-to-o-no-deps, $(PRIVATE_CFLAGS) $(PRIVATE_DEBUG_CFLAGS))
 endef
 
@@ -1546,7 +1572,7 @@
 # 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)
@@ -1555,6 +1581,89 @@
     $(PRIVATE_ARFLAGS) $@,$(PRIVATE_ALL_OBJECTS))
 endef
 
+# $(1): the full path of the source 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) \
+        $(PRIVATE_ARFLAGS) $@ $$filelist
+
+endef
+
+define extract-and-include-aux-whole-static-libs
+$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)))
+$(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \
+    $(call _extract-and-include-single-aux-whole-static-lib, $(lib)))
+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 $@
+$(extract-and-include-aux-whole-static-libs)
+$(call split-long-arguments,$(PRIVATE_AR) \
+    $(AUX_GLOBAL_ARFLAGS) \
+    $(PRIVATE_ARFLAGS) $@,$(PRIVATE_ALL_OBJECTS))
+endef
+
+define transform-o-to-aux-executable-inner
+$(hide) $(PRIVATE_CXX) -pie \
+	-Bdynamic \
+	-Wl,--gc-sections \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(call normalize-target-libraries,$(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 \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(call normalize-target-libraries,$(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
+
 ###########################################################
 ## Commands for running host ar
 ###########################################################
@@ -1699,7 +1808,7 @@
 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
@@ -1714,14 +1823,14 @@
 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 "target Strip (mini debug info): $(PRIVATE_MODULE) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) Strip (mini debug info): $(PRIVATE_MODULE) ($@)"
 @mkdir -p $(dir $@)
 $(hide) $(PRIVATE_NM) -D $< --format=posix --defined-only | awk '{ print $$1 }' | sort >$@.dynsyms
 $(hide) $(PRIVATE_NM) $< --format=posix --defined-only | awk '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' | sort >$@.funcsyms
@@ -1738,7 +1847,7 @@
 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` \
@@ -1750,7 +1859,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
@@ -1787,7 +1896,7 @@
 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
@@ -1830,7 +1939,7 @@
 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
@@ -2049,7 +2158,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
 
@@ -2568,19 +2677,19 @@
 
 # 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) ($@)"
+@echo "$($(PRIVATE_PREFIX)DISPLAY) 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
 
@@ -2627,7 +2736,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
@@ -2840,6 +2949,48 @@
   $(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
+
+$(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
+
 ###########################################################
 ## Other includes
 ###########################################################
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index 0f18a58..06506db 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
diff --git a/core/dumpvar.mk b/core/dumpvar.mk
index 4b3486a..74ea3ff 100644
--- a/core/dumpvar.mk
+++ b/core/dumpvar.mk
@@ -22,7 +22,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 += \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 1df25d2..f234702 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -273,6 +273,9 @@
 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
diff --git a/core/executable.mk b/core/executable.mk
index 8652077..f1b2462 100644
--- a/core/executable.mk
+++ b/core/executable.mk
@@ -16,6 +16,7 @@
 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,
diff --git a/core/fuzz_test.mk b/core/fuzz_test.mk
index fc582b3..c31e2e7 100644
--- a/core/fuzz_test.mk
+++ b/core/fuzz_test.mk
@@ -2,6 +2,7 @@
 ## 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.)
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index 7fdf249..cee3cc4 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
diff --git a/core/host_dalvik_static_java_library.mk b/core/host_dalvik_static_java_library.mk
index b79c0ea..78faf73 100644
--- a/core/host_dalvik_static_java_library.mk
+++ b/core/host_dalvik_static_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_STATIC_JAVA_LIBRARY)
 
 #
 # Rules for building a host dalvik static java library.
diff --git a/core/host_executable.mk b/core/host_executable.mk
index 0060c3e..78223eb 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 :=
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 9aa2a7c..0a7dd8a 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.
 #
diff --git a/core/host_native_test.mk b/core/host_native_test.mk
index 2a6097d..aa05bb3 100644
--- a/core/host_native_test.mk
+++ b/core/host_native_test.mk
@@ -2,6 +2,7 @@
 ## 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)
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..df24b63 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 :=
diff --git a/core/host_static_library.mk b/core/host_static_library.mk
index 068c702..61f5569 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 :=
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/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index 6136968..9f5d445 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.
diff --git a/core/java_library.mk b/core/java_library.mk
index 283e9ad..b132fa6 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)
diff --git a/core/main.mk b/core/main.mk
index 59e9524..3720971 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -457,6 +457,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
@@ -934,6 +937,8 @@
 all_modules: $(my_all_modules)
 endif
 
+.PHONY: auxiliary
+auxiliary: $(INSTALLED_AUX_TARGETS)
 
 # Build files and then package it into the rom formats
 .PHONY: droidcore
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 fe378b8..7b04d87 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 bb93eb0..8b49fbd 100644
--- a/core/native_test.mk
+++ b/core/native_test.mk
@@ -2,6 +2,7 @@
 ## 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)
diff --git a/core/ninja.mk b/core/ninja.mk
index 62102ba..069a43e 100644
--- a/core/ninja.mk
+++ b/core/ninja.mk
@@ -17,6 +17,7 @@
 	DUMP_% \
 	ECLIPSE-% \
 	PRODUCT-% \
+	AUX-% \
 	boottarball-nodeps \
 	brillo_tests \
 	btnod \
diff --git a/core/notice_files.mk b/core/notice_files.mk
index e7f8974..f0013c2 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))
diff --git a/core/package.mk b/core/package.mk
index 8c2c435..4fe058d 100644
--- a/core/package.mk
+++ b/core/package.mk
@@ -2,6 +2,8 @@
 # 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)
+
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
 LOCAL_MULTILIB := first
 endif
diff --git a/core/phony_package.mk b/core/phony_package.mk
index b534335..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
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index cbe2079..5831e24 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -5,6 +5,7 @@
 ## None.
 ##
 ###########################################################
+$(call record-module-type,PREBUILT)
 
 ifdef LOCAL_IS_HOST_MODULE
   my_prefix := HOST_
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/static_java_library.mk b/core/static_java_library.mk
index d3324f8..d6dd065 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
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_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/tasks/check_boot_jars/package_whitelist.txt b/core/tasks/check_boot_jars/package_whitelist.txt
index daf13fe..601017b 100644
--- a/core/tasks/check_boot_jars/package_whitelist.txt
+++ b/core/tasks/check_boot_jars/package_whitelist.txt
@@ -67,6 +67,8 @@
 org\.w3c\.dom\.ls
 org\.w3c\.dom\.traversal
 # OpenJdk internal implementation.
+sun\.invoke\.util
+sun\.invoke\.empty
 sun\.misc
 sun\.util.*
 sun\.text.*
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/warn.py b/tools/warn.py
index f17e8ac..f118263 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -74,6 +74,9 @@
         '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,   'members':[], 'option':'',
+        'description':'make: LOCAL_CLANG is false',
+        'patterns':[r".*: warning: LOCAL_CLANG is set to false"] },
     { 'category':'C/C++',   'severity':severity.HIGH,     'members':[], 'option':'-Wimplicit-function-declaration',
         'description':'Implicit function declaration',
         'patterns':[r".*: warning: implicit declaration of function .+",