Override release configs in depth

When overriding a release config, make sure that the overriden config is
fully present (by processing any of its overrides) before overriding it.

Bug: None
Test: manual
Change-Id: I8d29c7ee7208acf7fe63876f617c5b9e2c26c434
diff --git a/core/release_config.mk b/core/release_config.mk
index 1fb5747..edcf2ab 100644
--- a/core/release_config.mk
+++ b/core/release_config.mk
@@ -61,12 +61,32 @@
 
 # Declare or extend a release-config.
 #
+# The order of processing is:
+# 1. Recursively apply any overridden release configs.  Only apply each config
+#    the first time we reach it.
+# 2. Apply any files for this release config, in the order they were added to
+#    the declaration.
+#
+# Example:
+#   With these declarations:
+#     $(declare-release-config foo, foo.scl)
+#     $(declare-release-config bar, bar.scl, foo)
+#     $(declare-release-config baz, baz.scl, bar)
+#     $(declare-release-config bif, bif.scl, foo baz)
+#     $(declare-release-config bop, bop.scl, bar baz)
+#
+#   TARGET_RELEASE:
+#     - bar will use: foo.scl bar.scl
+#     - baz will use: foo.scl bar.scl baz.scl
+#     - bif will use: foo.scl bar.scl baz.scl bif.scl
+#     - bop will use: foo.scl bar.scl baz.scl bop.scl
+#
 # $1 config name
 # $2 release config files
-# $3 overridden release config.  Only applied for $(TARGET_RELEASE), not in depth.
+# $3 overridden release config
 define declare-release-config
-    $(if $(strip $(2)),,  \
-        $(error declare-release-config: config $(strip $(1)) must have release config files) \
+    $(if $(strip $(2)$(3)),,  \
+        $(error declare-release-config: config $(strip $(1)) must have release config files, override another release config, or both) \
     )
     $(eval _all_release_configs := $(sort $(_all_release_configs) $(strip $(1))))
     $(if $(strip $(3)), \
@@ -113,16 +133,30 @@
 # Don't sort this, use it in the order they gave us.
 # Do allow duplicate entries, retaining only the first usage.
 flag_value_files :=
-$(foreach r,$(_all_release_configs.$(TARGET_RELEASE).OVERRIDES) $(TARGET_RELEASE), \
+
+# Apply overrides recursively
+#
+# $1 release config that we override
+applied_releases :=
+define _apply-release-config-overrides
+$(foreach r,$(1), \
+  $(if $(filter $(r),$(applied_releases)),, \
+    $(foreach o,$(_all_release_configs.$(r).OVERRIDES),$(call _apply-release-config-overrides,$(o)))\
+    $(eval applied_releases += $(r))\
     $(foreach f,$(_all_release_configs.$(r).FILES), \
       $(if $(filter $(f),$(flag_value_files)),,$(eval flag_value_files += $(f)))\
     )\
+  )\
 )
-
+endef
+$(call _apply-release-config-overrides,$(TARGET_RELEASE))
 # Unset variables so they can't use them
 define declare-release-config
 $(error declare-release-config can only be called from inside release_config_map.mk files)
 endef
+define apply-release-config-overrides
+$(error invalid use of apply-release-config-overrides)
+endef
 
 # TODO: Remove this check after enough people have sourced lunch that we don't
 # need to worry about it trying to do get_build_vars TARGET_RELEASE. Maybe after ~9/2023
@@ -142,6 +176,7 @@
 )
 _all_release_configs:=
 config_map_files:=
+applied_releases:=
 
 
 # -----------------------------------------------------------------