Merge "Always define sdk_addon as phony"
diff --git a/Changes.md b/Changes.md
index baa5e6e..4aa7ea2 100644
--- a/Changes.md
+++ b/Changes.md
@@ -1,5 +1,31 @@
 # Build System Changes for Android.mk Writers
 
+## `DIST_DIR`, `dist_goal`, and `dist-for-goals`  {#dist}
+
+`DIST_DIR` and `dist_goal` are no longer available when reading Android.mk
+files (or other build tasks). Always use `dist-for-goals` instead, which takes
+a PHONY goal, and a list of files to copy to `$DIST_DIR`. Whenever `dist` is
+specified, and the goal would be built (either explicitly on the command line,
+or as a dependency of something on the command line), that file will be copied
+into `$DIST_DIR`. For example,
+
+``` make
+$(call dist-for-goals,foo,bar/baz)
+```
+
+will copy `bar/baz` into `$DIST_DIR/baz` when `m foo dist` is run.
+
+#### Renames during copy
+
+Instead of specifying just a file, a destination name can be specified,
+including subdirectories:
+
+``` make
+$(call dist-for-goals,foo,bar/baz:logs/foo.log)
+```
+
+will copy `bar/baz` into `$DIST_DIR/logs/foo.log` when `m foo dist` is run.
+
 ## `.PHONY` rule enforcement  {#phony_targets}
 
 There are several new warnings/errors meant to ensure the proper use of
diff --git a/CleanSpec.mk b/CleanSpec.mk
index a9093d2..39441e1 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -512,6 +512,9 @@
 # Remove strip.sh intermediates to save space
 $(call add-clean-step, find $(OUT_DIR) \( -name "*.so.debug" -o -name "*.so.dynsyms" -o -name "*.so.funcsyms" -o -name "*.so.keep_symbols" -o -name "*.so.mini_debuginfo.xz" \) -print0 | xargs -0 rm -f)
 
+# Clean up old ninja files
+$(call add-clean-step, rm -f $(OUT_DIR)/build-*-dist*.ninja)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/common/core.mk b/common/core.mk
new file mode 100644
index 0000000..e5264b0
--- /dev/null
+++ b/common/core.mk
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2018 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.
+#
+
+# Only use ANDROID_BUILD_SHELL to wrap around bash.
+# DO NOT use other shells such as zsh.
+ifdef ANDROID_BUILD_SHELL
+SHELL := $(ANDROID_BUILD_SHELL)
+else
+# Use bash, not whatever shell somebody has installed as /bin/sh
+# This is repeated from main.mk, since envsetup.sh runs this file
+# directly.
+SHELL := /bin/bash
+endif
+
+# Utility variables.
+empty :=
+space := $(empty) $(empty)
+comma := ,
+# Note that make will eat the newline just before endef.
+define newline
+
+
+endef
+# The pound character "#"
+define pound
+#
+endef
+# Unfortunately you can't simply define backslash as \ or \\.
+backslash := \a
+backslash := $(patsubst %a,%,$(backslash))
+
+# Prevent accidentally changing these variables
+.KATI_READONLY := SHELL empty space comma newline pound backslash
+
+# Basic warning/error wrappers. These will be redefined to include the local
+# module information when reading Android.mk files.
+define pretty-warning
+$(warning $(1))
+endef
+
+define pretty-error
+$(error $(1))
+endef
diff --git a/core/math.mk b/common/math.mk
similarity index 100%
rename from core/math.mk
rename to common/math.mk
diff --git a/core/strings.mk b/common/strings.mk
similarity index 100%
rename from core/strings.mk
rename to common/strings.mk
diff --git a/core/Makefile b/core/Makefile
index f7f6f35..fe728d6 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1921,7 +1921,7 @@
       build/make/tools/releasetools/build_image.py \
       $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
       $(systemimage_intermediates)/generated_system_image_info.txt \
-      || ( mkdir -p $$(DIST_DIR); cp $(INSTALLED_FILES_FILE) $$(DIST_DIR)/installed-files-rescued.txt; \
+      || ( mkdir -p $${DIST_DIR}; cp $(INSTALLED_FILES_FILE) $${DIST_DIR}/installed-files-rescued.txt; \
            exit 1 )
 endef
 
diff --git a/core/config.mk b/core/config.mk
index aeb8aee..0e4e1fb 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -17,40 +17,20 @@
 $(error done)
 endif
 
-# Only use ANDROID_BUILD_SHELL to wrap around bash.
-# DO NOT use other shells such as zsh.
-ifdef ANDROID_BUILD_SHELL
-SHELL := $(ANDROID_BUILD_SHELL)
-else
-# Use bash, not whatever shell somebody has installed as /bin/sh
-# This is repeated from main.mk, since envsetup.sh runs this file
-# directly.
-SHELL := /bin/bash
-endif
+BUILD_SYSTEM :=$= build/make/core
+BUILD_SYSTEM_COMMON :=$= build/make/common
 
-# Utility variables.
-empty :=
-space := $(empty) $(empty)
-comma := ,
-# Note that make will eat the newline just before endef.
-define newline
-
-
-endef
-# The pound character "#"
-define pound
-#
-endef
-# Unfortunately you can't simply define backslash as \ or \\.
-backslash := \a
-backslash := $(patsubst %a,%,$(backslash))
-
-# Prevent accidentally changing these variables
-.KATI_READONLY := SHELL empty space comma newline pound backslash
+include $(BUILD_SYSTEM_COMMON)/core.mk
 
 # Mark variables that should be coming as environment variables from soong_ui
 # as readonly
-.KATI_READONLY := OUT_DIR TMPDIR BUILD_DATETIME_FILE DIST_DIR
+.KATI_READONLY := OUT_DIR TMPDIR BUILD_DATETIME_FILE
+ifdef CALLED_FROM_SETUP
+  .KATI_READONLY := CALLED_FROM_SETUP
+endif
+ifdef KATI_PACKAGE_MK_DIR
+  .KATI_READONLY := KATI_PACKAGE_MK_DIR
+endif
 
 # Mark variables deprecated/obsolete
 CHANGES_URL := https://android.googlesource.com/platform/build/+/master/Changes.md
@@ -109,6 +89,7 @@
   TARGET_NDK_GCC_VERSION 2ND_TARGET_NDK_GCC_VERSION \
   GLOBAL_CFLAGS_NO_OVERRIDE GLOBAL_CPPFLAGS_NO_OVERRIDE \
   ,GCC support has been removed. Use Clang instead)
+$(KATI_obsolete_var DIST_DIR dist_goal,Use dist-for-goals instead. See $(CHANGES_URL)#dist)
 
 # This is marked as obsolete in envsetup.mk after reading the BoardConfig.mk
 $(KATI_deprecate_export It is a global setting. See $(CHANGES_URL)#export_keyword)
@@ -121,9 +102,6 @@
 
 ORIGINAL_MAKECMDGOALS := $(MAKECMDGOALS)
 
-dist_goal := $(strip $(filter dist,$(MAKECMDGOALS)))
-MAKECMDGOALS := $(strip $(filter-out dist,$(MAKECMDGOALS)))
-
 UNAME := $(shell uname -sm)
 
 SRC_TARGET_DIR := $(TOPDIR)build/target
@@ -138,9 +116,9 @@
 
 # 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
+include $(BUILD_SYSTEM_COMMON)/math.mk
 
-include $(BUILD_SYSTEM)/strings.mk
+include $(BUILD_SYSTEM_COMMON)/strings.mk
 
 # Various mappings to avoid hard-coding paths all over the place
 include $(BUILD_SYSTEM)/pathmap.mk
diff --git a/core/definitions.mk b/core/definitions.mk
index 3538166..baa2342 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -806,29 +806,13 @@
 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
-
 ###########################################################
-## Output the command lines, or not
+## Legacy showcommands compatibility
 ###########################################################
 
-ifeq ($(strip $(SHOW_COMMANDS)),)
 define pretty
 @echo $1
 endef
-else
-define pretty
-endef
-endif
 
 ###########################################################
 ## Commands for including the dependency files the compiler generates
@@ -2679,6 +2663,10 @@
 
 # Copy dex files, invoking $(HIDDENAPI) on them in the process.
 # Also make the source dex file an input of the hiddenapi singleton rule in dex_preopt.mk.
+# Users can set UNSAFE_DISABLE_HIDDENAPI_FLAGS=true to skip this step. This is
+# meant to speed up local incremental builds. Note that skipping this step changes
+# Java semantics of the result dex bytecode. Use at own risk.
+ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true)
 define hiddenapi-copy-dex-files
 $(2): $(1) $(HIDDENAPI) $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
       $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
@@ -2692,9 +2680,17 @@
 	    --blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
 
 $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): $(1)
-$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): \
-    PRIVATE_DEX_INPUTS := $$(PRIVATE_DEX_INPUTS) $(1)
+$(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): PRIVATE_DEX_INPUTS := $$(PRIVATE_DEX_INPUTS) $(1)
 endef
+else  # UNSAFE_DISABLE_HIDDENAPI_FLAGS
+define hiddenapi-copy-dex-files
+$(2): $(1)
+	echo "WARNING: skipping hiddenapi post-processing for $(1)" 1>&2
+	@rm -rf $(dir $(2))
+	@mkdir -p $(dir $(2))
+	find $(dir $(1)) -maxdepth 1 -name "classes*.dex" | xargs -I{} cp -f {} $(dir $(2))/
+endef
+endif  # UNSAFE_DISABLE_HIDDENAPI_FLAGS
 
 # Generate a greylist.txt from a classes.jar
 define hiddenapi-generate-greylist-txt
@@ -2705,8 +2701,8 @@
 $(3): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
 	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) \
 	    --write-whitelist $(2) \
-	    --write-greylist $(3) \
-	    --write-greylist 26,28:$(4)
+	    --write-greylist none,28:$(3) \
+	    --write-greylist 26:$(4)
 
 $(5): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
 	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) \
diff --git a/core/distdir.mk b/core/distdir.mk
index c074186..5f40407 100644
--- a/core/distdir.mk
+++ b/core/distdir.mk
@@ -17,52 +17,53 @@
 # When specifying "dist", the user has asked that we copy the important
 # files from this build into DIST_DIR.
 
-ifdef dist_goal
-
-# $(1): source file
-# $(2): destination file
-# $(3): goals that should copy the file
-#
-define copy-one-dist-file
-$(3): $(2)
-$(2): $(1)
-	@echo "Dist: $$@"
-	$$(copy-file-to-new-target-with-cp)
-endef
-
-# A global variable to remember all dist'ed src:dst pairs.
-# So if a src:dst is already dist'ed by another goal,
-# we should just establish the dependency and don't really call the
-# copy-one-dist-file to avoid multiple rules for the same target.
+# list of all goals that depend on any dist files
+_all_dist_goals :=
+# pairs of goal:distfile
+_all_dist_goal_output_pairs :=
+# pairs of srcfile:distfile
 _all_dist_src_dst_pairs :=
+
 # Other parts of the system should use this function to associate
 # certain files with certain goals.  When those goals are built
 # and "dist" is specified, the marked files will be copied to DIST_DIR.
 #
-# $(1): a list of goals  (e.g. droid, sdk, pdk, ndk)
+# $(1): a list of goals  (e.g. droid, sdk, pdk, ndk). These must be PHONY
 # $(2): the dist files to add to those goals.  If the file contains ':',
 #       the text following the colon is the name that the file is copied
 #       to under the dist directory.  Subdirs are ok, and will be created
 #       at copy time if necessary.
 define dist-for-goals
+$(if $(strip $(2)), \
+  $(eval _all_dist_goals += $$(1))) \
 $(foreach file,$(2), \
-  $(eval fw := $(subst :,$(space),$(file))) \
-  $(eval src := $(word 1,$(fw))) \
-  $(eval dst := $(word 2,$(fw))) \
-  $(eval dst := $(if $(dst),$(dst),$(notdir $(src)))) \
-  $(if $(filter $(_all_dist_src_dst_pairs),$(src):$(dst)),\
-    $(eval $(call add-dependency,$(1),$(DIST_DIR)/$(dst))),\
-    $(eval $(call copy-one-dist-file,\
-      $(src),$(DIST_DIR)/$(dst),$(1)))\
-      $(eval _all_dist_src_dst_pairs += $(src):$(dst))\
-  )\
-)
+  $(eval src := $(call word-colon,1,$(file))) \
+  $(eval dst := $(call word-colon,2,$(file))) \
+  $(if $(dst),,$(eval dst := $$(notdir $$(src)))) \
+  $(eval _all_dist_src_dst_pairs += $$(src):$$(dst)) \
+  $(foreach goal,$(1), \
+    $(eval _all_dist_goal_output_pairs += $$(goal):$$(dst))))
 endef
 
-else # !dist_goal
+#------------------------------------------------------------------
+# To be used at the end of the build to collect all the uses of
+# dist-for-goals, and write them into a file for the packaging step to use.
 
-# empty definition when not building dist
-define dist-for-goals
+# $(1): The file to write
+define dist-write-file
+$(strip \
+  $(KATI_obsolete_var dist-for-goals,Cannot be used after dist-write-file) \
+  $(foreach goal,$(sort $(_all_dist_goals)), \
+    $(eval $$(goal): _dist_$$(goal))) \
+  $(shell mkdir -p $(dir $(1))) \
+  $(file >$(1).tmp, \
+    DIST_GOAL_OUTPUT_PAIRS := $(sort $(_all_dist_goal_output_pairs)) \
+    $(newline)DIST_SRC_DST_PAIRS := $(sort $(_all_dist_src_dst_pairs))) \
+  $(shell if ! cmp -s $(1).tmp $(1); then \
+            mv $(1).tmp $(1); \
+          else \
+            rm $(1).tmp; \
+          fi))
 endef
 
-endif # !dist_goal
+.KATI_READONLY := dist-for-goals dist-write-file
diff --git a/core/main.mk b/core/main.mk
index ecb8c0d..6ff5f93 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -36,8 +36,6 @@
 TOP := .
 TOPDIR :=
 
-BUILD_SYSTEM := $(TOPDIR)build/make/core
-
 # This is the default target.  It must be the first declared target.
 .PHONY: droid
 DEFAULT_GOAL := droid
@@ -48,7 +46,7 @@
 
 # Set up various standard variables based on configuration
 # and host information.
-include $(BUILD_SYSTEM)/config.mk
+include build/make/core/config.mk
 
 ifneq ($(filter $(dont_bother_goals), $(MAKECMDGOALS)),)
 dont_bother := true
@@ -419,6 +417,19 @@
 ENFORCE_RRO_SOURCES :=
 endif
 
+# Color-coded warnings including current module info
+# $(1): message to print
+define pretty-warning
+$(shell $(call echo-warning,$(LOCAL_MODULE_MAKEFILE),$(LOCAL_MODULE): $(1)))
+endef
+
+# Color-coded errors including current module info
+# $(1): message to print
+define pretty-error
+$(shell $(call echo-error,$(LOCAL_MODULE_MAKEFILE),$(LOCAL_MODULE): $(1)))
+$(error done)
+endef
+
 subdir_makefiles_inc := .
 FULL_BUILD :=
 
@@ -493,6 +504,18 @@
 # -------------------------------------------------------------------
 
 # -------------------------------------------------------------------
+# Use basic warning/error messages now that LOCAL_MODULE_MAKEFILE
+# and LOCAL_MODULE aren't useful anymore.
+# -------------------------------------------------------------------
+define pretty-warning
+$(warning $(1))
+endef
+
+define pretty-error
+$(error $(1))
+endef
+
+# -------------------------------------------------------------------
 # Enforce to generate all RRO packages for modules having resource
 # overlays.
 # -------------------------------------------------------------------
@@ -1010,6 +1033,8 @@
 
 ifdef FULL_BUILD
   product_FILES := $(call product-installed-files, $(INTERNAL_PRODUCT))
+  # WARNING: The product_MODULES variable is depended on by external files.
+  product_MODULES := $(_pif_modules)
 
   # Verify the artifact path requirements made by included products.
 
@@ -1467,6 +1492,8 @@
 ndk: $(SOONG_OUT_DIR)/ndk.timestamp
 .PHONY: ndk
 
+$(call dist-write-file,$(KATI_PACKAGE_MK_DIR)/dist.mk)
+
 $(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] writing build rules ...)
 
 endif # KATI
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
index ca2dcee..684ab9f 100644
--- a/core/ninja_config.mk
+++ b/core/ninja_config.mk
@@ -7,7 +7,7 @@
 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-%
+NINJA_EXCLUDE_GOALS := all APP-% PRODUCT-%
 
 # A list of goals which affect parsing of makefiles and we need to pass to Kati.
 PARSE_TIME_MAKE_GOALS := \
@@ -28,7 +28,6 @@
 	custom_images \
 	deps-license \
 	dicttool_aosp \
-	dist \
 	dump-products \
 	eng \
 	fusion \
diff --git a/core/soong_config.mk b/core/soong_config.mk
index e61aad0..2d7c0d9 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -141,8 +141,6 @@
 $(call add_json_bool, UseGoma,                           $(filter-out false,$(USE_GOMA)))
 $(call add_json_bool, Arc,                               $(filter true,$(TARGET_ARC)))
 
-$(call add_json_str,  DistDir,                           $(if $(dist_goal), $(DIST_DIR)))
-
 $(call add_json_list, NamespacesToExport,                $(PRODUCT_SOONG_NAMESPACES))
 
 $(call add_json_list, PgoAdditionalProfileDirs,          $(PGO_ADDITIONAL_PROFILE_DIRS))
diff --git a/packaging/distdir.mk b/packaging/distdir.mk
new file mode 100644
index 0000000..264a8b0
--- /dev/null
+++ b/packaging/distdir.mk
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2018 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.
+#
+
+# From the Android.mk pass:
+DIST_GOAL_OUTPUT_PAIRS :=
+DIST_SRC_DST_PAIRS :=
+include $(KATI_PACKAGE_MK_DIR)/dist.mk
+
+$(foreach pair,$(DIST_GOAL_OUTPUT_PAIRS), \
+  $(eval goal := $(call word-colon,1,$(pair))) \
+  $(eval output := $(call word-colon,2,$(pair))) \
+  $(eval .PHONY: _dist_$$(goal)) \
+  $(if $(call streq,$(DIST),true),\
+    $(eval _dist_$$(goal): $$(DIST_DIR)/$$(output)), \
+    $(eval _dist_$$(goal):)))
+
+define copy-one-dist-file
+$(2): $(1)
+	@echo "Dist: $$@"
+	rm -f $$@
+	cp $$< $$@
+endef
+
+ifeq ($(DIST),true)
+  $(foreach pair,$(DIST_SRC_DST_PAIRS), \
+    $(eval src := $(call word-colon,1,$(pair))) \
+    $(eval dst := $(DIST_DIR)/$(call word-colon,2,$(pair))) \
+    $(eval $(call copy-one-dist-file,$(src),$(dst))))
+endif
+
+copy-one-dist-file :=
+DIST_GOAL_OUTPUT_PAIRS :=
+DIST_SRC_DST_PAIRS :=
diff --git a/packaging/main.mk b/packaging/main.mk
new file mode 100644
index 0000000..0b746a8
--- /dev/null
+++ b/packaging/main.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2018 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.
+#
+
+# Create a default rule. This is unused currently, as the real default rule is
+# still in the Kati build step.
+.PHONY: _packaging_default_rule_
+_packaging_default_rule_:
+
+ifndef KATI
+$(error Only Kati is supported.)
+endif
+
+$(info [1/3] initializing packaging system ...)
+
+.KATI_READONLY := KATI_PACKAGE_MK_DIR
+
+include build/make/common/core.mk
+include build/make/common/strings.mk
+
+$(info [2/3] including distdir.mk ...)
+
+include build/make/packaging/distdir.mk
+
+$(info [3/3] writing packaging rules ...)