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 define uniq-word
     98 $(strip \
     99   $(if $(filter-out 0 1,$(words $(filter $(2),$(1)))), \
    100     $(eval h := |||$(subst $(space),|||,$(strip $(1)))|||) \
    101     $(eval h := $(subst |||$(strip $(2))|||,|||$(space)|||,$(h))) \
    102     $(eval h := $(word 1,$(h)) $(2) $(wordlist 2,9999,$(h))) \
    103     $(subst |||,$(space),$(h)) \
    104    , \
    105     $(1) \
    106  ))
    107 endef
    108 
    109 INHERIT_TAG := @inherit:
    110 
    111 #
    112 # Walks through the list of variables, each qualified by the prefix,
    113 # and finds instances of words beginning with INHERIT_TAG.  Scrape
    114 # off INHERIT_TAG from each matching word, and return the sorted,
    115 # unique set of those words.
    116 #
    117 # E.g., given
    118 #   PREFIX.A := A $(INHERIT_TAG)aaa B C
    119 #   PREFIX.B := B $(INHERIT_TAG)aaa C $(INHERIT_TAG)bbb D E
    120 # Then
    121 #   $(call get-inherited-nodes,PREFIX,A B)
    122 # returns
    123 #   aaa bbb
    124 #
    125 # $(1): variable prefix
    126 # $(2): list of variables to check
    127 #
    128 define get-inherited-nodes
    129 $(sort \
    130   $(subst $(INHERIT_TAG),, \
    131     $(filter $(INHERIT_TAG)%, \
    132       $(foreach v,$(2),$($(1).$(v))) \
    133  )))
    134 endef
    135 
    136 #
    137 # for each variable ( (prefix + name) * vars ):
    138 #   get list of inherited words; if not empty:
    139 #     for each inherit:
    140 #       replace the first occurrence with (prefix + inherited + var)
    141 #       clear the source var so we can't inherit the value twice
    142 #
    143 # $(1): context prefix
    144 # $(2): name of this node
    145 # $(3): list of variable names
    146 #
    147 define _expand-inherited-values
    148   $(foreach v,$(3), \
    149     $(eval ### "Shorthand for the name of the target variable") \
    150     $(eval _eiv_tv := $(1).$(2).$(v)) \
    151     $(eval ### "Get the list of nodes that this variable inherits") \
    152     $(eval _eiv_i := \
    153         $(sort \
    154             $(patsubst $(INHERIT_TAG)%,%, \
    155                 $(filter $(INHERIT_TAG)%, $($(_eiv_tv)) \
    156      )))) \
    157     $(foreach i,$(_eiv_i), \
    158       $(eval ### "Make sure that this inherit appears only once") \
    159       $(eval $(_eiv_tv) := \
    160           $(call uniq-word,$($(_eiv_tv)),$(INHERIT_TAG)$(i))) \
    161       $(eval ### "Expand the inherit tag") \
    162       $(eval $(_eiv_tv) := \
    163           $(strip \
    164               $(patsubst $(INHERIT_TAG)$(i),$($(1).$(i).$(v)), \
    165                   $($(_eiv_tv))))) \
    166       $(eval ### "Clear the child so DAGs don't create duplicate entries" ) \
    167       $(eval $(1).$(i).$(v) :=) \
    168       $(eval ### "If we just inherited ourselves, it's a cycle.") \
    169       $(if $(filter $(INHERIT_TAG)$(2),$($(_eiv_tv))), \
    170         $(warning Cycle detected between "$(2)" and "$(i)" for context "$(1)") \
    171         $(error import of "$(2)" failed) \
    172       ) \
    173      ) \
    174    ) \
    175    $(eval _eiv_tv :=) \
    176    $(eval _eiv_i :=)
    177 endef
    178 
    179 #
    180 # $(1): context prefix
    181 # $(2): makefile representing this node
    182 # $(3): list of node variable names
    183 #
    184 # _include_stack contains the list of included files, with the most recent files first.
    185 define _import-node
    186   $(eval _include_stack := $(2) $$(_include_stack))
    187   $(call clear-var-list, $(3))
    188   $(eval LOCAL_PATH := $(patsubst %/,%,$(dir $(2))))
    189   $(eval MAKEFILE_LIST :=)
    190   $(eval include $(2))
    191   $(eval _included := $(filter-out $(2),$(MAKEFILE_LIST)))
    192   $(eval MAKEFILE_LIST :=)
    193   $(eval LOCAL_PATH :=)
    194   $(call copy-var-list, $(1).$(2), $(3))
    195   $(call clear-var-list, $(3))
    196 
    197   $(eval $(1).$(2).inherited := \
    198       $(call get-inherited-nodes,$(1).$(2),$(3)))
    199   $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3))
    200 
    201   $(call _expand-inherited-values,$(1),$(2),$(3))
    202 
    203   $(eval $(1).$(2).inherited :=)
    204   $(eval _include_stack := $(wordlist 2,9999,$$(_include_stack)))
    205 endef
    206 
    207 #
    208 # This will generate a warning for _included above
    209 #  $(if $(_included), \
    210 #      $(eval $(warning product spec file: $(2)))\
    211 #      $(foreach _inc,$(_included),$(eval $(warning $(space)$(space)$(space)includes: $(_inc)))),)
    212 #
    213 
    214 #
    215 # $(1): context prefix
    216 # $(2): list of makefiles representing nodes to import
    217 # $(3): list of node variable names
    218 #
    219 #TODO: Make the "does not exist" message more helpful;
    220 #      should print out the name of the file trying to include it.
    221 define _import-nodes-inner
    222   $(foreach _in,$(2), \
    223     $(if $(wildcard $(_in)), \
    224       $(if $($(1).$(_in).seen), \
    225         $(eval ### "skipping already-imported $(_in)") \
    226        , \
    227         $(eval $(1).$(_in).seen := true) \
    228         $(call _import-node,$(1),$(strip $(_in)),$(3)) \
    229        ) \
    230      , \
    231       $(error $(1): "$(_in)" does not exist) \
    232      ) \
    233    )
    234 endef
    235 
    236 #
    237 # $(1): output list variable name, like "PRODUCTS" or "DEVICES"
    238 # $(2): list of makefiles representing nodes to import
    239 # $(3): list of node variable names
    240 #
    241 define import-nodes
    242 $(if \
    243   $(foreach _in,$(2), \
    244     $(eval _node_import_context := _nic.$(1).[[$(_in)]]) \
    245     $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
    246                 should be empty here: $(_include_stack))),) \
    247     $(eval _include_stack := ) \
    248     $(call _import-nodes-inner,$(_node_import_context),$(_in),$(3)) \
    249     $(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) \
    250     $(eval _node_import_context :=) \
    251     $(eval $(1) := $($(1)) $(_in)) \
    252     $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \
    253                 should be empty here: $(_include_stack))),) \
    254    ) \
    255 ,)
    256 endef
    257