From 2ee0f0be563676205302802466093dfe0d77b85e Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 26 Sep 2003 10:22:22 +0000 Subject: [PATCH] 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] --- new/property-set.jam | 42 ++++++++++++++++++++++++++++++++++++++ new/property.jam | 25 ++++------------------- new/targets.jam | 43 ++++++++++++++++----------------------- test/project_test4.py | 34 ++++++++++++------------------- v2/build/property-set.jam | 42 ++++++++++++++++++++++++++++++++++++++ v2/build/property.jam | 25 ++++------------------- v2/build/targets.jam | 43 ++++++++++++++++----------------------- v2/test/project_test4.py | 34 ++++++++++++------------------- 8 files changed, 152 insertions(+), 136 deletions(-) diff --git a/new/property-set.jam b/new/property-set.jam index b216f20c7..09f80d316 100644 --- a/new/property-set.jam +++ b/new/property-set.jam @@ -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'. diff --git a/new/property.jam b/new/property.jam index b4ac59852..80ce019e1 100644 --- a/new/property.jam +++ b/new/property.jam @@ -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 gcc off - : on - : $(test-space) ] ; - assert.equal $(r[1]) : "@error" ; - try ; validate value : $(test-space) ; catch "Invalid property 'value': unknown feature 'feature'." ; diff --git a/new/targets.jam b/new/targets.jam index 15a15848f..ed4a50d39 100644 --- a/new/targets.jam +++ b/new/targets.jam @@ -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 ] ] ] ; } diff --git a/test/project_test4.py b/test/project_test4.py index 245e51348..968cd5d5f 100644 --- a/test/project_test4.py +++ b/test/project_test4.py @@ -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 single and 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 diff --git a/v2/build/property-set.jam b/v2/build/property-set.jam index b216f20c7..09f80d316 100644 --- a/v2/build/property-set.jam +++ b/v2/build/property-set.jam @@ -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'. diff --git a/v2/build/property.jam b/v2/build/property.jam index b4ac59852..80ce019e1 100644 --- a/v2/build/property.jam +++ b/v2/build/property.jam @@ -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 gcc off - : on - : $(test-space) ] ; - assert.equal $(r[1]) : "@error" ; - try ; validate value : $(test-space) ; catch "Invalid property 'value': unknown feature 'feature'." ; diff --git a/v2/build/targets.jam b/v2/build/targets.jam index 15a15848f..ed4a50d39 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -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 ] ] ] ; } diff --git a/v2/test/project_test4.py b/v2/test/project_test4.py index 245e51348..968cd5d5f 100644 --- a/v2/test/project_test4.py +++ b/v2/test/project_test4.py @@ -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 single and 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