From 837425b0c0f7b4d85cdeadf6db80ac129b064494 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Fri, 1 Jun 2018 14:18:14 +0100 Subject: [PATCH] Add a new macro for products to make artifact path requirements. When a product adds a path requirement, the build system will verify that all its artifacts are produced inside these paths, and fail otherwise. The paths are all relative to PRODUCT_OUT, and the macro also supports giving a whitelist, for known existing offenders in the hierarchy. The build will fail if redundant whitelist entries are present. Example invocation: _paths := $(TARGET_COPY_OUT_SYSTEM)/ _whitelist := root/init root/init.rc $(call require-artifacts-in-path $(_paths), $(_whitelist)) Bug: 80410283 Test: Downstream with a new product definition. Change-Id: I235de681f65254087a42e345af69b2113b682072 --- core/main.mk | 36 ++++++++++++++++++++++++++++++++++++ core/product.mk | 10 ++++++++++ core/product_config.mk | 6 ++++++ 3 files changed, 52 insertions(+) diff --git a/core/main.mk b/core/main.mk index eccae2d432..01dc0c1770 100644 --- a/core/main.mk +++ b/core/main.mk @@ -931,6 +931,42 @@ else product_FILES := endif +# Transforms paths relative to PRODUCT_OUT to absolute paths. +# $(1): list of relative paths +# $(2): optional suffix to append to paths +define resolve-product-relative-paths + $(subst $(_vendor_path_placeholder),$(TARGET_COPY_OUT_VENDOR),\ + $(subst $(_product_path_placeholder),$(TARGET_COPY_OUT_PRODUCT),\ + $(foreach p,$(1),$(PRODUCT_OUT)/$(p)$(2)))) +endef + +# Fails the build if the given list is non-empty, and prints it entries (stripping PRODUCT_OUT). +# $(1): list of files to print +# $(2): heading to print on failure +define maybe-print-list-and-error +$(if $(strip $(1)), \ + $(warning $(2)) \ + $(info Offending entries:) \ + $(foreach e,$(sort $(1)),$(info $(patsubst $(PRODUCT_OUT)/%,%,$(e)))) \ + $(error Build failed) \ +) +endef + +# Verify the artifact path requirements made by included products. +$(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\ + $(eval requirements := $(PRODUCTS.$(makefile).ARTIFACT_PATH_REQUIREMENTS)) \ + $(eval ### Verify that the product only produces files inside its path requirements.) \ + $(eval whitelist := $(PRODUCTS.$(makefile).ARTIFACT_PATH_WHITELIST)) \ + $(eval path_patterns := $(call resolve-product-relative-paths,$(requirements),%)) \ + $(eval whitelist_patterns := $(call resolve-product-relative-paths,$(whitelist))) \ + $(eval files := $(call product-installed-files, $(makefile))) \ + $(eval files := $(filter-out $(TARGET_OUT_FAKE)/% $(HOST_OUT)/%,$(files))) \ + $(eval offending_files := $(filter-out $(path_patterns) $(whitelist_patterns),$(files))) \ + $(call maybe-print-list-and-error,$(offending_files),$(makefile) produces files outside its artifact path requirement.) \ + $(eval unused_whitelist := $(filter-out $(files),$(whitelist_patterns))) \ + $(call maybe-print-list-and-error,$(unused_whitelist),$(makefile) includes redundant whitelist entries in its artifact path requirement.) \ +) + ifeq (0,1) $(info product_FILES for $(TARGET_DEVICE) ($(INTERNAL_PRODUCT)):) $(foreach p,$(product_FILES),$(info : $(p))) diff --git a/core/product.mk b/core/product.mk index f9174ccebc..3cf521ab17 100644 --- a/core/product.mk +++ b/core/product.mk @@ -234,6 +234,16 @@ define inherit-product $(eval PARENT_PRODUCT_FILES := $(sort $(PARENT_PRODUCT_FILES) $(current_mk))) endef +# Specifies a number of path prefixes, relative to PRODUCT_OUT, where the +# product makefile hierarchy rooted in the current node places its artifacts. +# Creating artifacts outside the specified paths will cause a build-time error. +define require-artifacts-in-path + $(eval current_mk := $(strip $(word 1,$(_include_stack)))) \ + $(eval PRODUCTS.$(current_mk).ARTIFACT_PATH_REQUIREMENTS := $(strip $(1))) \ + $(eval PRODUCTS.$(current_mk).ARTIFACT_PATH_WHITELIST := $(strip $(2))) \ + $(eval ARTIFACT_PATH_REQUIREMENT_PRODUCTS := \ + $(sort $(ARTIFACT_PATH_REQUIREMENT_PRODUCTS) $(current_mk))) +endef # # Do inherit-product only if $(1) exists diff --git a/core/product_config.mk b/core/product_config.mk index 3a77d0b2b8..8425b09258 100644 --- a/core/product_config.mk +++ b/core/product_config.mk @@ -234,6 +234,12 @@ endif $(call import-products, $(current_product_makefile)) endif # Import all or just the current product makefile +# Import all the products that have made artifact path requirements, so that we can verify +# the artifacts they produce. +$(foreach makefile,$(ARTIFACT_PATH_REQUIREMENT_PRODUCTS),\ + $(if $(filter-out $(makefile),$(PRODUCTS)),$(eval $(call import-products,$(makefile))))\ +) + # Sanity check $(check-all-products)