diff --git a/src/build/toolset.jam b/src/build/toolset.jam index 5af9c6842..21a23fd6d 100644 --- a/src/build/toolset.jam +++ b/src/build/toolset.jam @@ -7,6 +7,8 @@ import feature ; import numbers ; +import errors : error ; +import property ; .flag-no = 1 ; @@ -42,6 +44,9 @@ rule flags ( rule-or-module # If contains dot, should be a rule name. # - a set of property sets. If one of those property # sets is contained in build properties, 'values' # will be added to the variable. + # + # - empty. 'values' will be added to the variable + # unconditionally values * ) { .$(rule-or-module).flags += $(.flag-no) ; @@ -50,58 +55,103 @@ rule flags ( rule-or-module # If contains dot, should be a rule name. .$(rule-or-module).condition.$(.flag-no) += $(condition) ; .$(rule-or-module).values.$(.flag-no) += $(values) ; + if $(condition[1]:G=) + { + .$(rule-or-module).match-type.$(.flag-no) += property-set ; + property.validate-property-sets $(condition) ; + if ! $(values) + { + error empty value set used with property-set match criterion: + : $(condition) ; + } + } + else if $(condition) + { + .$(rule-or-module).match-type.$(.flag-no) += feature ; + if $(values) + { + error non-empty value set used with feature match criterion + } + } + else + { + .$(rule-or-module).match-type.$(.flag-no) += unconditional ; + error empty value set used with unconditional match criterion ; + } + .flag-no = [ numbers.increment $(.flag-no) ] ; } +# Returns the first element of 'property-sets' which is a subset of +# 'properties', or an empty list if no such element exists. +local rule find-property-subset ( property-sets * : properties * ) +{ + local result ; + for local s in $(property-sets) + { + if ! $(result) + { + if [ feature.split $(s) ] in $(properties) + { + result = $(s) ; + } + } + } + return $(result) ; +} rule set-target-variables ( rule-or-module target : properties * ) -{ +{ for local f in $(.$(rule-or-module).flags) { local variable = $(.$(rule-or-module).variable.$(f)) ; local condition = $(.$(rule-or-module).condition.$(f)) ; local values = $(.$(rule-or-module).values.$(f)) ; local result ; - local found ; - - for local c in $(condition) + + switch $(.$(rule-or-module).match-type.$(f)) { - local requirements = [ feature.split $(c) ] ; - - if $(requirements:G=) + case unconditional : + result += $(values) ; + + case property-set : + if [ find-property-subset $(condition) : $(properties) ] { - # This is a property set - if ! $(found) && $(requirements) in $(properties) + result += $(values) ; + } + + case feature : # add the values of all specified features to the variable + local matches = [ property.select $(condition) : $(properties) ] ; + for local p in $(matches) + { + if dependency in [ feature.attributes $(p:G) ] { - result += $(values) ; - found = 1 ; - } + # the value of a dependency feature is a target + # and must be actualized + result += [ $(p:G=).actualize ] ; + } + else + { + result += $(p:G=) ; + } } - else - { - for local r in $(requirements) - { - local item = [ feature.get-values $(r) : $(properties) ] ; - for local i in $(item) - { - if dependency in [ feature.attributes $(r:G) ] - { - result += [ $(i).actualize ] ; - } - else - { - result += $(i) ; - } - } - } - } - } - if ! $(condition) - { - result = $(values) ; } $(variable) on $(target) += $(result) ; } + + # recurse for any module-specific flags + local module = [ MATCH ^(.+)\\..* : $(rule-or-module) ] ; + if $(module) + { + set-target-variables ( $(module) $(target) : $(properties) * ) ; + } } +local rule __test__ ( ) +{ + import assert ; + local p = 1 2 3 ; + assert.result 1 2 : find-property-subset 0/0/1/2/5 9 : $(p) ; + assert.result : find-property-subset 0/0/9/9/5 9 : $(p) ; +} \ No newline at end of file