# $Id$ ## @file # kBuild - Footer - Target lists - Pass 2 - Template & Target Inheritance, Uses and Tools. # # # Copyright (c) 2004-2017 knut st. osmundsen # # This file is part of kBuild. # # kBuild is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version source of the License, or # (at your option) any later version. # # kBuild is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with kBuild; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # As a special exception you are granted permission to include this file, via # the kmk include directive, as you wish without this in itself causing the # resulting makefile, program or whatever to be covered by the GPL license. # This exception does not however invalidate any other reasons why the makefile, # program, whatever should not be covered the GPL. # # ## Converts a variable from simple to recursive flavor. # This is used by def_inherit_template_one_accumulate_l and def_inherit_template_one_accumulate_r. # @param $1 The variable name. define def_simple_2_recursive $1_DEFERRED := $$($1) $1 = $$($1_DEFERRED) endef ## Inherit one keyword in a non-accumulative manner. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. define def_inherit_one_keyword ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) = $($(trg)_$(prop).$(src_key)) endif endif endef # EXPAND_BY = overriding ## Inherit one keyword in a non-accumulative manner. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. define def_inherit_one_keyword_overriding_now_l ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) := $($(trg)_$(prop).$(src_key)) endif endif endef ## @copydoc def_inherit_one_overriding_now_l define def_inherit_one_keyword_overriding_now_r ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) := $($(trg)_$(prop).$(src_key)) endif endif endef ## Inherit one keyword in a non-accumulative manner, deferred expansion. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. # @remark This define relies on double evaluation define def_inherit_one_keyword_overriding_deferred ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) = $$($(trg)_$(prop).$(src_key)) endif endif endef ## @copydoc def_inherit_one_overriding_deferred define def_inherit_one_keyword_overriding_deferred_l ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) = $$($(trg)_$(prop).$(src_key)) endif endif endef ## @copydoc def_inherit_one_overriding_deferred define def_inherit_one_keyword_overriding_deferred_r ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) = $$($(trg)_$(prop).$(src_key)) endif endif endef # EXPAND_BY = prepending ## Inherit one keyword in a prepending manner. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. define def_inherit_one_keyword_prepending_now_l ifdef $(trg)_$(prop).$(src_key) $(trg)_$(prop).$(trg_key) := $($(trg)_$(prop).$(src_key)) $($(trg)_$(prop).$(trg_key)) endif endef ## @copydoc def_inherit_one_prepending_now_l define def_inherit_one_keyword_prepending_now_r ifdef $(trg)_$(prop).$(src_key) $(trg)_$(prop).$(trg_key) := $($(trg)_$(prop).$(trg_key)) $($(trg)_$(prop).$(src_key)) endif endef ## Inherit one keyword in a non-accumulative manner, deferred expansion. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. # @remark This define relies on double evaluation define def_inherit_one_keyword_prepending_deferred ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) = $$($(trg)_$(prop).$(src_key)) endif endif endef ## Inherit one keyword in a prepending manner, deferred expansion. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. define def_inherit_one_keyword_prepending_deferred_l ifdef $(trg)_$(prop).$(src_key) ifeq ($$(flavor $(trg)_$(prop).$(trg_key)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop).$(trg_key)) endif $(trg)_$(prop).$(trg_key) <= $$($(trg)_$(prop).$(src_key)) endif endef ## @copydoc def_inherit_one_prepending_deferred_l define def_inherit_one_keyword_prepending_deferred_r ifdef $(trg)_$(prop).$(src_key) ifeq ($$(flavor $(trg)_$(prop).$(trg_key)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop).$(trg_key)) endif $(trg)_$(prop).$(trg_key) += $$($(trg)_$(prop).$(src_key)) endif endef # EXPAND_BY = appending ## Inherit one keyword in an appending manner. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. define def_inherit_one_keyword_appending_now_l ifdef $(trg)_$(prop).$(src_key) $(trg)_$(prop).$(trg_key) := $($(trg)_$(prop).$(trg_key)) $($(trg)_$(prop).$(src_key)) endif endef ## @copydoc def_inherit_one_appending_now_l define def_inherit_one_keyword_appending_now_r ifdef $(trg)_$(prop).$(src_key) $(trg)_$(prop).$(trg_key) := $($(trg)_$(prop).$(src_key)) $($(trg)_$(prop).$(trg_key)) endif endef ## Inherit one keyword in a non-accumulative manner, deferred expansion. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. # @remark This define relies on double evaluation define def_inherit_one_keyword_appending_deferred ifdef $(trg)_$(prop).$(src_key) ifndef $(trg)_$(prop).$(trg_key) $(trg)_$(prop).$(trg_key) = $$($(trg)_$(prop).$(src_key)) endif endif endef ## Inherit one keyword in an appending manner, deferred expansion. # @param $(trg) Target object. # @param $(prop) The property. # @param $(src_key) Source keyword. # @param $(trg_key) Target keyword. define def_inherit_one_keyword_appending_deferred_l ifdef $(trg)_$(prop).$(src_key) ifeq ($$(flavor $(trg)_$(prop).$(trg_key)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop).$(trg_key)) endif $(trg)_$(prop).$(trg_key) += $$($(trg)_$(prop).$(src_key)) endif endef ## @copydoc def_inherit_one_appending_deferred_l define def_inherit_one_keyword_appending_deferred_r ifdef $(trg)_$(prop).$(src_key) ifeq ($$(flavor $(trg)_$(prop).$(trg_key)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop).$(trg_key)) endif $(trg)_$(prop).$(trg_key) <= $$($(trg)_$(prop).$(src_key)) endif endef ## Worker for def_inherit that deals with one keyword that makes # use of inheritance. # @param prefix_keyword key_prefix:keyword. The cool join/split game as usual. # @param trg Object to consider for inheriting. # @param properties List of the properties with straight expansion. # @param properties_now_l List of the properties with immediate expansion, accumulating on the left side. # @param properties_now_r List of the properties with immediate expansion, accumulating on the right side. # @param properties_deferred List of the properties with deferred expansion (e.g. function), non-accumulative . # @param properties_deferred_l List of the properties with deferred expansion (e.g. function), accumulating on the left side. # @param properties_deferred_r List of the properties with deferred expansion (e.g. function), accumulating on the right side. define def_inherit_keyword local prefix := $(word 1,$(subst :, ,$(prefix_keyword))) local trg_key := $(word 2,$(subst :, ,$(prefix_keyword))) local src_key := $($(prefix)_$(trg_key)_EXTENDS) local by := $($(prefix)_$(trg_key)_EXTENDS_BY) # Inherit the properties. $(foreach prop, $(properties), $(eval $(def_inherit_one_keyword))) $(foreach prop, $(properties_now_l), $(eval $(def_inherit_one_keyword_$(by)_now_l))) $(foreach prop, $(properties_now_r), $(eval $(def_inherit_one_keyword_$(by)_now_r))) $(foreach prop, $(properties_deferred), $(eval $(def_inherit_one_keyword_$(by)_deferred))) $(foreach prop, $(properties_deferred_l), $(eval $(def_inherit_one_keyword_$(by)_deferred_l))) $(foreach prop, $(properties_deferred_r), $(eval $(def_inherit_one_keyword_$(by)_deferred_r))) endef # def_inherit_keyword ## Inherit one template property in a non-accumulative manner. # @param $(prop) Property name # @param $(src) Source (parent) object. # @param $(trg) Target (child) object. define def_inherit_one ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) = $($(src)_$(prop)) endif endif endef # EXPAND_BY = overriding ## Inherit one template property in a non-accumulative manner. # @param $(prop) Property name # @param $(src) Source (parent) object. # @param $(trg) Target (child) object. define def_inherit_one_overriding_now_l ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) := $($(src)_$(prop)) endif endif endef ## @copydoc def_inherit_one_overriding_now_l define def_inherit_one_overriding_now_r ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) := $($(src)_$(prop)) endif endif endef ## Inherit one template property in a non-accumulative manner, deferred expansion. # @param $(prop) Property name # @param $(src) Source # @param $(trg) Target # @remark This define relies on double evaluation define def_inherit_one_overriding_deferred ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) = $$($(src)_$(prop)) endif endif endef ## @copydoc def_inherit_one_overriding_deferred define def_inherit_one_overriding_deferred_l ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) = $$($(src)_$(prop)) endif endif endef ## @copydoc def_inherit_one_overriding_deferred define def_inherit_one_overriding_deferred_r ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) = $$($(src)_$(prop)) endif endif endef # EXPAND_BY = prepending ## Inherit one template property in a prepending manner. # @param $(prop) Property name # @param $(src) Source (parent) object. # @param $(trg) Target (child) object. define def_inherit_one_prepending_now_l ifdef $(src)_$(prop) $(trg)_$(prop) := $($(src)_$(prop)) $($(trg)_$(prop)) endif endef ## @copydoc def_inherit_one_prepending_now_l define def_inherit_one_prepending_now_r ifdef $(src)_$(prop) $(trg)_$(prop) := $($(trg)_$(prop)) $($(src)_$(prop)) endif endef ## Inherit one template property in a non-accumulative manner, deferred expansion. # @param $(prop) Property name # @param $(src) Source # @param $(trg) Target # @remark This define relies on double evaluation define def_inherit_one_prepending_deferred ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) = $$($(src)_$(prop)) endif endif endef ## Inherit one template property in a prepending manner, deferred expansion. # @param $(prop) Property name # @param $(src) Source (parent) object. # @param $(trg) Target (child) object. define def_inherit_one_prepending_deferred_l ifdef $(src)_$(prop) ifeq ($$(flavor $(trg)_$(prop)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop)) endif $(trg)_$(prop) <= $$($(src)_$(prop)) endif endef ## @copydoc def_inherit_one_prepending_deferred_l define def_inherit_one_prepending_deferred_r ifdef $(src)_$(prop) ifeq ($$(flavor $(trg)_$(prop)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop)) endif $(trg)_$(prop) += $$($(src)_$(prop)) endif endef # EXPAND_BY = appending ## Inherit one template property in an appending manner. # @param $(prop) Property name # @param $(src) Source (parent) object. # @param $(trg) Target (child) object. define def_inherit_one_appending_now_l ifdef $(src)_$(prop) $(trg)_$(prop) := $($(trg)_$(prop)) $($(src)_$(prop)) endif endef ## @copydoc def_inherit_one_appending_now_l define def_inherit_one_appending_now_r ifdef $(src)_$(prop) $(trg)_$(prop) := $($(src)_$(prop)) $($(trg)_$(prop)) endif endef ## Inherit one template property in a non-accumulative manner, deferred expansion. # @param $(prop) Property name # @param $(src) Source # @param $(trg) Target # @remark This define relies on double evaluation define def_inherit_one_appending_deferred ifdef $(src)_$(prop) ifndef $(trg)_$(prop) $(trg)_$(prop) = $$($(src)_$(prop)) endif endif endef ## Inherit one template property in an appending manner, deferred expansion. # @param $(prop) Property name # @param $(src) Source (parent) object. # @param $(trg) Target (child) object. define def_inherit_one_appending_deferred_l ifdef $(src)_$(prop) ifeq ($$(flavor $(trg)_$(prop)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop)) endif $(trg)_$(prop) += $$($(src)_$(prop)) endif endef ## @copydoc def_inherit_one_appending_deferred_l define def_inherit_one_appending_deferred_r ifdef $(src)_$(prop) ifeq ($$(flavor $(trg)_$(prop)),simple) $$(evalcall2 def_simple_2_recursive,$(trg)_$(prop)) endif $(trg)_$(prop) <= $$($(src)_$(prop)) endif endef ## combines the specified properties $(1) with the $(_KEYWORDS) list. _INHERIT_JOIN_KEYWORDS = $(1) $(foreach keyword,$(_KEYWORDS), $(addsuffix .$(keyword), $(1))) ## Generic inheritance for use with targets templates and tools. # @param trg Object to consider for inheriting. # @param src_prefix What to prefix the value found in EXTENDS with to get the object. # @param load_function Load function for stuff that needs # @param properties List of the properties with straight expansion. # @param properties_now_l List of the properties with immediate expansion, accumulating on the left side. # @param properties_now_r List of the properties with immediate expansion, accumulating on the right side. # @param properties_deferred List of the properties with deferred expansion (e.g. function), non-accumulative . # @param properties_deferred_l List of the properties with deferred expansion (e.g. function), accumulating on the left side. # @param properties_deferred_r List of the properties with deferred expansion (e.g. function), accumulating on the right side. define def_inherit # Load it - loading is a mess, fix. ifneq ($(load_function),) local loading := $(patsubst $(src_prefix)%,%,$(trg)) $(evalvalctx $(load_function)) endif local src := $(strip $($(trg)_EXTENDS)) ifneq ($(src),) ifndef $(trg)_EXTENDS_STATUS_ $(trg)_EXTENDS_STATUS_ := 0 # Load the source. ifneq ($(load_function),) local loading := $(src) $(evalvalctx $(load_function)) endif # less typing. local src := $(src_prefix)$(src) # Recursivly process the parent (src) if it's inherting from somebody too. ifdef $(src)_EXTENDS ifneq ($($(src)_EXTENDS_STATUS_),42) # 'foreach' will create 'trg' in a new variable context hiding # out current variable. 'src' OTOH will be overwritten. $(foreach trg, $(src), $(evalval def_inherit)) local src := $(src_prefix)$(strip $($(trg)_EXTENDS)) endif endif # Get & check EXTENDS_BY. local by = $(strip $($(trg)_EXTENDS_BY)) ifeq ($(by),) local by = overriding else ifn1of ($(by), overriding appending prepending) $(error kBuild: Invalid EXTENDS_BY value '$(by)' on '$(trg)'!) endif # Inherit the properties. $(foreach prop, $(call _INHERIT_JOIN_KEYWORDS,$(properties)), $(eval $(def_inherit_one))) $(foreach prop, $(call _INHERIT_JOIN_KEYWORDS,$(properties_now_l)), $(eval $(def_inherit_one_$(by)_now_l))) $(foreach prop, $(call _INHERIT_JOIN_KEYWORDS,$(properties_now_r)), $(eval $(def_inherit_one_$(by)_now_r))) $(foreach prop, $(call _INHERIT_JOIN_KEYWORDS,$(properties_deferred)), $(eval $(def_inherit_one_$(by)_deferred))) $(foreach prop, $(call _INHERIT_JOIN_KEYWORDS,$(properties_deferred_l)), $(eval $(def_inherit_one_$(by)_deferred_l))) $(foreach prop, $(call _INHERIT_JOIN_KEYWORDS,$(properties_deferred_r)), $(eval $(def_inherit_one_$(by)_deferred_r))) # Mark the target as done. $(trg)_EXTENDS_STATUS_ := 42 else # Check for inheritance loops. ifneq ($($(trg)_EXTENDS_STATUS_),42) $(error kBuild: Target inheritance loop! target=$(trg) $(trg)_EXTENDS_STATUS_=$($(trg)_EXTENDS_STATUS_)) endif endif endif # Keyword inheritance. $(foreach prefix_keyword, $(join $(_KEYWORDS_PREFIX), $(addprefix :,$(_KEYWORDS_EXTENDS))), $(evalval def_inherit_keyword)) endef # def_inherit # # Load global units before doing any inheriting so they can add new properties. # # This only applies to the guys listed in the global USES since there is # no reliable way to deal with things on a target level without first # applying templates. So, to avoid having USES mess up all targets, # we'll make the global and per-target USES property work differently: # The global USES does not apply to targets, just globally. # ## Unit load function. # @param loading The unit name define def_unit_load_function ifndef UNIT_$(loading) UNIT_$(loading)_KMK_FILE := $(firstword $(foreach path, $(KBUILD_UNIT_PATHS) $(KBUILD_PATH)/units $(KBUILD_DEFAULT_PATHS), $(wildcard $(path)/$(loading).kmk))) ifeq ($(UNIT_$(loading)_KMK_FILE),) $(error kBuild: Cannot find include file for the unit '$(loading)'! Searched: $(KBUILD_UNIT_PATHS) $(KBUILD_PATH)/units $(KBUILD_DEFAULT_PATHS)) endif include $(UNIT_$(loading)_KMK_FILE) ifndef UNIT_$(loading) $(warning kBuild: UNIT_$(loading) was not defined by $(UNIT_$(loading)_KMK_FILE)!) endif endif endef # def_unit_load_function $(foreach loading, \ $(USES.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) \ $(USES.$(KBUILD_TARGET_CPU)) \ $(USES.$(KBUILD_TARGET_ARCH)) \ $(USES.$(KBUILD_TARGET)) \ $(USES.$(KBUILD_HOST).$(KBUILD_HOST_ARCH)) \ $(USES.$(KBUILD_HOST_CPU)) \ $(USES.$(KBUILD_HOST_ARCH)) \ $(USES.$(KBUILD_TARGET)) \ $(USES.$(KBUILD_TYPE)) \ $(USES),$(evalval def_unit_load_function)) # # Determin all the templates that is being used and make # sure they are present before we try collect keywords. # _TEMPLATES := $(TEMPLATE) define def_templates ifdef $(target)_TEMPLATE ifneq ("$($(target)_TEMPLATE)","$(strip $($(target)_TEMPLATE))") $$(error kBuild: The template name of target '$(target)' contains tabs ($($(target)_TEMPLATE))). Please remove them) endif _TEMPLATES += $($(target)_TEMPLATE) endif endef # def_templates $(foreach target, $(_ALL_TARGETS), $(eval $(def_templates))) _TEMPLATES := $(sort $(_TEMPLATES)) ## Template load function. # @param loading The template name. This is prefixed. define def_templates_load_function ifndef TEMPLATE_$(loading) TEMPLATE_$(loading)_KMK_FILE := $(firstword $(foreach path, $(KBUILD_TEMPLATE_PATHS) $(KBUILD_PATH)/templates $(KBUILD_DEFAULT_PATHS), $(wildcard $(path)/$(loading).kmk))) ifeq ($(TEMPLATE_$(loading)_KMK_FILE),) $(error kBuild: Cannot find include file for the template '$(loading)'! Searched: $(KBUILD_TEMPLATE_PATHS) $(KBUILD_PATH)/templates $(KBUILD_DEFAULT_PATHS) Used by target(s): $(strip $(foreach target, $(_ALL_TARGETS),$(if-expr "$($(target)_TEMPLATE)" == "$(loading)",$(target) (in $(where $(target)_TEMPLATE)),)))) endif include $(TEMPLATE_$(loading)_KMK_FILE) ifndef TEMPLATE_$(loading) $(warning kBuild: TEMPLATE_$(loading) was not defined by $(TEMPLATE_$(loading)_KMK_FILE)!) endif endif endef # def_templates_load_function $(foreach loading, $(_TEMPLATES), $(evalval def_templates_load_function)) # # Determin the keywords required for correct inherting and setup keyword inheritance. # # This means walking all the lists of immediate template and targets and # pick up all the BLD_T* keywords. Since templates that are referenced # indirectly in the inheritance hierarchy, the result from this exercise # might not be 100% accurate... :-/ # _BLD_TYPES := $(KBUILD_TYPE) _BLD_TARGETS := $(KBUILD_TARGET) $(KBUILD_HOSTS) _BLD_ARCHES := $(KBUILD_TARGET_ARCH) $(KBUILD_HOST_ARCH) _BLD_CPUS := $(KBUILD_TARGET_CPU) $(KBUILD_HOST_CPU) define def_collect_bld_xyz ifdef $(src)_BLD_TYPE ifn1of ($($(src)_BLD_TYPE), $(KBUILD_BLD_TYPES)) $(error kBuild: $(src)_BLD_TYPE=$($(src)_BLD_TYPE) not in KBUILD_BLD_TYPES={$(KBUILD_BLD_TYPES)}!) endif _BLD_TYPES += $($(src)_BLD_TYPE) endif ifdef $(src)_BLD_TRG ifn1of ($($(src)_BLD_TRG), $(KBUILD_OSES)) $(error kBuild: $(src)_BLD_TRG=$($(src)_BLD_TRG) not in KBUILD_OSES={$(KBUILD_OSES)}!) endif _BLD_TARGETS += $($(src)_BLD_TRG) endif ifdef $(src)_BLD_TRG_ARCH ifn1of ($($(src)_BLD_TRG_ARCH), $(KBUILD_ARCHES)) $(error kBuild: $(src)_BLD_TRG_ARCH=$($(src)_BLD_TRG_ARCH) not in KBUILD_ARCHES={$(KBUILD_ARCHES)}!) endif _BLD_ARCHES += $($(src)_BLD_TRG_ARCH) endif ifdef $(src)_BLD_TRG_CPU if1of ($($(src)_BLD_CPU), $(KBUILD_ARCHES) $(KBUILD_OSES) $(KBUILD_BLD_TYPES)) $(error kBuild: $(src)_BLD_TRG_CPU=$($(src)_BLD_TRG_CPU) found in KBUILD_ARCHES, KBUILD_OSES or KBUILD_BLD_TYPES!) endif _BLD_CPUS += $($(src)_BLD_TRG_CPU) endif endef # def_collect_bld_xyz $(foreach src, $(addprefix TEMPLATE_, $(_TEMPLATES)) $(_ALL_TARGETS) \ ,$(evalval def_collect_bld_xyz)) # Drop duplicate values. # WARNING! These list might not include keywords only involved in inheritance. _BLD_TYPES := $(sort $(_BLD_TYPES)) _BLD_TARGETS := $(sort $(_BLD_TARGETS)) _BLD_ARCHES := $(sort $(_BLD_ARCHES)) _BLD_CPUS := $(sort $(_BLD_CPUS)) ## Look for keywords which extends others and order them. # @param keyword # @param prefix # @param valid define def_keyword_ordering # Check for EXTENDS, fix and validate it if found. local src := $(strip $($(prefix)_$(keyword)_EXTENDS)) ifneq ($(src),) ifndef $(prefix)_$(keyword)_EXTENDS_STATUS_ ifn1of ($(src), $(valid)) $(error kBuild: $(keyword) tries to extend unknown keyword '$(src)'! (known = $(valid))) endif # Recursivly process the parent (src). ifneq ($($(prefix)_$(src)_EXTENDS_STATUS_),42) $(prefix)_$(keyword)_EXTENDS_STATUS_ := 0 # 'foreach' will create 'keyword' in a new variable context hiding # out current variable. 'src' OTOH will be overwritten. $(foreach keyword, $(src), $(evalval def_keyword_ordering)) local src := $(strip $($(prefix)_$(keyword)_EXTENDS)) endif # Check and strip EXTENDS_BY. local by = $(strip $($(prefix)_$(keyword)_EXTENDS_BY)) ifeq ($(by),) local by = overriding else ifn1of ($(by), overriding appending prepending) $(error kBuild: Invalid EXTENDS_BY value '$(by)' on '$(keyword)'!) endif # Update the attributes with stripped $(prefix)_$(keyword)_EXTENDS_BY := $(by) $(prefix)_$(keyword)_EXTENDS := $(src) # Add it to the list and mark it as done. _KEYWORDS_EXTENDS += $(keyword) _KEYWORDS_PREFIX += $(prefix) $(prefix)_$(keyword)_EXTENDS_STATUS_ := 42 else # Check for inheritance loops. ifneq ($($(trg)_EXTENDS_STATUS_),42) $(error kBuild: Keyword inheritance loop! keyword=$(keyword) $(prefix)_$(keyword)_EXTENDS_STATUS_=$($(prefix)_$(keyword)_EXTENDS_STATUS_)) endif endif else # Add it to the ordered list and mark it as done. _KEYWORDS_ORDERED += $(keyword) $(prefix)_$(src)_EXTENDS_STATUS_ := 42 endif endef # def_keyword_ordering $(eval-opt-var def_keyword_ordering) # Look for keywords which extends others and their parents, and from this # construct two lists. _KEYWORDS_ORDERED := _KEYWORDS_EXTENDS := _KEYWORDS_PREFIX := prefix := BLD_TYPE valid := $(KBUILD_BLD_TYPES) $(foreach keyword, $(_BLD_TYPES) , $(evalval def_keyword_ordering)) prefix := BLD_TRG valid := $(KBUILD_OSES) $(foreach keyword, $(_BLD_TARGETS), $(evalval def_keyword_ordering)) prefix := BLD_ARCH valid := $(KBUILD_ARCHES) $(foreach keyword, $(_BLD_ARCHES) , $(evalval def_keyword_ordering)) prefix := BLD_CPU valid := $(KBUILD_CPUS) $(foreach keyword, $(_BLD_CPUS) , $(evalval def_keyword_ordering)) ## @todo Inherit bld_trg.bld_arch for too? # Construct all the possible keywords. _KEYWORDS := $(_KEYWORDS_ORDERED) $(_KEYWORDS_EXTENDS) \ $(foreach bld_trg,$(_BLD_TARGETS),$(addprefix $(bld_trg).,$(_BLD_ARCHES))) ifdef KBUILD_PROFILE_SELF $(evalcall def_profile_self, done keywords) endif # # Target inheritance. # # This has to be done on a per target list basis as to avoid adding # incorrect properties that will wast memory, time, and may confuse # later strictness checks. This also has to be done *before* templates # are applied to the targets. Since we're doing that part rather # early on, the target inheritance feature is a bit restricted at # the moment. However, this will be addressed in a little(?) while. # src_prefix := load_function := properties_deferred_l := properties_deferred_r := # Fetches. properties := $(PROPS_FETCHES_SINGLE) properties_now_l := $(PROPS_FETCHES_ACCUMULATE_L) properties_now_r := $(PROPS_FETCHES_ACCUMULATE_R) properties_deferred := $(PROPS_FETCHES_DEFERRED) $(foreach trg, $(_ALL_FETCHES),$(evalval def_inherit)) ## Patches. - not implemented yet. #properties := $(PROPS_PATCHES_SINGLE) #properties_now_l := $(PROPS_PATCHES_ACCUMULATE_L) #properties_now_r := $(PROPS_PATCHES_ACCUMULATE_R) #properties_deferred := $(PROPS_PATCHES_DEFERRED) #$(foreach trg, $(_ALL_PATCHES),$(evalval def_inherit)) # Programs and build programs. properties := $(PROPS_PROGRAMS_SINGLE) properties_now_l := $(PROPS_PROGRAMS_ACCUMULATE_L) properties_now_r := $(PROPS_PROGRAMS_ACCUMULATE_R) properties_deferred := $(PROPS_PROGRAMS_DEFERRED) $(foreach trg, $(_ALL_BLDPROGS) $(_ALL_PROGRAMS),$(evalval def_inherit)) # Libraries and import libraries. properties := $(PROPS_LIBRARIES_SINGLE) properties_now_l := $(PROPS_LIBRARIES_ACCUMULATE_L) properties_now_r := $(PROPS_LIBRARIES_ACCUMULATE_R) properties_deferred := $(PROPS_LIBRARIES_DEFERRED) if1of ($(KBUILD_TARGET), nt os2 win) $(foreach trg, $(_ALL_LIBRARIES) $(_ALL_IMPORT_LIBS),$(evalval def_inherit)) else $(foreach trg, $(_ALL_LIBRARIES),$(evalval def_inherit)) endif # DLLs. properties := $(PROPS_DLLS_SINGLE) properties_now_l := $(PROPS_DLLS_ACCUMULATE_L) properties_now_r := $(PROPS_DLLS_ACCUMULATE_R) properties_deferred := $(PROPS_DLLS_DEFERRED) if1of ($(KBUILD_TARGET), nt os2 win) $(foreach trg, $(_ALL_DLLS),$(evalval def_inherit)) else $(foreach trg, $(_ALL_DLLS) $(_ALL_IMPORT_LIBS),$(evalval def_inherit)) endif # System modules. properties := $(PROPS_SYSMODS_SINGLE) properties_now_l := $(PROPS_SYSMODS_ACCUMULATE_L) properties_now_r := $(PROPS_SYSMODS_ACCUMULATE_R) properties_deferred := $(PROPS_SYSMODS_DEFERRED) $(foreach trg, $(_ALL_SYSMODS),$(evalval def_inherit)) # Misc binaries. properties := $(PROPS_MISCBINS_SINGLE) properties_now_l := $(PROPS_MISCBINS_ACCUMULATE_L) properties_now_r := $(PROPS_MISCBINS_ACCUMULATE_R) properties_deferred := $(PROPS_MISCBINS_DEFERRED) $(foreach trg, $(_ALL_MISCBINS),$(evalval def_inherit)) # Installs. properties := $(PROPS_INSTALLS_SINGLE) properties_now_l := $(PROPS_INSTALLS_ACCUMULATE_L) properties_now_r := $(PROPS_INSTALLS_ACCUMULATE_R) properties_deferred := $(PROPS_INSTALLS_DEFERRED) $(foreach trg, $(_ALL_INSTALLS),$(evalval def_inherit)) ifdef KBUILD_PROFILE_SELF $(evalcall def_profile_self, done target inheritance) endif # # Template Inheritance. # # This is much the same as with target inheritance, except we cannot # restrict the properties involved since we haven't got a clue which # target platforms/archs are using them. But, we can drop the instance # expansion we're doing for targets since there won't be any more # changes to either the source nor the target templates beyond this # exercise. # src_prefix := TEMPLATE_ load_function := def_templates_load_function properties := properties_now_l := properties_now_r := properties_deferred := $(PROPS_SINGLE) $(PROPS_DEFERRED) properties_deferred_l := $(PROPS_ACCUMULATE_L) properties_deferred_r := $(PROPS_ACCUMULATE_R) $(foreach trg, $(addprefix TEMPLATE_,$(_TEMPLATES)),$(evalval def_inherit)) # done inheriting. src_prefix := load_function := properties := properties_now_l := properties_now_r := properties_deferred := properties_deferred_l := properties_deferred_r := ifdef KBUILD_PROFILE_SELF $(evalcall def_profile_self, done template inheritance) endif # # Template/Target Expansion. # # Extend all targets with the values from the template. Doing this up front # allows more generic code and less mess down in the pass 2 target handling. # However it does eat a good deal of memory. # define def_inherit_template_workaround_target local _tmpl := $(firstword $($(target)_TEMPLATE) $(TEMPLATE)) local _bld_type := $(firstword $($(target)_BLD_TYPE) $(TEMPLATE_$(_tmpl)_BLD_TYPE) $(KBUILD_TYPE)) local _bld_trg := $(firstword $($(target)_BLD_TRG) $(TEMPLATE_$(_tmpl)_BLD_TRG) $(KBUILD_TARGET)) local _bld_trg_arch := $(firstword $($(target)_BLD_TRG_ARCH) $(TEMPLATE_$(_tmpl)_BLD_TRG_ARCH) $(KBUILD_TARGET_ARCH)) local _bld_trg_cpu := $(firstword $($(target)_BLD_TRG_CPU) $(TEMPLATE_$(_tmpl)_BLD_TRG_CPU) $(KBUILD_TARGET_CPU)) $(kb-exp-tmpl 1,$(target),$(_bld_trg),$(_bld_trg_arch),$(_bld_trg_cpu),$(_bld_type)) endef # def_inherit_template_workaround_target #$(kb-exp-tmpl 1,$(_ALL_TARGET_TARGETS),$(KBUILD_TARGET),$(KBUILD_TARGET_ARCH),$(KBUILD_TARGET_CPU),$(KBUILD_TYPE)) $(foreach target,$(_ALL_TARGET_TARGETS),$(evalval def_inherit_template_workaround_target)) define def_inherit_template_workaround_host local _tmpl := $(firstword $($(target)_TEMPLATE) $(TEMPLATE)) local _bld_type := $(firstword $($(target)_BLD_TYPE) $(TEMPLATE_$(_tmpl)_BLD_TYPE) $(KBUILD_TYPE)) local _bld_trg := $(firstword $($(target)_BLD_TRG) $(TEMPLATE_$(_tmpl)_BLD_TRG) $(KBUILD_HOST)) local _bld_trg_arch := $(firstword $($(target)_BLD_TRG_ARCH) $(TEMPLATE_$(_tmpl)_BLD_TRG_ARCH) $(KBUILD_HOST_ARCH)) local _bld_trg_cpu := $(firstword $($(target)_BLD_TRG_CPU) $(TEMPLATE_$(_tmpl)_BLD_TRG_CPU) $(KBUILD_HOST_CPU)) $(kb-exp-tmpl 1,$(target),$(_bld_trg),$(_bld_trg_arch),$(_bld_trg_cpu),$(_bld_type)) endef # def_inherit_template_workaround_target #$(kb-exp-tmpl 1,$(_ALL_HOST_TARGETS),$(KBUILD_HOST),$(KBUILD_HOST_ARCH),$(KBUILD_HOST_CPU),$(KBUILD_TYPE)) $(foreach target,$(_ALL_HOST_TARGETS),$(evalval def_inherit_template_workaround_host)) ifdef KBUILD_PROFILE_SELF $(evalcall def_profile_self, done template/target expansion) endif # # Include tools, sdks and units. # # The first part of this exercise is to figure out which TOOLS and SDKS # that should be included. # _TOOLS := $(TOOL.$(KBUILD_TARGET)) $(TOOL.$(KBUILD_TARGET_ARCH)) $(TOOL.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) \ $(TOOL.$(KBUILD_HOST)) $(TOOL.$(KBUILD_HOST_ARCH)) $(TOOL.$(KBUILD_HOST).$(KBUILD_HOST_ARCH)) \ $(TOOL) _SDKS := $(SDKS.$(KBUILD_TARGET)) $(SDKS.$(KBUILD_TARGET_ARCH)) $(SDKS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) \ $(SDKS.$(KBUILD_HOST)) $(SDKS.$(KBUILD_HOST_ARCH)) $(SDKS.$(KBUILD_HOST).$(KBUILD_HOST_ARCH)) \ $(SDKS.$(KBUILD_TYPE)) \ $(SDKS) _USES := $(USES.$(KBUILD_TARGET)) $(USES.$(KBUILD_TARGET_ARCH)) $(USES.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)) \ $(USES.$(KBUILD_HOST)) $(USES.$(KBUILD_HOST_ARCH)) $(USES.$(KBUILD_HOST).$(KBUILD_HOST_ARCH)) \ $(USES.$(KBUILD_TYPE)) \ $(USES) define def_tools_sdks_target_source $(eval _TOOLS += $(foreach prop, $(PROPS_TOOLS), \ $($(source)_$(prop).$(_bld_trg)) \ $($(target)_$(source)_$(prop).$(_bld_trg)) \ $($(source)_$(prop).$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_$(source)_$(prop).$(_bld_trg).$(_bld_trg_arch)) \ $($(source)_$(prop).$(_bld_trg_arch)) \ $($(target)_$(source)_$(prop).$(_bld_trg_arch)) \ $($(source)_$(prop)) \ $($(target)_$(source)_$(prop)))) $(eval _SDKS += \ $($(source)_SDKS.$(_bld_trg)) \ $($(target)_$(source)_SDKS.$(_bld_trg)) \ $($(source)_SDKS.$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_$(source)_SDKS.$(_bld_trg).$(_bld_trg_arch)) \ $($(source)_SDKS.$(_bld_trg_arch)) \ $($(target)_$(source)_SDKS.$(_bld_trg_arch)) \ $($(source)_SDKS.$(KBUILD_TYPE)) \ $($(target)_$(source)_SDKS.$(KBUILD_TYPE)) \ $($(source)_SDKS) \ $($(target)_$(source)_SDKS)) $(eval _USES += \ $($(source)_USES.$(_bld_trg)) \ $($(target)_$(source)_USES.$(_bld_trg)) \ $($(source)_USES.$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_$(source)_USES.$(_bld_trg).$(_bld_trg_arch)) \ $($(source)_USES.$(_bld_trg_arch)) \ $($(target)_$(source)_USES.$(_bld_trg_arch)) \ $($(source)_USES.$(KBUILD_TYPE)) \ $($(target)_$(source)_USES.$(KBUILD_TYPE)) \ $($(source)_USES) \ $($(target)_$(source)_USES)) endef # def_tools_sdks_target_source $(eval-opt-var def_tools_sdks_target_source) define def_tools_sdks_target local _bld_type := $(firstword $($(target)_BLD_TYPE) $(KBUILD_TYPE)) local _bld_trg := $(firstword $($(target)_BLD_TRG) $(bld_trg)) local _bld_trg_arch := $(firstword $($(target)_BLD_TRG_ARCH) $(bld_trg_arch)) local _bld_trg_cpu := $(firstword $($(target)_BLD_TRG_CPU) $(bld_trg_cpu)) $(eval _TOOLS += $(foreach prop, $(PROPS_TOOLS), \ $($(target)_$(prop).$(_bld_trg)) \ $($(target)_$(prop).$(_bld_trg_arch)) \ $($(target)_$(prop).$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_$(prop)))) $(eval _SDKS += \ $($(target)_SDKS.$(_bld_trg)) \ $($(target)_SDKS.$(_bld_trg_arch)) \ $($(target)_SDKS.$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_SDKS)) $(eval _USES += \ $($(target)_USES.$(_bld_trg)) \ $($(target)_USES.$(_bld_trg_arch)) \ $($(target)_USES.$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_USES)) $(foreach source, \ $($(target)_SOURCES.$(_bld_trg)) \ $($(target)_SOURCES.$(_bld_trg_arch)) \ $($(target)_SOURCES.$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_SOURCES.$(_bld_trg_cpu)) \ $($(target)_SOURCES.$(_bld_type)) \ $($(target)_SOURCES) \ , $(evalval def_tools_sdks_target_source)) endef # def_tools_sdks_target $(eval-opt-var def_tools_sdks_target) define def_tools_srcname_target local _bld_type := $(firstword $($(target)_BLD_TYPE) $(KBUILD_TYPE)) local _bld_trg := $(firstword $($(target)_BLD_TRG) $(bld_trg)) local _bld_trg_arch := $(firstword $($(target)_BLD_TRG_ARCH) $(bld_trg_arch)) local _bld_trg_cpu := $(firstword $($(target)_BLD_TRG_CPU) $(bld_trg_cpu)) $(foreach source, $(notdir\ $($(target)_SOURCES.$(_bld_trg)) \ $($(target)_SOURCES.$(_bld_trg_arch)) \ $($(target)_SOURCES.$(_bld_trg).$(_bld_trg_arch)) \ $($(target)_SOURCES.$(_bld_trg_cpu)) \ $($(target)_SOURCES.$(_bld_type)) \ $($(target)_SOURCES) \ ), $(evalval def_tools_sdks_target_source)) endef # def_tools_srcname_target $(eval-opt-var def_tools_srcname_target) bld_trg := $(KBUILD_TARGET) bld_trg_arch := $(KBUILD_TARGET_ARCH) bld_trg_cpu := $(KBUILD_TARGET_CPU) $(foreach target, $(_ALL_TARGET_TARGETS), $(evalval def_tools_sdks_target)) $(foreach target, $(_ALL_SRCNAME_TARGETS), $(evalval def_tools_srcname_target)) bld_trg := $(KBUILD_HOST) bld_trg_arch := $(KBUILD_HOST_ARCH) bld_trg_cpu := $(KBUILD_HOST_CPU) $(foreach target, $(_ALL_HOST_TARGETS), $(evalval def_tools_sdks_target)) _TOOLS := $(sort $(_TOOLS)) _SDKS := $(sort $(_SDKS)) ## Tool load function. # @param loading The tool name define def_tools_load_function ifndef TOOL_$(loading) TOOL_$(loading)_KMK_FILE := $(firstword $(foreach path, $(KBUILD_TOOL_PATHS) $(KBUILD_PATH)/tools $(KBUILD_DEFAULT_PATHS), $(wildcard $(path)/$(loading).kmk))) ifeq ($(TOOL_$(loading)_KMK_FILE),) $(error kBuild: Cannot find include file for the tool '$(loading)'! Searched: $(KBUILD_TOOL_PATHS) $(KBUILD_PATH)/tools $(KBUILD_DEFAULT_PATHS)) endif include $(TOOL_$(loading)_KMK_FILE) ifndef TOOL_$(loading) $(warning kBuild: TOOL_$(loading) was not defined by $(TOOL_$(loading)_KMK_FILE)!) endif endif endef # def_tools_include ## SDK load function. # @param loading The tool name define def_sdk_load_function ifndef SDK_$(loading) SDK_$(loading)_KMK_FILE := $(firstword $(foreach path, $(KBUILD_SDK_PATHS) $(KBUILD_PATH)/sdks $(KBUILD_DEFAULT_PATHS), $(wildcard $(path)/$(loading).kmk))) ifeq ($(SDK_$(loading)_KMK_FILE),) $(error kBuild: Cannot find include file for the SDK '$(loading)'! Searched: $(KBUILD_SDK_PATHS) $(KBUILD_PATH)/sdks $(KBUILD_DEFAULT_PATHS)) endif include $(SDK_$(loading)_KMK_FILE) ifndef SDK_$(loading) $(warning kBuild: SDK_$(loading) was not defined by $(SDK_$(loading)_KMK_FILE)!) endif endif endef # def_sdk_load_function properties := properties_now_l := properties_now_r := properties_deferred := $(PROPS_SINGLE) $(PROPS_DEFERRED) properties_deferred_l := $(PROPS_ACCUMULATE_L) properties_deferred_r := $(PROPS_ACCUMULATE_R) src_prefix := SDK_ load_function := def_sdk_load_function $(foreach trg, $(addprefix SDK_,$(_SDKS)), $(evalval def_inherit)) properties_deferred := $(PROPS_SINGLE) $(PROPS_DEFERRED) $(PROPS_TOOLS_ONLY) src_prefix := TOOL_ load_function := def_tools_load_function $(foreach trg, $(addprefix TOOL_,$(_TOOLS)), $(evalval def_inherit)) # done inheriting. src_prefix := load_function := properties := properties_now_l := properties_now_r := properties_deferred := properties_deferred_l := properties_deferred_r := # No inheriting for the uses, they're just global 'code'. $(foreach loading, $(_USES), $(evalval def_unit_load_function)) ifdef KBUILD_PROFILE_SELF $(evalcall def_profile_self, done tools + sdks + units) endif