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

Drop the notion of link-compatibility. We don't really want it for

projects, and for individual targets, it will reappear later.

* new/property.jam:
  (refine): Don't check for link-compatibility.

* new/targets.jam
  (project-target.generate): Don't call 'refine' and don't emit any
  warnings.

  (basic-target.match-rank): The alternative selection mechanism dependended
  on link-compatibility in some way. Work around the difference in semantic
  we have now. This will be resolved in a more clean way later.

* new/property-set.jam
  (property-set.link-incompatible, property-set.link-incompatible-with):
  New methods.


[SVN r20190]
This commit is contained in:
Vladimir Prus
2003-09-26 10:22:22 +00:00
parent 68dfec0436
commit 2ee0f0be56
8 changed files with 152 additions and 136 deletions

View File

@@ -25,6 +25,7 @@ class property-set
import feature ;
import property-set ;
import property ;
import set ;
rule __init__ ( raw-properties * )
{
@@ -57,6 +58,10 @@ class property-set
{
self.propagated += $(p) ;
}
if link-incompatible in $(att)
{
self.link-incompatible += $(p) ;
}
}
}
@@ -139,6 +144,17 @@ class property-set
return $(self.propagated-ps) ;
}
rule link-incompatible ( )
{
if ! $(self.link-incompatible-ps)
{
self.link-incompatible-ps =
[ property-set.create $(self.link-incompatible) ] ;
}
return $(self.link-incompatible-ps) ;
}
rule run-actions ( )
{
if ! $(self.run)
@@ -181,6 +197,32 @@ class property-set
{
return [ add [ property-set.create $(properties) ] ] ;
}
rule link-incompatible-with ( ps )
{
if ! $(.li.$(ps))
{
local li1 = [ $(__name__).link-incompatible ] ;
local li2 = [ $(ps).link-incompatible ] ;
if [ set.equal $(li1) : $(li2) ]
{
.li.$(ps) = false ;
}
else
{
.li.$(ps) = true ;
}
}
if $(.li.$(ps)) = true
{
return true ;
}
else
{
return ;
}
}
# Returns all values of 'feature'.

View File

@@ -13,13 +13,10 @@ import sequence ;
import set ;
import path ;
# Refines 'properties' by overriding any elements for which a different
# value is specified in 'requirements'. If the resulting property set
# will be link-incompatible with 'properties', it is an error.
# Refines 'properties' by overriding any non-free properties
# for which a different value is specified in 'requirements'.
# Conditional requirements are just added without modification.
# On success, returns properties. On error, returns a list which first
# element is "@error" and the other elements compose the explanation
# string.
# Returns the resulting list of properties.
rule refine ( properties * : requirements * )
{
local result ;
@@ -52,16 +49,7 @@ rule refine ( properties * : requirements * )
local value = $(p:G=) ;
if $(value) != $(required-value)
{
if link-incompatible in [ feature.attributes $(p:G) ]
{
error = @error link-incompatible properties $(p) and
$(p:G)$(required-value) ;
# Cannot break, so just iterate again
}
else
{
result += $(p:G)$(required-value) ;
}
result += $(p:G)$(required-value) ;
}
else
{
@@ -525,11 +513,6 @@ local rule __test__ ( )
: $(test-space)
;
r = [ refine <toolset>gcc <rtti>off
: <rtti>on
: $(test-space) ] ;
assert.equal $(r[1]) : "@error" ;
try ;
validate <feature>value : $(test-space) ;
catch "Invalid property '<feature>value': unknown feature 'feature'." ;

View File

@@ -192,34 +192,15 @@ class project-target : abstract-target
# Generates all possible targets contained in this project.
rule generate ( property-set * )
{
# Project properties are directly imposed on all main targets.
# However, we'd need to check if this project can be build at
# all.
local xproperties = [ $(property-set).refine $(self.requirements) ] ;
local usage-requirements = [ property-set.empty ] ;
local targets ;
if $(xproperties[1]) = "@error"
for local t in [ targets-to-build ]
{
local id = [ project.attribute $(self.project) id ] ;
print.wrapped-text "warning: skipping build of project $(id:E=) at"
[ project.attribute $(self.project) location ]
"due to unsatisfied requirements." ;
print.wrapped-text "warning: explanation: " $(xproperties[2-]) ;
print.wrapped-text "warning: build-request: " $(properties) ;
print.wrapped-text "warning: requirements: " [ $(self.requirements).raw ] ;
local g = [ $(t).generate $(property-set) ] ;
usage-requirements = [ $(usage-requirements).add $(g[1]) ] ;
targets += $(g[2-]) ;
}
else
{
for local t in [ targets-to-build ]
{
local g = [ $(t).generate $(property-set) ] ;
usage-requirements = [ $(usage-requirements).add $(g[1]) ] ;
targets += $(g[2-]) ;
}
}
return $(usage-requirements) $(targets) ;
}
@@ -838,11 +819,21 @@ class basic-target : abstract-target
{
# First check if our requirements can be satisfied.
local rproperties = [ $(property-set).refine $(self.requirements) ] ;
if $(rproperties[1]) != "@error"
{
# Kluge: previously, link-incompatible alternatives were skipped
# completely. Until a better alternative selection algorithm is
# in place, treat such alternatives as having rank of zero.
# As another kluge, add 1 to all other ranks so that zero is worse that
# anything.
if [ $(rproperties).link-incompatible-with $(property-set) ]
{
return 0 ;
}
else
{
# Returns the number of properties common to requirements
# and build request.
return [ sequence.length [ set.intersection
return [ sequence.length "fake" [ set.intersection
[ $(self.requirements).base ] :
[ $(property-set).raw ] ] ] ;
}

View File

@@ -35,33 +35,25 @@ t.expect_content("bin/$toolset/debug/main-target-b.exe/b.exe",
"bin/$toolset/debug/a.obj\n"
)
# TODO: restore this test when we have new notion of link-compatibility
#t.copy("lib/Jamfile3", "lib/Jamfile")
t.copy("lib/Jamfile2", "lib/Jamfile")
expected="""error: Requirements for project at 'lib' conflict with parent's.
Explanation: link-incompatible properties <threading>single and <threading>multi
"""
t.run_build_system("--no-error-backtrace", stdout=expected, status=None)
t.copy("lib/Jamfile3", "lib/Jamfile")
t.run_build_system(status=None)
t.fail_test(find(t.stdout(), "warning: skipped build of lib/b.obj with properties") \
!= 0)
#t.run_build_system(status=None)
#t.fail_test(find(t.stdout(), "warning: skipped build of lib/b.obj with properties") \
# != 0)
# Check that project can be skipped as well
t.copy("Jamfile4", "Jamfile")
#t.copy("Jamfile4", "Jamfile")
expected="warning: skipping build of project at lib2 due to unsatisfied requirements."
t.run_build_system("rtti=on")
t.fail_test(find(t.stdout(), expected) != 0)
#expected="warning: skipping build of project at lib2 due to unsatisfied requirements."
#t.run_build_system("rtti=on")
#t.fail_test(find(t.stdout(), expected) != 0)
t.copy("lib2/Jamfile2", "lib2/Jamfile")
#t.copy("lib2/Jamfile2", "lib2/Jamfile")
expected="warning: skipping build of project /mylib at lib2 due to unsatisfied\nrequirements."
t.run_build_system("rtti=on")
t.fail_test(find(t.stdout(), expected) != 0)
#expected="warning: skipping build of project /mylib at lib2 due to unsatisfied\nrequirements."
#t.run_build_system("rtti=on")
#t.fail_test(find(t.stdout(), expected) != 0)
# We don't yet make targets depend on Jamfile, so need to start from scratch
# The following test is disabled, because of problems related to

View File

@@ -25,6 +25,7 @@ class property-set
import feature ;
import property-set ;
import property ;
import set ;
rule __init__ ( raw-properties * )
{
@@ -57,6 +58,10 @@ class property-set
{
self.propagated += $(p) ;
}
if link-incompatible in $(att)
{
self.link-incompatible += $(p) ;
}
}
}
@@ -139,6 +144,17 @@ class property-set
return $(self.propagated-ps) ;
}
rule link-incompatible ( )
{
if ! $(self.link-incompatible-ps)
{
self.link-incompatible-ps =
[ property-set.create $(self.link-incompatible) ] ;
}
return $(self.link-incompatible-ps) ;
}
rule run-actions ( )
{
if ! $(self.run)
@@ -181,6 +197,32 @@ class property-set
{
return [ add [ property-set.create $(properties) ] ] ;
}
rule link-incompatible-with ( ps )
{
if ! $(.li.$(ps))
{
local li1 = [ $(__name__).link-incompatible ] ;
local li2 = [ $(ps).link-incompatible ] ;
if [ set.equal $(li1) : $(li2) ]
{
.li.$(ps) = false ;
}
else
{
.li.$(ps) = true ;
}
}
if $(.li.$(ps)) = true
{
return true ;
}
else
{
return ;
}
}
# Returns all values of 'feature'.

View File

@@ -13,13 +13,10 @@ import sequence ;
import set ;
import path ;
# Refines 'properties' by overriding any elements for which a different
# value is specified in 'requirements'. If the resulting property set
# will be link-incompatible with 'properties', it is an error.
# Refines 'properties' by overriding any non-free properties
# for which a different value is specified in 'requirements'.
# Conditional requirements are just added without modification.
# On success, returns properties. On error, returns a list which first
# element is "@error" and the other elements compose the explanation
# string.
# Returns the resulting list of properties.
rule refine ( properties * : requirements * )
{
local result ;
@@ -52,16 +49,7 @@ rule refine ( properties * : requirements * )
local value = $(p:G=) ;
if $(value) != $(required-value)
{
if link-incompatible in [ feature.attributes $(p:G) ]
{
error = @error link-incompatible properties $(p) and
$(p:G)$(required-value) ;
# Cannot break, so just iterate again
}
else
{
result += $(p:G)$(required-value) ;
}
result += $(p:G)$(required-value) ;
}
else
{
@@ -525,11 +513,6 @@ local rule __test__ ( )
: $(test-space)
;
r = [ refine <toolset>gcc <rtti>off
: <rtti>on
: $(test-space) ] ;
assert.equal $(r[1]) : "@error" ;
try ;
validate <feature>value : $(test-space) ;
catch "Invalid property '<feature>value': unknown feature 'feature'." ;

View File

@@ -192,34 +192,15 @@ class project-target : abstract-target
# Generates all possible targets contained in this project.
rule generate ( property-set * )
{
# Project properties are directly imposed on all main targets.
# However, we'd need to check if this project can be build at
# all.
local xproperties = [ $(property-set).refine $(self.requirements) ] ;
local usage-requirements = [ property-set.empty ] ;
local targets ;
if $(xproperties[1]) = "@error"
for local t in [ targets-to-build ]
{
local id = [ project.attribute $(self.project) id ] ;
print.wrapped-text "warning: skipping build of project $(id:E=) at"
[ project.attribute $(self.project) location ]
"due to unsatisfied requirements." ;
print.wrapped-text "warning: explanation: " $(xproperties[2-]) ;
print.wrapped-text "warning: build-request: " $(properties) ;
print.wrapped-text "warning: requirements: " [ $(self.requirements).raw ] ;
local g = [ $(t).generate $(property-set) ] ;
usage-requirements = [ $(usage-requirements).add $(g[1]) ] ;
targets += $(g[2-]) ;
}
else
{
for local t in [ targets-to-build ]
{
local g = [ $(t).generate $(property-set) ] ;
usage-requirements = [ $(usage-requirements).add $(g[1]) ] ;
targets += $(g[2-]) ;
}
}
return $(usage-requirements) $(targets) ;
}
@@ -838,11 +819,21 @@ class basic-target : abstract-target
{
# First check if our requirements can be satisfied.
local rproperties = [ $(property-set).refine $(self.requirements) ] ;
if $(rproperties[1]) != "@error"
{
# Kluge: previously, link-incompatible alternatives were skipped
# completely. Until a better alternative selection algorithm is
# in place, treat such alternatives as having rank of zero.
# As another kluge, add 1 to all other ranks so that zero is worse that
# anything.
if [ $(rproperties).link-incompatible-with $(property-set) ]
{
return 0 ;
}
else
{
# Returns the number of properties common to requirements
# and build request.
return [ sequence.length [ set.intersection
return [ sequence.length "fake" [ set.intersection
[ $(self.requirements).base ] :
[ $(property-set).raw ] ] ] ;
}

View File

@@ -35,33 +35,25 @@ t.expect_content("bin/$toolset/debug/main-target-b.exe/b.exe",
"bin/$toolset/debug/a.obj\n"
)
# TODO: restore this test when we have new notion of link-compatibility
#t.copy("lib/Jamfile3", "lib/Jamfile")
t.copy("lib/Jamfile2", "lib/Jamfile")
expected="""error: Requirements for project at 'lib' conflict with parent's.
Explanation: link-incompatible properties <threading>single and <threading>multi
"""
t.run_build_system("--no-error-backtrace", stdout=expected, status=None)
t.copy("lib/Jamfile3", "lib/Jamfile")
t.run_build_system(status=None)
t.fail_test(find(t.stdout(), "warning: skipped build of lib/b.obj with properties") \
!= 0)
#t.run_build_system(status=None)
#t.fail_test(find(t.stdout(), "warning: skipped build of lib/b.obj with properties") \
# != 0)
# Check that project can be skipped as well
t.copy("Jamfile4", "Jamfile")
#t.copy("Jamfile4", "Jamfile")
expected="warning: skipping build of project at lib2 due to unsatisfied requirements."
t.run_build_system("rtti=on")
t.fail_test(find(t.stdout(), expected) != 0)
#expected="warning: skipping build of project at lib2 due to unsatisfied requirements."
#t.run_build_system("rtti=on")
#t.fail_test(find(t.stdout(), expected) != 0)
t.copy("lib2/Jamfile2", "lib2/Jamfile")
#t.copy("lib2/Jamfile2", "lib2/Jamfile")
expected="warning: skipping build of project /mylib at lib2 due to unsatisfied\nrequirements."
t.run_build_system("rtti=on")
t.fail_test(find(t.stdout(), expected) != 0)
#expected="warning: skipping build of project /mylib at lib2 due to unsatisfied\nrequirements."
#t.run_build_system("rtti=on")
#t.fail_test(find(t.stdout(), expected) != 0)
# We don't yet make targets depend on Jamfile, so need to start from scratch
# The following test is disabled, because of problems related to