cfgtree.mk: file-based configuration

cfgtree.mk is part of an effort to make product
configuration less error-prone in part by removing
superfluous Makefile editing. For instance, a common
error is dropping the trailing backslash on PRODUCT_PACKAGES.

Secondarily, simplifying product configuration storage
enables cleaner automation.  Brunch can use the same files
to manage a product without an extra database or separate
configuration tool (as it has today with config and
reconfig).

Tertiarily, a simple file loading model enables consistent
enforcement (over $(shell cat ..)) and allows sub-makefiles
to pull values from the product path.  E.g., configuring
a crash server or product id.

This change adds cfgtree.mk which contains the function
cfgtree-get.  cfgtree-get will retrieve a file relative to
a common configuration tree root, ignoring all file
lines that begin with '#'.  If a request is optional,
cfgtree-get-if-exists should be used.  Optional retrievals
fail silently while required entries will cause the build
to error out on the Makefile line requesting the value.

For example, a new product makefile may look like:
  # Automatically generated by brunch.
  CFGTREE_ROOT := $(LOCAL_PATH)
  include device/generic/brillo/brillo_base.mk

  PRODUCT_NAME := $(call get_product_name_from_file)
  PRODUCT_BRAND := $(call cfgtree-get,brand)
  PRODUCT_DEVICE := $(call cfgtree-get,device)
  PRODUCT_MANUFACTURER := $(call cfgtree-get,manufacturer)
  PRODUCT_PACKAGES += $(call cfgtree-get-if-exists,packages)
  PRODUCT_COPY_FILES += $(call cfgtree-get-if-exists,copy_files)

  # Reserved for future use.
  CREATED_BY_BDK_VERSION := $(call cfgtree-get-if-exists,bdk/created_by_version)
  $(call bdk_update_hook)

  # Add any extra Android product.mk directive in extras.mk
  -include $(LOCAL_PATH)/extras.mk

This allows direct inspection of the setting of important variables
without requiring users to set them in the more finicky Makefile environment.

Even though the approach keeps the magic to a minimum, Android's
magic can still be used to introspect for product variable values
with:
  m -j24 dump-products

cfgtree.mk can be used directly in Android.mk files as well. For
instance, the BRILLO_PRODUCT_ID can be populated using this
mechanism by updating system/extras/brillo_config/Android.mk:

  BRILLO_PRODUCT_ID := $(call cfgtree-get,brillo/product_id)

Of course, a two stage load-then-assign can be used if the ability
to override is desired.  (cfgtree_get should be used with immediate
assignment ':='.)

The same can be done in system/core/crash_reporter/Android.mk:

  BRILLO_CRASH_SERVER := $(call cfgtree-get,brillo/crash_server)

(While the crash_reporter rule could just copy the file directly, it would
 mean that the value could no longer be defined as a variable or that the
 'crash_server' rule would need to check for the files existence first.
 In either case, if the source data has changed, make should update on an
 incremental re-run.)

BUG=25343470
DDOC=https://docs.google.com/document/d/1xZ1Fexl6j9JWK8OED8ZcAnvc-42w0jYiqDBaVfWqHH4/edit#
TEST=manual. brunch needs to be updated still.

Change-Id: Ice1235da88cf11ffa1da42460cda8cb6dd393c07
2 files changed