github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/make/core/node_fns.mk (about)

     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