OSDN Git Service

33b special
[android-x86/build.git] / core / node_fns.mk
1 #
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 #
29 define clear-var-list
30 $(foreach v,$(1),$(eval $(v):=))
31 endef
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 #
47 define copy-var-list
48 $(foreach v,$(2),$(eval $(strip $(1)).$(v):=$($(v))))
49 endef
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 #
70 define move-var-list
71 $(foreach v,$(3), \
72   $(eval $(2).$(v) := $($(1).$(v))) \
73   $(eval $(1).$(v) :=) \
74  )
75 endef
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 #
97 empty :=
98 space := $(empty) $(empty)
99 define 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  ))
109 endef
110
111 INHERIT_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 #
130 define get-inherited-nodes
131 $(sort \
132   $(subst $(INHERIT_TAG),, \
133     $(filter $(INHERIT_TAG)%, \
134       $(foreach v,$(2),$($(1).$(v))) \
135  )))
136 endef
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 #
149 define _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           $(strip \
166               $(patsubst $(INHERIT_TAG)$(i),$($(1).$(i).$(v)), \
167                   $($(_eiv_tv))))) \
168       $(eval ### "Clear the child so DAGs don't create duplicate entries" ) \
169       $(eval $(1).$(i).$(v) :=) \
170       $(eval ### "If we just inherited ourselves, it's a cycle.") \
171       $(if $(filter $(INHERIT_TAG)$(2),$($(_eiv_tv))), \
172         $(warning Cycle detected between "$(2)" and "$(i)" for context "$(1)") \
173         $(error import of "$(2)" failed) \
174       ) \
175      ) \
176    ) \
177    $(eval _eiv_tv :=) \
178    $(eval _eiv_i :=)
179 endef
180
181 #
182 # $(1): context prefix
183 # $(2): makefile representing this node
184 # $(3): list of node variable names
185 #
186 # _include_stack contains the list of included files, with the most recent files first.
187 define _import-node
188   $(eval _include_stack := $(2) $$(_include_stack))
189   $(call clear-var-list, $(3))
190   $(eval LOCAL_PATH := $(patsubst %/,%,$(dir $(2))))
191   $(eval MAKEFILE_LIST :=)
192   $(eval include $(2))
193   $(eval _included := $(filter-out $(2),$(MAKEFILE_LIST)))
194   $(eval MAKEFILE_LIST :=)
195   $(eval LOCAL_PATH :=)
196   $(call copy-var-list, $(1).$(2), $(3))
197   $(call clear-var-list, $(3))
198
199   $(eval $(1).$(2).inherited := \
200       $(call get-inherited-nodes,$(1).$(2),$(3)))
201   $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3))
202
203   $(call _expand-inherited-values,$(1),$(2),$(3))
204
205   $(eval $(1).$(2).inherited :=)
206   $(eval _include_stack := $(wordlist 2,9999,$$(_include_stack)))
207 endef
208
209 #
210 # This will generate a warning for _included above
211 #  $(if $(_included), \
212 #      $(eval $(warning product spec file: $(2)))\
213 #      $(foreach _inc,$(_included),$(eval $(warning $(space)$(space)$(space)includes: $(_inc)))),)
214 #
215
216 #
217 # $(1): context prefix
218 # $(2): list of makefiles representing nodes to import
219 # $(3): list of node variable names
220 #
221 #TODO: Make the "does not exist" message more helpful;
222 #      should print out the name of the file trying to include it.
223 define _import-nodes-inner
224   $(foreach _in,$(2), \
225     $(if $(wildcard $(_in)), \
226       $(if $($(1).$(_in).seen), \
227         $(eval ### "skipping already-imported $(_in)") \
228        , \
229         $(eval $(1).$(_in).seen := true) \
230         $(call _import-node,$(1),$(strip $(_in)),$(3)) \
231        ) \
232      , \
233       $(error $(1): "$(_in)" does not exist) \
234      ) \
235    )
236 endef
237
238 #
239 # $(1): output list variable name, like "PRODUCTS" or "DEVICES"
240 # $(2): list of makefiles representing nodes to import
241 # $(3): list of node variable names
242 #
243 define import-nodes
244 $(if \
245   $(foreach _in,$(2), \
246     $(eval _node_import_context := _nic.$(1).[[$(_in)]]) \
247     $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
248                 should be empty here: $(_include_stack))),) \
249     $(eval _include_stack := ) \
250     $(call _import-nodes-inner,$(_node_import_context),$(_in),$(3)) \
251     $(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) \
252     $(eval _node_import_context :=) \
253     $(eval $(1) := $($(1)) $(_in)) \
254     $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
255                 should be empty here: $(_include_stack))),) \
256    ) \
257 ,)
258 endef