diff --git a/src/build/generators.jam b/src/build/generators.jam index 41e0bf83c..6912d034c 100644 --- a/src/build/generators.jam +++ b/src/build/generators.jam @@ -578,6 +578,7 @@ class composing-generator : generator ; } } + .construct-stack = ; # Attempts to create target of 'target-type' with 'properties' # from 'sources'. The 'sources' are treated as a collection of @@ -588,12 +589,15 @@ class composing-generator : generator ; # even if a composing generators was already used up the call stack. # # - # Returns a vector of two vectors. The first contains targets of - # requested types. The second contains all unused sources and - # additionally generated targets. + # Returns a list of target. When this invocation is first instance of + # 'construct' in stack, returns only targets of requested 'target-type', + # otherwise, returns also unused sources and additionally generated + # targets. rule construct-dbg ( project name ? : target-type multiple ? : properties * : sources + : allow-composing-generators ? ) { + .construct-stack += 1 ; + increase-indent ; generators.dout [ indent ] "*** construct" $(target-type) ; for local s in $(sources) @@ -737,7 +741,26 @@ class composing-generator : generator ; decrase-indent ; - return $(result) ; + .construct-stack = $(.construct-stack[2-]) ; + + if ! $(.construct-stack) # This is first invocation in stack + { + local result2 ; + for local t in $(result) + { + local type = [ $(t).type ] ; + if $(type) = $(target-type) + || [ type.is-derived $(type) $(target-type) ] + { + result2 += $(t) ; + } + } + return $(result2) ; + } + else + { + return $(result) ; + } } #} diff --git a/src/build/type.jam b/src/build/type.jam index 55c98cd8a..75a383238 100644 --- a/src/build/type.jam +++ b/src/build/type.jam @@ -32,6 +32,7 @@ rule register ( type : suffixes * : base-type ? : main ? ) else { .types += $(type) ; + .bases.$(type) = $(base-type) ; .suffix.$(type) = $(suffixes[1]) ; .type.$(suffixes) = $(type) ; feature.extend target-type : $(type) ; @@ -45,13 +46,38 @@ rule register ( type : suffixes * : base-type ? : main ? ) } } +# Returns true if 'type' has 'base' as its direct or +# indirect base. +rule is-derived ( type base ) +{ + if $(base) in $(.bases.$(type)) + { + return true ; + } + else + { + # CONSIDER: maybe break when 'found' is true + local found ; + for local e in $(.bases.$(type)) + { + if [ is-derived $(e) $(base) ] + { + found = true ; + } + } + return $(found) ; + } +} + + # Returns suffix that should be used when generating target of 'type'. rule generated-target-suffix ( type ) { return $(.suffix.$(type)) ; } -# Returns file type given its suffix. +# Returns file type given its suffix. The 'suffix' parameter should include +# the dot. rule type ( suffix ) { return $(.type$(suffix)) ;