diff --git a/new/generators.jam b/new/generators.jam index 2291ef4aa..594310830 100644 --- a/new/generators.jam +++ b/new/generators.jam @@ -217,15 +217,20 @@ rule generator ( if $(property-requirements) in $(properties-to-match) && $(feature-requirements) in $(properties-to-match:G) { - # We're only used to rank matches based on the number of - # optional properties that appear in the property set. - - # That seemed a little weak to me, so I changed it: now we - # account for the number of properties and features that - # were matched as well. -- dwa 5/6/2003 + # We only count matched optional properties to achive better + # orthogonality: + # - required properties are what is needed to generators to run + # - optional properties are used to resolve ambiguities + # + # For example, we have two generators + # - CPP->OBJ, with required property msvc + # - RC->OBJ, without required properties + # + # If we could required properties, then the first one will be + # considered more specific, and the second one will never be + # tried. return [ sequence.length - $(all-requirements) [ set.intersection [ optional-properties ] : $(properties-to-match) diff --git a/test/custom_generator.py b/test/custom_generator.py new file mode 100644 index 000000000..e48ab4781 --- /dev/null +++ b/test/custom_generator.py @@ -0,0 +1,61 @@ +#!/usr/bin/python + +# Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears in +# all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. + + +from BoostBuild import Tester, List + + +t = Tester() + +# Attempt to declare a generator for creating OBJ from RC files. +# That generator should be considered together with standard +# CPP->OBJ generators and successfully create the target. +# Since we don't have RC compiler everywhere, we fake the action. +# The resulting OBJ will be unusable, but it must be created. + +t.write("project-root.jam", """ +import rc ; +""") + +t.write("rc.jam", """ +import type ; +import generators ; +import print ; + +type.register RC : rc ; + +rule resource-compile ( targets * : sources * : properties * ) +{ + print.output $(targets[1]) ; + print.text "rc-object" ; +} + +generators.register-standard rc.resource-compile : RC : OBJ ; + +""") + +t.write("Jamfile", """ +exe hello : hello.cpp r.rc ; +""") + +t.write("hello.cpp", """ +int main() +{ + return 0; +} +""") + +t.write("r.rc", """ +""") + +t.run_build_system(status=1, stderr=None) +t.expect_content("bin/$toolset/debug/r.obj", "rc-object\n") + +t.cleanup() + + + diff --git a/test/test_all.py b/test/test_all.py index 15d59b33f..6428f0b90 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -94,6 +94,7 @@ tests = [ "project_test1", "explicit", "absolute_sources", "dependency_property", + "custom_generator", ] if os.name == 'posix': diff --git a/v2/build/generators.jam b/v2/build/generators.jam index 2291ef4aa..594310830 100644 --- a/v2/build/generators.jam +++ b/v2/build/generators.jam @@ -217,15 +217,20 @@ rule generator ( if $(property-requirements) in $(properties-to-match) && $(feature-requirements) in $(properties-to-match:G) { - # We're only used to rank matches based on the number of - # optional properties that appear in the property set. - - # That seemed a little weak to me, so I changed it: now we - # account for the number of properties and features that - # were matched as well. -- dwa 5/6/2003 + # We only count matched optional properties to achive better + # orthogonality: + # - required properties are what is needed to generators to run + # - optional properties are used to resolve ambiguities + # + # For example, we have two generators + # - CPP->OBJ, with required property msvc + # - RC->OBJ, without required properties + # + # If we could required properties, then the first one will be + # considered more specific, and the second one will never be + # tried. return [ sequence.length - $(all-requirements) [ set.intersection [ optional-properties ] : $(properties-to-match) diff --git a/v2/test/custom_generator.py b/v2/test/custom_generator.py new file mode 100644 index 000000000..e48ab4781 --- /dev/null +++ b/v2/test/custom_generator.py @@ -0,0 +1,61 @@ +#!/usr/bin/python + +# Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears in +# all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. + + +from BoostBuild import Tester, List + + +t = Tester() + +# Attempt to declare a generator for creating OBJ from RC files. +# That generator should be considered together with standard +# CPP->OBJ generators and successfully create the target. +# Since we don't have RC compiler everywhere, we fake the action. +# The resulting OBJ will be unusable, but it must be created. + +t.write("project-root.jam", """ +import rc ; +""") + +t.write("rc.jam", """ +import type ; +import generators ; +import print ; + +type.register RC : rc ; + +rule resource-compile ( targets * : sources * : properties * ) +{ + print.output $(targets[1]) ; + print.text "rc-object" ; +} + +generators.register-standard rc.resource-compile : RC : OBJ ; + +""") + +t.write("Jamfile", """ +exe hello : hello.cpp r.rc ; +""") + +t.write("hello.cpp", """ +int main() +{ + return 0; +} +""") + +t.write("r.rc", """ +""") + +t.run_build_system(status=1, stderr=None) +t.expect_content("bin/$toolset/debug/r.obj", "rc-object\n") + +t.cleanup() + + + diff --git a/v2/test/test_all.py b/v2/test/test_all.py index 15d59b33f..6428f0b90 100644 --- a/v2/test/test_all.py +++ b/v2/test/test_all.py @@ -94,6 +94,7 @@ tests = [ "project_test1", "explicit", "absolute_sources", "dependency_property", + "custom_generator", ] if os.name == 'posix':