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# 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# 97define 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 )) 107endef 108 109INHERIT_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# 128define get-inherited-nodes 129$(sort \ 130 $(subst $(INHERIT_TAG),, \ 131 $(filter $(INHERIT_TAG)%, \ 132 $(foreach v,$(2),$($(1).$(v))) \ 133 ))) 134endef 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 node variable names 146# $(4): list of single value variable names (subset of $(3)) 147# 148define _expand-inherited-values 149 $(foreach v,$(3), \ 150 $(eval ### "Shorthand for the name of the target variable") \ 151 $(eval _eiv_tv := $(1).$(2).$(v)) \ 152 $(eval ### "Get the list of nodes that this variable inherits") \ 153 $(eval _eiv_i := \ 154 $(sort \ 155 $(patsubst $(INHERIT_TAG)%,%, \ 156 $(filter $(INHERIT_TAG)%, $($(_eiv_tv)) \ 157 )))) \ 158 $(eval ### "Whether this variable should only take a single value") \ 159 $(eval _eiv_sv := $(filter $(v),$(4))) \ 160 $(foreach i,$(_eiv_i), \ 161 $(eval ### "Make sure that this inherit appears only once") \ 162 $(eval $(_eiv_tv) := \ 163 $(call uniq-word,$($(_eiv_tv)),$(INHERIT_TAG)$(i))) \ 164 $(eval ### "The expanded value, empty if we want a single value and have one") \ 165 $(eval _eiv_ev := \ 166 $(if $(and $(_eiv_sv),$(filter-out $(INHERIT_TAG)%,$($(_eiv_tv)))),,\ 167 $($(1).$(i).$(v)) \ 168 ) \ 169 ) \ 170 $(eval ### "Expand the inherit tag") \ 171 $(eval $(_eiv_tv) := \ 172 $(strip $(patsubst $(INHERIT_TAG)$(i),$(_eiv_ev),$($(_eiv_tv))))) \ 173 $(eval ### "Clear the child so DAGs don't create duplicate entries" ) \ 174 $(eval $(1).$(i).$(v) :=) \ 175 $(eval ### "If we just inherited ourselves, it's a cycle.") \ 176 $(if $(filter $(INHERIT_TAG)$(2),$($(_eiv_tv))), \ 177 $(warning Cycle detected between "$(2)" and "$(i)" for context "$(1)") \ 178 $(error import of "$(2)" failed) \ 179 ) \ 180 ) \ 181 ) \ 182 $(eval _eiv_tv :=) \ 183 $(eval _eiv_i :=) 184endef 185 186# 187# $(1): context prefix 188# $(2): makefile representing this node 189# $(3): list of node variable names 190# $(4): list of single value variable names (subset of $(3)) 191# 192# _include_stack contains the list of included files, with the most recent files first. 193define _import-node 194 $(eval _include_stack := $(2) $$(_include_stack)) 195 $(call clear-var-list, $(3)) 196 $(eval LOCAL_PATH := $(patsubst %/,%,$(dir $(2)))) 197 $(eval MAKEFILE_LIST :=) 198 $(call dump-import-start,$(_include_stack)) 199 $(call dump-config-vals,$(2),before) 200 $(eval include $(2)) 201 $(call dump-import-done,$(_include_stack)) 202 $(call dump-config-vals,$(2),after) 203 $(eval _included := $(filter-out $(2),$(MAKEFILE_LIST))) 204 $(eval MAKEFILE_LIST :=) 205 $(eval LOCAL_PATH :=) 206 $(call copy-var-list, $(1).$(2), $(3)) 207 $(call clear-var-list, $(3)) 208 209 $(eval $(1).$(2).inherited := \ 210 $(call get-inherited-nodes,$(1).$(2),$(3))) 211 $(call _import-nodes-inner,$(1),$($(1).$(2).inherited),$(3),$(4)) 212 213 $(call _expand-inherited-values,$(1),$(2),$(3),$(4)) 214 215 $(eval $(1).$(2).inherited :=) 216 $(eval _include_stack := $(wordlist 2,9999,$$(_include_stack))) 217endef 218 219# 220# This will generate a warning for _included above 221# $(if $(_included), \ 222# $(eval $(warning product spec file: $(2)))\ 223# $(foreach _inc,$(_included),$(eval $(warning $(space)$(space)$(space)includes: $(_inc)))),) 224# 225 226# 227# $(1): context prefix 228# $(2): list of makefiles representing nodes to import 229# $(3): list of node variable names 230# $(4): list of single value variable names (subset of $(3)) 231# 232#TODO: Make the "does not exist" message more helpful; 233# should print out the name of the file trying to include it. 234define _import-nodes-inner 235 $(foreach _in,$(2), \ 236 $(if $(wildcard $(_in)), \ 237 $(if $($(1).$(_in).seen), \ 238 $(eval ### "skipping already-imported $(_in)") \ 239 , \ 240 $(eval $(1).$(_in).seen := true) \ 241 $(call _import-node,$(1),$(strip $(_in)),$(3),$(4)) \ 242 ) \ 243 , \ 244 $(error $(1): "$(_in)" does not exist) \ 245 ) \ 246 ) 247endef 248 249# 250# $(1): output list variable name, like "PRODUCTS" or "DEVICES" 251# $(2): list of makefiles representing nodes to import 252# $(3): list of node variable names 253# $(4): list with subset of variable names that take only a single value, instead 254# of the default list semantics 255# 256define import-nodes 257$(call dump-phase-start,$(1),$(2),$(3),$(4),build/make/core/node_fns.mk) \ 258$(if \ 259 $(foreach _in,$(2), \ 260 $(eval _node_import_context := _nic.$(1).[[$(_in)]]) \ 261 $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \ 262 should be empty here: $(_include_stack))),) \ 263 $(eval _include_stack := ) \ 264 $(call _import-nodes-inner,$(_node_import_context),$(_in),$(3),$(4)) \ 265 $(call move-var-list,$(_node_import_context).$(_in),$(1).$(_in),$(3)) \ 266 $(eval _node_import_context :=) \ 267 $(eval $(1) := $($(1)) $(_in)) \ 268 $(if $(_include_stack),$(eval $(error ASSERTION FAILED: _include_stack \ 269 should be empty here: $(_include_stack))),) \ 270 ) \ 271,) \ 272$(call dump-phase-end,build/make/core/node_fns.mk) 273endef 274