diff --git a/src/build/feature.jam b/src/build/feature.jam index ef1fdb51e..3930e8b38 100644 --- a/src/build/feature.jam +++ b/src/build/feature.jam @@ -11,6 +11,7 @@ import regex ; import set ; import utility ; import modules indirect ; +import assert : * ; local rule setup ( ) { @@ -694,7 +695,7 @@ rule expand-composites ( properties * ) # Return true iff f is an ordinary subfeature of the parent-property's # feature, or if f is a subfeature fo the parent-property's feature # specific to the parent-property's value -local rule is-subfeature ( parent-property f ) +local rule is-subfeature-of ( parent-property f ) { if subfeature in $($(f).attributes) { @@ -725,9 +726,9 @@ local rule is-subfeature ( parent-property f ) } # as above, for subproperties -local rule is-subproperty ( parent-property p ) +local rule is-subproperty-of ( parent-property p ) { - return [ is-subfeature $(parent-property) $(p:G) ] ; + return [ is-subfeature-of $(parent-property) $(p:G) ] ; } # Given a property, return the subset of features consisting of all @@ -736,13 +737,13 @@ local rule is-subproperty ( parent-property p ) # property's value. local rule select-subfeatures ( parent-property : features * ) { - return [ sequence.filter is-subfeature $(parent-property) : $(features) ] ; + return [ sequence.filter is-subfeature-of $(parent-property) : $(features) ] ; } # as above, for subproperties local rule select-subproperties ( parent-property : properties * ) { - return [ sequence.filter is-subproperty $(parent-property) : $(properties) ] ; + return [ sequence.filter is-subproperty-of $(parent-property) : $(properties) ] ; } # Given a property set which may consist of composite and implicit @@ -781,11 +782,7 @@ local rule move-subfeatures-to-the-end ( properties * ) local x2 ; for local p in $(properties) { - # Check if grist contains dash. If it is, this - # is possibly subfeature, so move it to the end - # FIXME: in general, this may be ordinary feature. - local g = $(p:G) ; - if [ MATCH "(-)" : $(g) ] + if subfeature in $($(p:G).attributes) { x2 += $(p) ; } @@ -867,6 +864,48 @@ rule minimize ( properties * ) return $(result) ; } +# Combine all subproperties into their parent properties +# +# Requires: for every subproperty, there is a parent property. All +# features are explicitly expressed. +# +# This rule probably shouldn't be needed, but +# build-request.expand-no-defaults is being abused for unintended +# purposes and it needs help +rule compress-subproperties ( properties * ) +{ + local all-subs matched-subs result ; + + for local p in $(properties) + { + if ! $(p:G) + { + assert.nonempty-variable p:G ; # expecting fully-gristed properties + } + + + if ! subfeature in $($(p:G).attributes) + { + local subs = [ + sequence.insertion-sort + [ sequence.filter is-subproperty-of $(p) : $(properties) ] + ] ; + + matched-subs += $(subs) ; + + local subvalues = -$(subs:G=:J=-) ; + subvalues ?= "" ; + result += $(p)$(subvalues) ; + } + else + { + all-subs += $(p) ; + } + } + assert.result true : set.equal $(all-subs) : $(matched-subs) ; + return $(result) ; +} + # given an ungristed string, finds the longest prefix which is a # top-level feature name followed by a dash, and return a pair # consisting of the parts before and after that dash. More diff --git a/src/build/project.jam b/src/build/project.jam index 745139f4e..6fef16687 100644 --- a/src/build/project.jam +++ b/src/build/project.jam @@ -260,10 +260,6 @@ local rule load-jamfile ( "Please consult the documentation at 'http://www.boost.org'." ; } - # The module of the jamfile. - # - local jamfile-module = [ module-name [ path.parent $(jamfile-to-load[1]) ] ] ; - # Multiple Jamfiles found in the same place. Warn about this. # And ensure we use only one of them. # @@ -272,10 +268,14 @@ local rule load-jamfile ( ECHO "WARNING: Found multiple Jamfiles at this '"$(dir)"' location!" "Loading the first one: '" [ path.basename $(jamfile-to-load[1]) ] "'." ; + + jamfile-to-load = $(jamfile-to-load[1]) ; } - jamfile-to-load = $(jamfile-to-load[1]) ; - + # The module of the jamfile. + # + local jamfile-module = [ module-name [ path.parent $(jamfile-to-load) ] ] ; + # Initialize the jamfile module before loading. # initialize $(jamfile-module) : [ path.parent $(jamfile-to-load) ] ; @@ -344,7 +344,7 @@ rule inherit-attributes ( project-module : project-root-module : parent-module ? { local attributes = $($(project-module).attributes) ; local pattributes = [ attributes $(parent-module) ] ; - $(attributes).set parent : [ path.parent $(parent) ] ; + $(attributes).set parent : [ path.parent $(parent-module) ] ; $(attributes).set default-build : [ $(pattributes).get default-build ] ; $(attributes).set requirements @@ -561,7 +561,7 @@ rule use ( id : location ) module project-rules { - rule project ( id ? : option1 * : option2 * : option3 * ) + rule project ( id ? : options * : * ) { import project ; import path ; @@ -574,17 +574,13 @@ module project-rules $(attributes).set id : $(id) ; } - if $(option1) + for n in 2 3 4 5 6 7 8 9 { - $(attributes).set $(option1[1]) : $(option1[2-]) ; - } - if $(option2) - { - $(attributes).set $(option2[1]) : $(option2[2-]) ; - } - if $(option3) - { - $(attributes).set $(option3[1]) : $(option3[2-]) ; + local option = $($(n)) ; + if $(option) + { + $(attributes).set $(option[1]) : $(option[2-]) ; + } } } diff --git a/src/build/targets.jam b/src/build/targets.jam index 588167fe1..8b89c276e 100644 --- a/src/build/targets.jam +++ b/src/build/targets.jam @@ -449,8 +449,26 @@ class main-target : abstract-target local result ; if $(defaults-to-apply) { - properties = [ build-request.expand-no-defaults - $(raw) $(defaults-to-apply) ] ; + properties = [ + build-request.expand-no-defaults + + # We have to compress subproperties here to prevent + # property lists like: + # + # msvc 7.1 multi + # + # from being expanded into: + # + # 7.1/multi + # msvc/7.1/multi + # + # due to cross-product property combination. That may + # be an indication that + # build-request.expand-no-defaults is the wrong rule + # to use here. + [ feature.compress-subproperties $(raw) ] + $(defaults-to-apply) + ] ; if $(properties) { @@ -509,7 +527,9 @@ class main-target : abstract-target # why it can't be build. print.wrapped-text "warning: skipped build of" [ full-name ] - "with properties" [ $(property-set).raw ] ; + "with properties" [ $(property-set).raw ] + "because no best-matching alternative could be found" + ; } else if $(best-alternatives[2]) {