2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 01:12:13 +00:00

improved property.as-path

[SVN r14269]
This commit is contained in:
Dave Abrahams
2002-07-01 20:05:37 +00:00
parent ecdf182cce
commit 3392742d1e
6 changed files with 358 additions and 74 deletions

View File

@@ -31,8 +31,9 @@ import errors : error lol->list ;
import sequence ;
import regex ;
import set ;
import utility ;
all-attributes =
.all-attributes =
implicit # features whose values alone identify the
# feature. For example, a user is not required to
@@ -94,8 +95,8 @@ all-attributes =
;
all-features = ;
all-implicit-values = ;
.all-features = ;
.all-implicit-values = ;
# Transform features by bracketing any elements which aren't already
# bracketed by "<>"
@@ -115,12 +116,12 @@ rule feature ( name : values * : attributes * )
local error ;
# if there are any unknown attributes...
if ! ( $(attributes) in $(all-attributes) )
if ! ( $(attributes) in $(.all-attributes) )
{
error = unknown attributes:
[ set.difference $(attributes) : $(all-attributes) ] ;
[ set.difference $(attributes) : $(.all-attributes) ] ;
}
else if $(name) in $(all-features)
else if $(name) in $(.all-features)
{
error = feature already defined: ;
}
@@ -144,7 +145,7 @@ rule feature ( name : values * : attributes * )
$(name).subfeatures ?= ;
$(attributes).features += $(name) ;
all-features += $(name) ;
.all-features += $(name) ;
extend $(name) : $(values) ;
}
@@ -172,7 +173,7 @@ rule defaults ( features * )
# returns true iff all elements of names are valid features.
rule valid ( names + )
{
if [ grist $(names) ] in $(all-features)
if [ grist $(names) ] in $(.all-features)
{
return true ;
}
@@ -214,12 +215,9 @@ local rule find-implied-subfeature ( feature subvalue : value-string ? )
error invalid feature $(feature) ;
}
local v
= subfeature($(feature),$(subvalue))
subfeature($(feature),$(value-string),$(subvalue)) ;
value-string ?= "" ;
local subfeature = $($(v)) ;
return $(subfeature[1]) ;
return $($(feature)$(value-string)<>$(subvalue).subfeature) ;
}
# Given a feature name and a subfeature value, find the associated
@@ -242,7 +240,7 @@ rule implied-subfeature ( feature subvalue : value-string ? )
# generate an error if the feature is unknown
local rule validate-feature ( feature )
{
if ! [ grist $(feature) ] in $(all-features)
if ! [ grist $(feature) ] in $(.all-features)
{
error unknown feature \"$(feature)\" ;
}
@@ -266,7 +264,7 @@ local rule expand-subfeatures-aux ( feature ? : value )
{
feature = [ implied-feature $(components[1]) ] ;
}
else if ! $(feature) in $(all-features)
else if ! $(feature) in $(.all-features)
{
error unknown feature $(feature) ;
}
@@ -295,7 +293,7 @@ rule expand-subfeatures ( properties * )
return $(result) ;
}
# Helper for extend, below. Handles the case feature case.
# Helper for extend, below. Handles the feature case.
local rule extend-feature ( feature : values * )
{
validate-feature $(feature) ;
@@ -310,12 +308,12 @@ local rule extend-feature ( feature : values * )
$(v).implicit-feature = $(feature) ;
}
all-implicit-values += $(values) ;
.all-implicit-values += $(values) ;
}
$(feature).values += $(values) ;
}
# Checks that value-string is a valide value-string for the given feature.
# Checks that value-string is a valid value-string for the given feature.
local rule validate-value-string ( feature value-string )
{
local values = $(value-string) ;
@@ -354,12 +352,12 @@ rule extend-subfeature ( feature value-string ? : subfeature : subvalues * )
validate-value-string $(feature) $(value-string) ;
}
# provide a way to get from the given feature or property and
# subfeature value to the subfeature name.
value-string ?= "" ;
for local subvalue in $(subvalues)
{
local v
= subfeature($(feature),$(value-string),$(subvalue))
subfeature($(feature),$(subvalue)) ;
$(v[1]) = $(subfeature) ;
$(feature)$(value-string)<>$(subvalue).subfeature = $(subfeature) ;
}
}
@@ -431,6 +429,8 @@ rule subfeature ( feature value-string ? : subfeature : subvalues * )
}
$(feature).subfeatures += $(subfeature) ;
extend-subfeature $(feature) $(value-string) : $(subfeature) : $(subvalues) ;
local f = [ utility.ungrist $(feature) ] ;
feature $(f)-$(subfeature) : $(subvalues) ;
}
# Set the components of the given composite property
@@ -449,6 +449,10 @@ rule compose ( composite-property : component-properties * )
$($(composite-property).components) ;
}
if $(composite-property) in $(components)
{
errror composite property "$(composite-property)" cannot have itself as a component ;
}
$(composite-property).components = $(component-properties) ;
}
@@ -486,6 +490,8 @@ rule free-features ( )
return $(free.features) ;
}
# Expand all composite properties in the set so that all components
# are explicitly expressed.
rule expand-composites ( properties * )
{
local explicit-features = $(properties:G) ;
@@ -538,6 +544,76 @@ rule expand ( properties * )
return [ expand-composites $(expanded) ] ;
}
# Helper rule for minimize, below - return true iff property's feature
# is present in the contents of the variable named by feature-set-var.
local rule in-features ( feature-set-var property )
{
if $(property:G) in $($(feature-set-var))
{
return true ;
}
}
# Given an expanded property set, eliminate all redundancy: properties
# which are elements of other (composite) properties in the set will
# be eliminated, implicit properties will be expressed without feature
# grist, and sub-property values will be expressed as elements joined
# to the corresponding main property.
rule minimize ( properties * )
{
# remove properties implied by composite features
local x = $(properties) ;
for local p in $(properties)
{
if ! $(p:G)
{
error minimize requires an expanded property set, but \"$(p)\"
appears to be an un-expanded implicit feature ;
}
x = [ set.difference $(x) : $($(p).components) ] ;
}
# handle subfeatures and implicit features
local result ;
while $(x)
{
local p = $(x[1]) ;
local f = $(p:G) ;
# eliminate features in implicit properties.
if implicit in [ attributes $(f) ]
{
p = $(p:G="") ;
}
# locate all subproperties of f in the property set
local subproperties ;
local subfeatures = $($(f).subfeatures) ;
if $(subfeatures)
{
local f_ = [ utility.ungrist $(f) ] ;
subfeatures = [ grist $(f_)-$(subfeatures) ] ;
subproperties = [ sequence.filter in-features subfeatures : $(x) ] ;
}
if $(subproperties)
{
# reconstitute the joined property name
local sorted = [ sequence.insertion-sort $(subproperties) ] ;
result += $(p)-$(sorted:G="":J=-) ;
x = [ set.difference $(x[2-]) : $(subproperties) ] ;
}
else
{
result += $(p) ;
x = $(x[2-]) ;
}
}
return $(result) ;
}
# Given a property-set of the form
# v1/v2/...vN-1/<fN>vN/<fN+1>vN+1/...<fM>vM
#
@@ -619,6 +695,18 @@ local rule __test__ ( )
: expand debug <optimization>on
;
assert.result gcc-3.0.1 debug <optimization>on
: minimize [ expand gcc-3.0.1 debug <optimization>on ]
;
assert.result gcc-3.0.1 debug
: minimize [ expand gcc-3.0.1 debug <optimization>off ]
;
assert.result debug <optimization>on
: minimize [ expand debug <optimization>on ]
;
assert.result <x>y/z <a>b/c <d>e/f
: split <x>y/z/<a>b/c/<d>e/f
;

View File

@@ -77,16 +77,57 @@ rule refine ( properties * : requirements * : feature-space ? )
}
}
# Returns a path which represents the given property set.
# TODO: this is a quick sketch. We need much better logic.
rule as-path ( properties * )
# Helper for as-path, below. Orders properties with the implicit ones
# first, and within the two sections in alphabetical order of feature
# name.
local rule path-order ( feature-space x y )
{
if $(y:G) && ! $(x:G)
{
return true ;
}
else if $(x:G) && ! $(y:G)
{
return ;
}
else
{
if ! $(x:G)
{
x = [ $(feature-space).expand-subfeatures $(x) ] ;
y = [ $(feature-space).expand-subfeatures $(y) ] ;
}
if $(x[0]) < $(y[0])
{
return true ;
}
}
}
# Returns a path which represents the given expanded property set.
rule as-path ( properties * : feature-space ? )
{
feature-space ?= feature ;
# trim redundancy
properties = [ $(feature-space).minimize $(properties) ] ;
# sort according to path-order
properties = [ sequence.insertion-sort $(properties) : path-order $(feature-space) ] ;
local components ;
for local p in $(properties)
{
local name = [ ungrist $(p:G) ] ;
local value = $(p:G=) ;
components += $(name)-$(value) ;
if $(p:G)
{
local f = [ ungrist $(p:G) ] ;
components += $(f)-$(p:G=) ;
}
else
{
components += $(p) ;
}
}
return $(components:J=/) ;
}
@@ -111,6 +152,7 @@ local rule __test__ ( )
compose <variant>debug : <define>_DEBUG <optimization>off ;
compose <variant>release : <define>NDEBUG <optimization>on ;
}
assert.result <toolset>gcc <rtti>off <define>FOO
@@ -129,15 +171,20 @@ local rule __test__ ( )
: refine <toolset>gcc : <rtti>off : $(test-space)
;
assert.result debug
: as-path <optimization>off <variant>debug
: $(test-space)
;
assert.result gcc/debug/rtti-off
: as-path <toolset>gcc <optimization>off <rtti>off <variant>debug
: $(test-space)
;
r = [ refine <toolset>gcc <rtti>off
: <rtti>on
: $(test-space) ] ;
assert.equal $(r[1]) : "@error" ;
assert.result optimization-off/variant-debug
: as-path <optimization>off <variant>debug
;
}

View File

@@ -11,14 +11,21 @@ t.set_tree("project-test3")
t.run_build_system()
t.expect_addition("bin/a.obj")
t.fail_test(t.read("bin/a.obj") != \
"""variant-debug/optimization-off
expected = """debug
a.cpp
""")
"""
if t.read("bin/a.obj") != expected:
print '***expected:'
print expected
print '***got this instead:'
print t.read("bin/a.obj")
t.fail_test(1)
t.expect_addition("bin/a.exe")
t.fail_test(t.read("bin/a.exe") != \
"""variant-debug/optimization-off
t.fail_test(t.read("bin/a.exe") !=
"""debug
bin/a.obj
""")

View File

@@ -31,8 +31,9 @@ import errors : error lol->list ;
import sequence ;
import regex ;
import set ;
import utility ;
all-attributes =
.all-attributes =
implicit # features whose values alone identify the
# feature. For example, a user is not required to
@@ -94,8 +95,8 @@ all-attributes =
;
all-features = ;
all-implicit-values = ;
.all-features = ;
.all-implicit-values = ;
# Transform features by bracketing any elements which aren't already
# bracketed by "<>"
@@ -115,12 +116,12 @@ rule feature ( name : values * : attributes * )
local error ;
# if there are any unknown attributes...
if ! ( $(attributes) in $(all-attributes) )
if ! ( $(attributes) in $(.all-attributes) )
{
error = unknown attributes:
[ set.difference $(attributes) : $(all-attributes) ] ;
[ set.difference $(attributes) : $(.all-attributes) ] ;
}
else if $(name) in $(all-features)
else if $(name) in $(.all-features)
{
error = feature already defined: ;
}
@@ -144,7 +145,7 @@ rule feature ( name : values * : attributes * )
$(name).subfeatures ?= ;
$(attributes).features += $(name) ;
all-features += $(name) ;
.all-features += $(name) ;
extend $(name) : $(values) ;
}
@@ -172,7 +173,7 @@ rule defaults ( features * )
# returns true iff all elements of names are valid features.
rule valid ( names + )
{
if [ grist $(names) ] in $(all-features)
if [ grist $(names) ] in $(.all-features)
{
return true ;
}
@@ -214,12 +215,9 @@ local rule find-implied-subfeature ( feature subvalue : value-string ? )
error invalid feature $(feature) ;
}
local v
= subfeature($(feature),$(subvalue))
subfeature($(feature),$(value-string),$(subvalue)) ;
value-string ?= "" ;
local subfeature = $($(v)) ;
return $(subfeature[1]) ;
return $($(feature)$(value-string)<>$(subvalue).subfeature) ;
}
# Given a feature name and a subfeature value, find the associated
@@ -242,7 +240,7 @@ rule implied-subfeature ( feature subvalue : value-string ? )
# generate an error if the feature is unknown
local rule validate-feature ( feature )
{
if ! [ grist $(feature) ] in $(all-features)
if ! [ grist $(feature) ] in $(.all-features)
{
error unknown feature \"$(feature)\" ;
}
@@ -266,7 +264,7 @@ local rule expand-subfeatures-aux ( feature ? : value )
{
feature = [ implied-feature $(components[1]) ] ;
}
else if ! $(feature) in $(all-features)
else if ! $(feature) in $(.all-features)
{
error unknown feature $(feature) ;
}
@@ -295,7 +293,7 @@ rule expand-subfeatures ( properties * )
return $(result) ;
}
# Helper for extend, below. Handles the case feature case.
# Helper for extend, below. Handles the feature case.
local rule extend-feature ( feature : values * )
{
validate-feature $(feature) ;
@@ -310,12 +308,12 @@ local rule extend-feature ( feature : values * )
$(v).implicit-feature = $(feature) ;
}
all-implicit-values += $(values) ;
.all-implicit-values += $(values) ;
}
$(feature).values += $(values) ;
}
# Checks that value-string is a valide value-string for the given feature.
# Checks that value-string is a valid value-string for the given feature.
local rule validate-value-string ( feature value-string )
{
local values = $(value-string) ;
@@ -354,12 +352,12 @@ rule extend-subfeature ( feature value-string ? : subfeature : subvalues * )
validate-value-string $(feature) $(value-string) ;
}
# provide a way to get from the given feature or property and
# subfeature value to the subfeature name.
value-string ?= "" ;
for local subvalue in $(subvalues)
{
local v
= subfeature($(feature),$(value-string),$(subvalue))
subfeature($(feature),$(subvalue)) ;
$(v[1]) = $(subfeature) ;
$(feature)$(value-string)<>$(subvalue).subfeature = $(subfeature) ;
}
}
@@ -431,6 +429,8 @@ rule subfeature ( feature value-string ? : subfeature : subvalues * )
}
$(feature).subfeatures += $(subfeature) ;
extend-subfeature $(feature) $(value-string) : $(subfeature) : $(subvalues) ;
local f = [ utility.ungrist $(feature) ] ;
feature $(f)-$(subfeature) : $(subvalues) ;
}
# Set the components of the given composite property
@@ -449,6 +449,10 @@ rule compose ( composite-property : component-properties * )
$($(composite-property).components) ;
}
if $(composite-property) in $(components)
{
errror composite property "$(composite-property)" cannot have itself as a component ;
}
$(composite-property).components = $(component-properties) ;
}
@@ -486,6 +490,8 @@ rule free-features ( )
return $(free.features) ;
}
# Expand all composite properties in the set so that all components
# are explicitly expressed.
rule expand-composites ( properties * )
{
local explicit-features = $(properties:G) ;
@@ -538,6 +544,76 @@ rule expand ( properties * )
return [ expand-composites $(expanded) ] ;
}
# Helper rule for minimize, below - return true iff property's feature
# is present in the contents of the variable named by feature-set-var.
local rule in-features ( feature-set-var property )
{
if $(property:G) in $($(feature-set-var))
{
return true ;
}
}
# Given an expanded property set, eliminate all redundancy: properties
# which are elements of other (composite) properties in the set will
# be eliminated, implicit properties will be expressed without feature
# grist, and sub-property values will be expressed as elements joined
# to the corresponding main property.
rule minimize ( properties * )
{
# remove properties implied by composite features
local x = $(properties) ;
for local p in $(properties)
{
if ! $(p:G)
{
error minimize requires an expanded property set, but \"$(p)\"
appears to be an un-expanded implicit feature ;
}
x = [ set.difference $(x) : $($(p).components) ] ;
}
# handle subfeatures and implicit features
local result ;
while $(x)
{
local p = $(x[1]) ;
local f = $(p:G) ;
# eliminate features in implicit properties.
if implicit in [ attributes $(f) ]
{
p = $(p:G="") ;
}
# locate all subproperties of f in the property set
local subproperties ;
local subfeatures = $($(f).subfeatures) ;
if $(subfeatures)
{
local f_ = [ utility.ungrist $(f) ] ;
subfeatures = [ grist $(f_)-$(subfeatures) ] ;
subproperties = [ sequence.filter in-features subfeatures : $(x) ] ;
}
if $(subproperties)
{
# reconstitute the joined property name
local sorted = [ sequence.insertion-sort $(subproperties) ] ;
result += $(p)-$(sorted:G="":J=-) ;
x = [ set.difference $(x[2-]) : $(subproperties) ] ;
}
else
{
result += $(p) ;
x = $(x[2-]) ;
}
}
return $(result) ;
}
# Given a property-set of the form
# v1/v2/...vN-1/<fN>vN/<fN+1>vN+1/...<fM>vM
#
@@ -619,6 +695,18 @@ local rule __test__ ( )
: expand debug <optimization>on
;
assert.result gcc-3.0.1 debug <optimization>on
: minimize [ expand gcc-3.0.1 debug <optimization>on ]
;
assert.result gcc-3.0.1 debug
: minimize [ expand gcc-3.0.1 debug <optimization>off ]
;
assert.result debug <optimization>on
: minimize [ expand debug <optimization>on ]
;
assert.result <x>y/z <a>b/c <d>e/f
: split <x>y/z/<a>b/c/<d>e/f
;

View File

@@ -77,16 +77,57 @@ rule refine ( properties * : requirements * : feature-space ? )
}
}
# Returns a path which represents the given property set.
# TODO: this is a quick sketch. We need much better logic.
rule as-path ( properties * )
# Helper for as-path, below. Orders properties with the implicit ones
# first, and within the two sections in alphabetical order of feature
# name.
local rule path-order ( feature-space x y )
{
if $(y:G) && ! $(x:G)
{
return true ;
}
else if $(x:G) && ! $(y:G)
{
return ;
}
else
{
if ! $(x:G)
{
x = [ $(feature-space).expand-subfeatures $(x) ] ;
y = [ $(feature-space).expand-subfeatures $(y) ] ;
}
if $(x[0]) < $(y[0])
{
return true ;
}
}
}
# Returns a path which represents the given expanded property set.
rule as-path ( properties * : feature-space ? )
{
feature-space ?= feature ;
# trim redundancy
properties = [ $(feature-space).minimize $(properties) ] ;
# sort according to path-order
properties = [ sequence.insertion-sort $(properties) : path-order $(feature-space) ] ;
local components ;
for local p in $(properties)
{
local name = [ ungrist $(p:G) ] ;
local value = $(p:G=) ;
components += $(name)-$(value) ;
if $(p:G)
{
local f = [ ungrist $(p:G) ] ;
components += $(f)-$(p:G=) ;
}
else
{
components += $(p) ;
}
}
return $(components:J=/) ;
}
@@ -111,6 +152,7 @@ local rule __test__ ( )
compose <variant>debug : <define>_DEBUG <optimization>off ;
compose <variant>release : <define>NDEBUG <optimization>on ;
}
assert.result <toolset>gcc <rtti>off <define>FOO
@@ -129,15 +171,20 @@ local rule __test__ ( )
: refine <toolset>gcc : <rtti>off : $(test-space)
;
assert.result debug
: as-path <optimization>off <variant>debug
: $(test-space)
;
assert.result gcc/debug/rtti-off
: as-path <toolset>gcc <optimization>off <rtti>off <variant>debug
: $(test-space)
;
r = [ refine <toolset>gcc <rtti>off
: <rtti>on
: $(test-space) ] ;
assert.equal $(r[1]) : "@error" ;
assert.result optimization-off/variant-debug
: as-path <optimization>off <variant>debug
;
}

View File

@@ -11,14 +11,21 @@ t.set_tree("project-test3")
t.run_build_system()
t.expect_addition("bin/a.obj")
t.fail_test(t.read("bin/a.obj") != \
"""variant-debug/optimization-off
expected = """debug
a.cpp
""")
"""
if t.read("bin/a.obj") != expected:
print '***expected:'
print expected
print '***got this instead:'
print t.read("bin/a.obj")
t.fail_test(1)
t.expect_addition("bin/a.exe")
t.fail_test(t.read("bin/a.exe") != \
"""variant-debug/optimization-off
t.fail_test(t.read("bin/a.exe") !=
"""debug
bin/a.obj
""")