#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Clears a list of variables using ":=".
#
# E.g.,
# $(call clear-var-list,A B C)
# would be the same as:
# A :=
# B :=
# C :=
#
# $(1): list of variable names to clear
#
define clear-var-list
$( foreach v,$( 1),$( eval $(v):=))
endef
#
# Copies a list of variables into another list of variables.
# The target list is the same as the source list, but has
# a dotted prefix affixed to it.
#
# E.g.,
# $(call copy-var-list, PREFIX, A B)
# would be the same as:
# PREFIX.A := $(A)
# PREFIX.B := $(B)
#
# $(1): destination prefix
# $(2): list of variable names to copy
#
define copy-var-list
$( foreach v,$( 2),$( eval $(strip $( 1)).$(v):=$($(v))))
endef
#
# Moves a list of variables into another list of variables.
# The variable names differ by a prefix. After moving, the
# source variable is cleared.
#
# NOTE: Spaces are not allowed around the prefixes.
#
# E.g.,
# $(call move-var-list,SRC,DST,A B)
# would be the same as:
# DST.A := $(SRC.A)
# SRC.A :=
# DST.B := $(SRC.B)
# SRC.B :=
#
# $(1): source prefix
# $(2): destination prefix
# $(3): list of variable names to move
#
define move-var-list
$( foreach v,$( 3), \
$( eval $( 2).$(v) := $($( 1).$(v))) \
$( eval $( 1).$(v) :=) \
)
endef
#
# $(1): haystack
# $(2): needle
#
# Guarantees that needle appears at most once in haystack,
# without changing the order of other elements in haystack.
# If needle appears multiple times, only the first occurrance
# will survive.
#
define uniq-word
$(strip \
$( if $(filter-out 0 1,$(words $(filter $( 2),$( 1)))), \
$( eval _uniq_word_seen :=) \
$( foreach w,$( 1), \
$( if $(filter $( 2),$(w)), \
$( if $(_uniq_word_seen),, \
$(w) \
$( eval _uniq_word_seen := true)), \
$(w))), \
$( 1)))
endef
INHERIT_TAG := @inherit:
#
# Walks through the list of variables, each qualified by the prefix,
# and finds instances of words beginning with INHERIT_TAG. Scrape
# off INHERIT_TAG from each matching word, and return the sorted,
# unique set of those words.
#
# E.g., given
# PREFIX.A := A $(INHERIT_TAG)aaa B C
# PREFIX.B := B $(INHERIT_TAG)aaa C $(INHERIT_TAG)bbb D E
# Then
# $(call get-inherited-nodes,PREFIX,A B)
# returns
# aaa bbb
#
# $(1): variable prefix
# $(2): list of variables to check
#
define get-inherited-nodes
$(sort \
$(subst $(INHERIT_TAG),, \
$(filter $(INHERIT_TAG)%, \
$( foreach v,$( 2),$($( 1).$(v))) \
)))
endef
#
# for each variable ( (prefix + name) * vars ):
# get list of inherited words; if not empty:
# for each inherit:
# replace the first occurrence with (prefix + inherited + var)
# clear the source var so we can't inherit the value twice
#
# $(1): context prefix
# $(2): name of this node
# $(3): list of node variable names
# $(4): list of single value variable names (subset of $(3))
#
define _expand-inherited-values
$( foreach v,$( 3), \
$( eval ### "Shorthand for the name of the target variable") \
$( eval _eiv_tv := $( 1).$( 2).$(v)) \
$( eval ### "Get the list of nodes that this variable inherits") \
$( eval _eiv_i := \
$(sort \
$(patsubst $(INHERIT_TAG)%,%, \
$(filter $(INHERIT_TAG)%, $($(_eiv_tv)) \
)))) \
$( eval ### "Whether this variable should only take a single value") \
$( eval _eiv_sv := $(filter $(v),$( 4))) \
$( foreach i,$(_eiv_i), \
$( eval ### "Make sure that this inherit appears only once") \
$( eval $(_eiv_tv) := \
$( call uniq-word,$($(_eiv_tv)),$(INHERIT_TAG)$(i))) \
$( eval ### "The expanded value, empty if we want a single value and have one") \
$( eval _eiv_ev := \
$( if $(and $(_eiv_sv),$(filter-out $(INHERIT_TAG)%,$($(_eiv_tv)))),,\
$($( 1).$(i).$(v)) \
) \
) \
$( eval ### "Expand the inherit tag") \
$( eval $(_eiv_tv) := \
$(strip $(patsubst $(INHERIT_TAG)$(i),$(_eiv_ev),$($(_eiv_tv))))) \
$( eval ### "Clear the child so DAGs don't create duplicate entries" ) \
$( eval $( 1).$(i).$(v) :=) \
$( eval ### "If we just inherited ourselves, it's a cycle.") \
$( if $(filter $(INHERIT_TAG)$( 2),$($(_eiv_tv))), \
$(warning Cycle detected between "$(2)" and "$(i)" for context "$(1)") \
$(error import of "$(2)" failed) \
) \
) \
) \
$( eval _eiv_tv :=) \
$( eval _eiv_i :=)
endef
#
# $(1): context prefix
# $(2): makefile representing this node
# $(3): list of node variable names
# $(4): list of single value variable names (subset of $(3))
#
# _include_stack contains the list of included files, with the most recent files first.
define _ import-node
$( eval _include_stack := $( 2) $$(_include_stack))
$( call clear-var-list, $( 3))
$( eval LOCAL_PATH := $(patsubst %/,%,$(dir $( 2))))
$( eval MAKEFILE_LIST :=)
$( call dump- import-start,$(_include_stack))
$( call dump-config-vals,$( 2),before)
$( eval include $( 2))
$( call dump- import- done,$(_include_stack))
$( call dump-config-vals,$( 2),after)
$( eval _included := $(filter-out $( 2),$(MAKEFILE_LIST)))
$( eval MAKEFILE_LIST :=)
$( eval LOCAL_PATH :=)
$( call copy-var-list, $( 1).$( 2), $( 3))
$( call clear-var-list, $( 3))
$( eval $( 1).$( 2).inherited := \
$( call get-inherited-nodes,$( 1).$( 2),$( 3)))
$( call _ import-nodes-inner,$( 1),$($( 1).$( 2).inherited),$( 3),$( 4))
$( call _expand-inherited-values,$( 1),$( 2),$( 3),$( 4))
$( eval $( 1).$( 2).inherited :=)
$( eval _include_stack := $(wordlist 2, 9999,$(_include_stack)))
endef
#
# This will generate a warning for _included above
# $(if $(_included), \
# $(eval $(warning product spec file: $(2)))\
# $(foreach _inc,$(_included),$(eval $(warning $(space)$(space)$(space)includes: $(_inc)))),)
#
#
# $(1): context prefix
# $(2): list of makefiles representing nodes to import
# $(3): list of node variable names
# $(4): list of single value variable names (subset of $(3))
#
#TODO: Make the "does not exist" message more helpful;
# should print out the name of the file trying to include it.
define _ import-nodes-inner
$( foreach _in,$( 2), \
$( if $(wildcard $(_in)), \
$( if $($( 1).$(_in).seen), \
$( eval ### "skipping already-imported $(_in)") \
, \
$( eval $( 1).$(_in).seen := true) \
$( call _ import-node,$( 1),$(strip $(_in)),$( 3),$( 4)) \
) \
, \
$(error $( 1): "$(_in)" does not exist) \
) \
)
endef
#
# $(1): output list variable name, like "PRODUCTS" or "DEVICES"
# $(2): list of makefiles representing nodes to import
# $(3): list of node variable names
# $(4): list with subset of variable names that take only a single value, instead
# of the default list semantics
#
define import-nodes
$( call dump-phase-start,$( 1),$( 2),$( 3),$( 4),build/ make/core/node_fns.mk) \
$( if \
$( foreach _in,$( 2), \
$( eval _node_import_context := _nic.$( 1).[[$(_in)]]) \
$( if $(_include_stack),$( eval $(error ASSERTION FAILED: _include_stack \
should be empty here: $(_include_stack))),) \
$( eval _include_stack := ) \
$( call _ import-nodes-inner,$(_node_import_context),$(_in),$( 3),$( 4)) \
$( call move-var-list,$(_node_import_context).$(_in),$( 1).$(_in),$( 3)) \
$( eval _node_import_context :=) \
$( eval $( 1) := $($( 1)) $(_in)) \
$( if $(_include_stack),$( eval $(error ASSERTION FAILED: _include_stack \
should be empty here: $(_include_stack))),) \
) \
,) \
$( call dump-phase- end,build/ make/core/node_fns.mk)
endef
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland
|
|