| # | |
| # Copyright (C) 2007 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. | |
| # | |
| # | |
| # Clears a list of variables using ":=". | |
| # | |
| # E.g., | |
| # $(call clear-var-list,A B C) | |
| # would be the same as: | |
| # A := | |
| # B := | |
| # C := | |
| # | |
| # $(1): list of variable names to clear | |
| # | |
| define clear-var-list | |
| $(foreach v,$(1),$(eval $(v):=)) | |
| endef | |
| # | |
| # Copies a list of variables into another list of variables. | |
| # The target list is the same as the source list, but has | |
| # a dotted prefix affixed to it. | |
| # | |
| # E.g., | |
| # $(call copy-var-list, PREFIX, A B) | |
| # would be the same as: | |
| # PREFIX.A := $(A) | |
| # PREFIX.B := $(B) | |
| # | |
| # $(1): destination prefix | |
| # $(2): list of variable names to copy | |
| # | |
| define copy-var-list | |
| $(foreach v,$(2),$(eval $(strip $(1)).$(v):=$($(v)))) | |
| endef | |
| # | |
| # Moves a list of variables into another list of variables. | |
| # The variable names differ by a prefix. After moving, the | |
| # source variable is cleared. | |
| # | |
| # NOTE: Spaces are not allowed around the prefixes. | |
| # | |
| # E.g., | |
| # $(call move-var-list,SRC,DST,A B) | |
| # would be the same as: | |
| # DST.A := $(SRC.A) | |
| # SRC.A := | |
| # DST.B := $(SRC.B) | |
| # SRC.B := | |
| # | |
| # $(1): source prefix | |
| # $(2): destination prefix | |
| # $(3): list of variable names to move | |
| # | |
| define move-var-list | |
| $(foreach v,$(3), \ | |
| $(eval $(2).$(v) := $($(1).$(v))) \ | |
| $(eval $(1).$(v) :=) \ | |
| ) | |
| endef | |
| # | |
| # $(1): haystack | |
| # $(2): needle | |
| # | |
| # Guarantees that needle appears at most once in haystack, | |
| # without changing the order of other elements in haystack. | |
| # If needle appears multiple times, only the first occurrance | |
| # will survive. | |
| # | |
| define uniq-word | |
| $(strip \ | |
| $(if $(filter-out 0 1,$(words $(filter $(2),$(1)))), \ | |
| $(eval _uniq_word_seen :=) \ | |
| $(foreach w,$(1), \ | |
| $(if $(filter $(2),$(w)), \ | |
| $(if $(_uniq_word_seen),, \ | |
| $(w) \ | |
| $(eval _uniq_word_seen := true)), \ | |
| $(w))), \ | |
| $(1))) | |
| endef | |
| INHERIT_TAG := @inherit: | |
| # | |
| # Walks through the list of variables, each qualified by the prefix, | |
| # and finds instances of words beginning with INHERIT_TAG. Scrape | |
| # off INHERIT_TAG from each matching word, and return the sorted, | |
| # unique set of those words. | |
| # | |
| # E.g., given | |
| # PREFIX.A := A $(INHERIT_TAG)aaa B C | |
| # PREFIX.B := B $(INHERIT_TAG)aaa C $(INHERIT_TAG)bbb D E | |
| # Then | |
| # $(call get-inherited-nodes,PREFIX,A B) | |
| # returns | |
| # aaa bbb | |
| # | |
| # $(1): variable prefix | |
| # $(2): list of variables to check | |
| # | |
| define get-inherited-nodes | |
| $(sort \ | |
| $(subst $(INHERIT_TAG),, \ | |
| $(filter $(INHERIT_TAG)%, \ | |
| $(foreach v,$(2),$($(1).$(v))) \ | |
| ))) | |
| endef | |
| # | |
| # for each variable ( (prefix + name) * vars ): | |
| # get list of inherited words; if not empty: | |
| # for each inherit: | |
| # replace the first occurrence with (prefix + inherited + var) | |
| # clear the source var so we can't inherit the value twice | |
| # | |
| # $(1): context prefix | |
| # $(2): name of this node | |
| # $(3): list of node variable names | |
| # $(4): list of single value variable names (subset of $(3)) | |
| # | |
| define _expand-inherited-values | |
| $(foreach v,$(3), \ | |
| $(eval ### "Shorthand for the name of the target variable") \ | |
| $(eval _eiv_tv := $(1).$(2).$(v)) \ | |
| $(eval ### "Get the list of nodes that this variable inherits") \ | |
| $(eval _eiv_i := \ | |
| $(sort \ | |
| $(patsubst $(INHERIT_TAG)%,%, \ | |
| $(filter $(INHERIT_TAG)%, $($(_eiv_tv)) \ | |
| )))) \ | |
| $(eval ### "Whether this variable should only take a single value") \ | |
| $(eval _eiv_sv := $(filter $(v),$(4))) \ | |
| $(foreach i,$(_eiv_i), \ | |
| $(eval ### "Make sure that this inherit appears only once") \ | |
| $(eval $(_eiv_tv) := \ | |
| $(call uniq-word,$($(_eiv_tv)),$(INHERIT_TAG)$(i))) \ | |
| $(eval ### "The expanded value, empty if we want a single value and have one") \ | |
| $(eval _eiv_ev := \ | |
| $(if $(and $(_eiv_sv),$(filter-out $(INHERIT_TAG)%,$($(_eiv_tv)))),,\ | |
| $($(1).$(i).$(v)) \ | |
| ) \ | |
| ) \ | |
| $(eval ### "Expand the inherit tag") \ | |
| $(eval $(_eiv_tv) := \ | |
| $(strip $(patsubst $(INHERIT_TAG)$(i),$(_eiv_ev),$($(_eiv_tv))))) \ | |
| $(eval ### "Clear the child so DAGs don't create duplicate entries" ) \ | |
| $(eval $(1).$(i).$(v) :=) \ | |
| $(eval ### "If we just inherited ourselves, it's a cycle.") \ | |
| $(if $(filter $(INHERIT_TAG)$(2),$($(_eiv_tv))), \ | |
| $(warning Cycle detected between "$(2)" and "$(i)" for context "$(1)") \ | |
| $(error import of "$(2)" failed) \ | |
| ) \ | |
| ) \ | |
| ) \ | |
| $(eval _eiv_tv :=) \ | |
| $(eval _eiv_i :=) | |
| endef | |
| # | |
| # $(1): context prefix | |
| # $(2): makefile representing this node | |
| # $(3): list of node variable names | |
| # $(4): list of single value variable names (subset of $(3)) | |
| # | |
| # _include_stack contains the list of included files, with the most recent files first. | |
| define _import-node | |
| $(eval _include_stack := $(2) $$(_include_stack)) | |
| $(call clear-var-list, $(3)) | |
| $(eval LOCAL_PATH := $(patsubst %/,%,$(dir $(2)))) | |
| $(eval MAKEFILE_LIST :=) | |
| $(call dump-import-start,$(_include_stack)) | |
| $(call dump-config-vals,$(2),before) | |
| $(eval include $(2)) | |
| $(call dump-import-done,$(_include_stack)) | |
| $(call dump-config-vals,$(2),after) | |
| $(eval _included := $(filter-out $(2),$(MAKEFILE_LIST))) | |
| $(eval MAKEFILE_LIST :=) | |
| $(eval LOCAL_PATH :=) | |
| $(call copy-var-list, $(1).$(2), $(3)) | |
| $(call clear-var-list, $(3)) | |
| $(eval $(1).$(2).inherited := \ | |
| $(call get-inherited-nodes,$(1).$(2),$(3))) | |
| $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3),$(4)) | |
| $(call _expand-inherited-values,$(1),$(2),$(3),$(4)) | |
| $(eval $(1).$(2).inherited :=) | |
| $(eval _include_stack := $(wordlist 2,9999,$(_include_stack))) | |
| endef | |
| # | |
| # This will generate a warning for _included above | |
| # $(if $(_included), \ | |
| # $(eval $(warning product spec file: $(2)))\ | |
| # $(foreach _inc,$(_included),$(eval $(warning $(space)$(space)$(space)includes: $(_inc)))),) | |
| # | |
| # | |
| # $(1): context prefix | |
| # $(2): list of makefiles representing nodes to import | |
| # $(3): list of node variable names | |
| # $(4): list of single value variable names (subset of $(3)) | |
| # | |
| #TODO: Make the "does not exist" message more helpful; | |
| # should print out the name of the file trying to include it. | |
| define _import-nodes-inner | |
| $(foreach _in,$(2), \ | |
| $(if $(wildcard $(_in)), \ | |
| $(if $($(1).$(_in).seen), \ | |
| $(eval ### "skipping already-imported $(_in)") \ | |
| , \ | |
| $(eval $(1).$(_in).seen := true) \ | |
| $(call _import-node,$(1),$(strip $(_in)),$(3),$(4)) \ | |
| ) \ | |
| , \ | |
| $(error $(1): "$(_in)" does not exist) \ | |
| ) \ | |
| ) | |
| endef | |
| # | |
| # $(1): output list variable name, like "PRODUCTS" or "DEVICES" | |
| # $(2): list of makefiles representing nodes to import | |
| # $(3): list of node variable names | |
| # $(4): list with subset of variable names that take only a single value, instead | |
| # of the default list semantics | |
| # | |
| define import-nodes | |
| $(call dump-phase-start,$(1),$(2),$(3),$(4),build/make/core/node_fns.mk) \ | |
| $(if \ | |
| $(foreach _in,$(2), \ | |
| $(eval _node_import_context := _nic.$(1).[[$(_in)]]) \ | |
| $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \ | |
| should be empty here: $(_include_stack))),) \ | |
| $(eval _include_stack := ) \ | |
| $(call _import-nodes-inner,$(_node_import_context),$(_in),$(3),$(4)) \ | |
| $(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) \ | |
| $(eval _node_import_context :=) \ | |
| $(eval $(1) := $($(1)) $(_in)) \ | |
| $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \ | |
| should be empty here: $(_include_stack))),) \ | |
| ) \ | |
| ,) \ | |
| $(call dump-phase-end,build/make/core/node_fns.mk) | |
| endef |