blob: 8b026f5775c34b75d8efc71afa817793bfee8c09 [file] [log] [blame]
The Android Open Source Project88b60792009-03-03 19:28:42 -08001#
2# Copyright (C) 2007 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17#
18# Clears a list of variables using ":=".
19#
20# E.g.,
21# $(call clear-var-list,A B C)
22# would be the same as:
23# A :=
24# B :=
25# C :=
26#
27# $(1): list of variable names to clear
28#
29define clear-var-list
30$(foreach v,$(1),$(eval $(v):=))
31endef
32
33#
34# Copies a list of variables into another list of variables.
35# The target list is the same as the source list, but has
36# a dotted prefix affixed to it.
37#
38# E.g.,
39# $(call copy-var-list, PREFIX, A B)
40# would be the same as:
41# PREFIX.A := $(A)
42# PREFIX.B := $(B)
43#
44# $(1): destination prefix
45# $(2): list of variable names to copy
46#
47define copy-var-list
48$(foreach v,$(2),$(eval $(strip $(1)).$(v):=$($(v))))
49endef
50
51#
52# Moves a list of variables into another list of variables.
53# The variable names differ by a prefix. After moving, the
54# source variable is cleared.
55#
56# NOTE: Spaces are not allowed around the prefixes.
57#
58# E.g.,
59# $(call move-var-list,SRC,DST,A B)
60# would be the same as:
61# DST.A := $(SRC.A)
62# SRC.A :=
63# DST.B := $(SRC.B)
64# SRC.B :=
65#
66# $(1): source prefix
67# $(2): destination prefix
68# $(3): list of variable names to move
69#
70define move-var-list
71$(foreach v,$(3), \
72 $(eval $(2).$(v) := $($(1).$(v))) \
73 $(eval $(1).$(v) :=) \
74 )
75endef
76
77#
78# $(1): haystack
79# $(2): needle
80#
81# Guarantees that needle appears at most once in haystack,
82# without changing the order of other elements in haystack.
83# If needle appears multiple times, only the first occurrance
84# will survive.
85#
86# How it works:
87#
88# - Stick everything in haystack into a single word,
89# with "|||" separating the words.
90# - Replace occurrances of "|||$(needle)|||" with "||| |||",
91# breaking haystack back into multiple words, with spaces
92# where needle appeared.
93# - Add needle between the first and second words of haystack.
94# - Replace "|||" with spaces, breaking haystack back into
95# individual words.
96#
97empty :=
98space := $(empty) $(empty)
99define uniq-word
100$(strip \
101 $(if $(filter $(2),$(1)), \
102 $(eval h := |||$(subst $(space),|||,$(strip $(1)))|||) \
103 $(eval h := $(subst |||$(strip $(2))|||,|||$(space)|||,$(h))) \
104 $(eval h := $(word 1,$(h)) $(2) $(wordlist 2,9999,$(h))) \
105 $(subst |||,$(space),$(h)) \
106 , \
107 $(1) \
108 ))
109endef
110
111INHERIT_TAG := @inherit:
112
113#
114# Walks through the list of variables, each qualified by the prefix,
115# and finds instances of words beginning with INHERIT_TAG. Scrape
116# off INHERIT_TAG from each matching word, and return the sorted,
117# unique set of those words.
118#
119# E.g., given
120# PREFIX.A := A $(INHERIT_TAG)aaa B C
121# PREFIX.B := B $(INHERIT_TAG)aaa C $(INHERIT_TAG)bbb D E
122# Then
123# $(call get-inherited-nodes,PREFIX,A B)
124# returns
125# aaa bbb
126#
127# $(1): variable prefix
128# $(2): list of variables to check
129#
130define get-inherited-nodes
131$(sort \
132 $(subst $(INHERIT_TAG),, \
133 $(filter $(INHERIT_TAG)%, \
134 $(foreach v,$(2),$($(1).$(v))) \
135 )))
136endef
137
138#
139# for each variable ( (prefix + name) * vars ):
140# get list of inherited words; if not empty:
141# for each inherit:
142# replace the first occurrence with (prefix + inherited + var)
143# clear the source var so we can't inherit the value twice
144#
145# $(1): context prefix
146# $(2): name of this node
147# $(3): list of variable names
148#
149define _expand-inherited-values
150 $(foreach v,$(3), \
151 $(eval ### "Shorthand for the name of the target variable") \
152 $(eval _eiv_tv := $(1).$(2).$(v)) \
153 $(eval ### "Get the list of nodes that this variable inherits") \
154 $(eval _eiv_i := \
155 $(sort \
156 $(patsubst $(INHERIT_TAG)%,%, \
157 $(filter $(INHERIT_TAG)%, $($(_eiv_tv)) \
158 )))) \
159 $(foreach i,$(_eiv_i), \
160 $(eval ### "Make sure that this inherit appears only once") \
161 $(eval $(_eiv_tv) := \
162 $(call uniq-word,$($(_eiv_tv)),$(INHERIT_TAG)$(i))) \
163 $(eval ### "Expand the inherit tag") \
164 $(eval $(_eiv_tv) := \
165 $(patsubst $(INHERIT_TAG)$(i),$($(1).$(i).$(v)), \
166 $($(_eiv_tv)))) \
167 $(eval ### "Clear the child so DAGs don't create duplicate entries" ) \
168 $(eval $(1).$(i).$(v) :=) \
169 $(eval ### "If we just inherited ourselves, it's a cycle.") \
170 $(if $(filter $(INHERIT_TAG)$(2),$($(_eiv_tv))), \
171 $(warning Cycle detected between "$(2)" and "$(i)" for context "$(1)") \
172 $(error import of "$(2)" failed) \
173 ) \
174 ) \
175 ) \
176 $(eval _eiv_tv :=) \
177 $(eval _eiv_i :=)
178endef
179
180#
181# $(1): context prefix
182# $(2): makefile representing this node
183# $(3): list of node variable names
184#
The Android Open Source Project6a5f7f02009-03-05 14:34:30 -0800185# _include_stack contains the list of included files, with the most recent files first.
The Android Open Source Project88b60792009-03-03 19:28:42 -0800186define _import-node
The Android Open Source Project6a5f7f02009-03-05 14:34:30 -0800187 $(eval _include_stack := $(2) $$(_include_stack))
The Android Open Source Project88b60792009-03-03 19:28:42 -0800188 $(call clear-var-list, $(3))
189 $(eval include $(2))
190 $(call copy-var-list, $(1).$(2), $(3))
191 $(call clear-var-list, $(3))
192
193 $(eval $(1).$(2).inherited := \
194 $(call get-inherited-nodes,$(1).$(2),$(3)))
195 $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3))
196
197 $(call _expand-inherited-values,$(1),$(2),$(3))
198
199 $(eval $(1).$(2).inherited :=)
The Android Open Source Project6a5f7f02009-03-05 14:34:30 -0800200 $(eval _include_stack := $(wordlist 2,9999,$$(_include_stack)))
The Android Open Source Project88b60792009-03-03 19:28:42 -0800201endef
202
203#
204# $(1): context prefix
205# $(2): list of makefiles representing nodes to import
206# $(3): list of node variable names
207#
208#TODO: Make the "does not exist" message more helpful;
209# should print out the name of the file trying to include it.
210define _import-nodes-inner
211 $(foreach _in,$(2), \
212 $(if $(wildcard $(_in)), \
213 $(if $($(1).$(_in).seen), \
214 $(eval ### "skipping already-imported $(_in)") \
215 , \
216 $(eval $(1).$(_in).seen := true) \
217 $(call _import-node,$(1),$(strip $(_in)),$(3)) \
218 ) \
219 , \
220 $(error $(1): "$(_in)" does not exist) \
221 ) \
222 )
223endef
224
225#
226# $(1): output list variable name, like "PRODUCTS" or "DEVICES"
227# $(2): list of makefiles representing nodes to import
228# $(3): list of node variable names
229#
230define import-nodes
231$(if \
232 $(foreach _in,$(2), \
233 $(eval _node_import_context := _nic.$(1).[[$(_in)]]) \
The Android Open Source Project6a5f7f02009-03-05 14:34:30 -0800234 $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
235 should be empty here: $(_include_stack))),) \
236 $(eval _include_stack := ) \
The Android Open Source Project88b60792009-03-03 19:28:42 -0800237 $(call _import-nodes-inner,$(_node_import_context),$(_in),$(3)) \
238 $(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) \
239 $(eval _node_import_context :=) \
240 $(eval $(1) := $($(1)) $(_in)) \
The Android Open Source Project6a5f7f02009-03-05 14:34:30 -0800241 $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
242 should be empty here: $(_include_stack))),) \
The Android Open Source Project88b60792009-03-03 19:28:42 -0800243 ) \
244,)
245endef