Home | History | Annotate | Download | only in core
      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
    259