From 4115276dec781ead96d146da4d8bb7da90c00fe9 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Mon, 7 Oct 2002 13:34:14 +0000 Subject: [PATCH] Sundry improvements: Bison and lex support. unit-test rule --version option default build really works * new/build-system.jam: Bugfixes. Added "--version" option. * new/project.jam: If default-build is not specifies, don't stick "debug". * new/property.jam (evaluate-conditionals): New rule. * new/targets.jam (basic-target.generate): Evalute conditional properties. * test/BoostBuild.py (Tester.maybe_do_diff): New method. (Tester.run_build_system): Call the above method when appropriate. [SVN r15771] --- new/bison.jam | 20 ++++++++++++++ new/build-system.jam | 29 +++++++++++++++++++-- new/gcc.jam | 2 +- new/lex.jam | 11 +++++++- new/make.jam | 2 +- new/project.jam | 14 +++++----- new/property.jam | 56 +++++++++++++++++++++++++++++++++++++--- new/targets.jam | 27 ++++++++++--------- new/testing.jam | 56 ++++++++++++++++++++++++++++++++++++++++ new/type.jam | 2 +- new/version.jam | 17 ++++++++++++ test/BoostBuild.py | 18 +++++++++++++ test/project_test1.py | 4 +-- test/project_test3.py | 1 - test/project_test4.py | 4 +-- test/test_all.py | 1 + v2/bison.jam | 20 ++++++++++++++ v2/build/project.jam | 14 +++++----- v2/build/property.jam | 56 +++++++++++++++++++++++++++++++++++++--- v2/build/targets.jam | 27 ++++++++++--------- v2/build/type.jam | 2 +- v2/build/version.jam | 17 ++++++++++++ v2/gcc.jam | 2 +- v2/lex.jam | 11 +++++++- v2/test/BoostBuild.py | 18 +++++++++++++ v2/test/project_test1.py | 4 +-- v2/test/project_test3.py | 1 - v2/test/project_test4.py | 4 +-- v2/test/test_all.py | 1 + v2/tools/make.jam | 2 +- v2/tools/testing.jam | 56 ++++++++++++++++++++++++++++++++++++++++ 31 files changed, 433 insertions(+), 66 deletions(-) create mode 100644 new/bison.jam create mode 100644 new/testing.jam create mode 100644 new/version.jam create mode 100644 v2/bison.jam create mode 100644 v2/build/version.jam create mode 100644 v2/tools/testing.jam diff --git a/new/bison.jam b/new/bison.jam new file mode 100644 index 000000000..4a7c2453e --- /dev/null +++ b/new/bison.jam @@ -0,0 +1,20 @@ + +import generators ; + +feature.feature bison.prefix : : free ; +type.register Y : y ; +generators.register-standard bison.bison : Y : C H ; + +rule bison ( dst dst_header : src : properties * ) +{ + local r = [ property.select bison.prefix : $(properties) ] ; + if $(r) + { + PREFIX_OPT on $(<) = -p $(r:G=) ; + } +} + +actions bison +{ + bison $(PREFIX_OPT) -d -o $(<[1]) $(>) +} \ No newline at end of file diff --git a/new/build-system.jam b/new/build-system.jam index a41bb0060..96b8a6957 100644 --- a/new/build-system.jam +++ b/new/build-system.jam @@ -11,10 +11,22 @@ import build-request ; import builtin ; import make ; +import version ; + import site-config ; import user-config ; -current-project = [ project.load "." ] ; +if --version in [ modules.peek : ARGV ] +{ + version.print ; + EXIT ; +} + +# We always load project in "." so that 'use-project' directives has +# any chance of been seen. Otherwise, we won't be able to refer to +# subprojects using target ids. +project.load "." ; + if [ MATCH (--dump-projects) : [ modules.peek : ARGV ] ] { project-root.print ; @@ -26,7 +38,20 @@ properties = [ $(build-request).get-at 2 ] ; # For the time being, just stick toolset to the build request. We'd need to # find a way to select default toolset collection and a method to override # that from command line -expanded = [ build-request.expand $(properties) gcc ] ; +if $(properties) +{ + if ! in $(properties:G) + { + properties = gcc $(properties) ; + } + expanded = [ build-request.expand $(properties) ] ; +} +else +{ + # If properties contain only , the 'generate' method of + # 'abstract-target' will apply its default-build clause. + expanded = gcc ; +} local target-ids = [ $(build-request).get-at 1 ] ; diff --git a/new/gcc.jam b/new/gcc.jam index 024be9b64..371f25252 100644 --- a/new/gcc.jam +++ b/new/gcc.jam @@ -36,7 +36,7 @@ rule compile ( target : sources * : property-set * ) actions compile { - g++ $(OPTIONS) -c -o $(<) $(>) + g++ -ftemplate-depth-100 $(OPTIONS) -c -o $(<) $(>) } rule link ( target : sources * : property-set * ) diff --git a/new/lex.jam b/new/lex.jam index f573994ec..f766bae27 100644 --- a/new/lex.jam +++ b/new/lex.jam @@ -1,6 +1,10 @@ import type ; import generators ; +import feature ; +import property ; + +feature.feature flex.prefix : : free ; type.register LEX : l ; @@ -8,9 +12,14 @@ generators.register-standard lex.lex : LEX : C ; rule lex ( target : source : properties * ) { + local r = [ property.select flex.prefix : $(properties) ] ; + if $(r) + { + PREFIX on $(<) = $(r:G=) ; + } } actions lex { - flex -o$(<) $(>) + flex -P$(PREFIX) -o$(<) $(>) } \ No newline at end of file diff --git a/new/make.jam b/new/make.jam index 77a963f2d..16bb9ee4a 100644 --- a/new/make.jam +++ b/new/make.jam @@ -14,7 +14,7 @@ import type : type ; import regex ; rule make-target-class ( name : project : sources * : requirements * - : make-rule + : default-build ) + : make-rule + : default-build * ) { basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements) : $(default-build) ; diff --git a/new/project.jam b/new/project.jam index ac882f37f..cd023b3c6 100644 --- a/new/project.jam +++ b/new/project.jam @@ -115,7 +115,11 @@ rule lookup-with-load ( id : current-location ) if ! $(location) { # Try to load the project at the specified location - location = [ MATCH (.*)@(.*) : $(project-id) ] ; + location = [ MATCH (.*)@(.*) : $(id) ] ; + if ! $(location) + { + location = "." ; + } location = [ path.root $(location[1]) $(current-location) ] ; if [ find-jamfile $(location) ] { @@ -216,8 +220,8 @@ rule find-target ( id : current-location ) else if $(explicit) { print.wrapped-text - "The target id" $(id) " specified by project at" $(current-location) - "is invalid" ; + "The target id" $(id) ",specified by project at" $(current-location) + "is invalid (missing 'use-project'?)" ; EXIT ; } } @@ -378,10 +382,6 @@ local rule initialize ( $(attributes).set requirements : [ $(pattributes).get requirements ] : exact ; } - else - { - $(attributes).set default-build : debug ; - } } # Associate the given id with the given location diff --git a/new/property.jam b/new/property.jam index 55d418659..7b9c6a2c7 100644 --- a/new/property.jam +++ b/new/property.jam @@ -11,6 +11,7 @@ import errors : error ; # 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. +# 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. @@ -20,14 +21,16 @@ rule refine ( properties * : requirements * : feature-space ? ) local result ; local error ; - - + # All the elements of requirements should be present in the result # Record them so that we can handle 'properties'. for local r in $(requirements) { - # Note: cannot use local here, so take an ugly name - __require__$(r:G) = $(r:G=) ; + if ! [ MATCH (:) : $(r) ] + { + # Note: cannot use local here, so take an ugly name + __require__$(r:G) = $(r:G=) ; + } } for local p in $(properties) @@ -84,6 +87,41 @@ rule refine ( properties * : requirements * : feature-space ? ) } } +# Removes all conditional properties which conditions are not met +# For those with met conditions, removes the condition. +rule evaluate-conditionals ( properties * ) +{ + local base ; + local conditionals ; + for local p in $(properties) + { + if [ MATCH (:) : $(p) ] + { + conditionals += $(p) ; + } + else + { + base += $(p) ; + } + } + + local result = $(base) ; + for local p in $(conditionals) + { + # Separate condition and property + local s = [ MATCH (.*):(.*) : $(p) ] ; + # Split condition into individual properties + local c = [ regex.split $(s[1]) "," ] ; + # Evaluate condition + if $(c) in $(base) + { + result += $(s[2]) ; + } + } + return $(result) ; +} + + # Helper for as-path, below. Orders properties with the implicit ones # first, and within the two sections in alphabetical order of feature # name. @@ -307,6 +345,16 @@ local rule __test__ ( ) : refine gcc : off : $(test-space) ; + assert.result gcc off off:FOO + : refine gcc : off off:FOO + : $(test-space) + ; + + assert.result gcc release off MY_RELEASE + : evaluate-conditionals gcc release off + release,off:MY_RELEASE + ; + assert.result debug : as-path off debug : $(test-space) diff --git a/new/targets.jam b/new/targets.jam index 3473f7d91..3eb0c3ea3 100644 --- a/new/targets.jam +++ b/new/targets.jam @@ -70,6 +70,9 @@ rule abstract-target ( name # name of the target in Jamfile # of some problem returns a list with "@error" as the first element # and explanation in all others. (CONSIDER: need some utilities for # this method of error reporting? 'is-error'?) + # + # If 'properties' are empty or consist of lonely xxx, + # uses default set(s) of properties. rule generate ( properties * ) { errors.error "method should be defined in derived classes" ; @@ -280,11 +283,10 @@ rule main-target ( name : project ) # allowed to be propagated. local ref = [ project.attribute $(self.project) requirements ] $(properties) ; + ref = [ property.refine $(properties) : $(ref) ] ; + ref = [ property.evaluate-conditionals $(ref) ] ; ref = [ property.take free : [ property.remove incidental : $(ref) ] ] ; - local pr = [ property.take free : [ property.remove incidental : - [ project.attribute $(self.project) requirements ] ] ] ; - # Process all vtargets that will be created if this main target # is created. local all-targets = @@ -334,21 +336,20 @@ rule basic-target ( name : project self.requirements = $(requirements) ; self.default-build = $(default-build) ; - # Applies default-build if 'properties' are empty. + # Applies default-build if 'properties' are empty or + # have only single element. # Generates sources. Calls 'construct' # This method should not be overriden. # - # Note: historical perspectives of this rule are not clear.... - # since generators will be allowed to change requirements as they - # search from targets to sources, we won't be able to call - # generate on sources right here, because we don't know properties - # that should be used. rule generate ( properties * ) { - if ! $(properties) + if ! $(properties) || $(properties:G) = { # CONSIDER: I'm really not sure if this is correct... - properties = [ build-request.expand $(self.default-build) ] ; + # FIXME: as in 'build-system' we stick default toolset + properties = [ build-request.expand $(properties) + $(self.default-build) ] ; + local result = ; for local p in $(properties) { @@ -368,6 +369,8 @@ rule basic-target ( name : project local rproperties = [ property.refine $(properties) : $(self.requirements) ] ; + rproperties = [ property.evaluate-conditionals $(rproperties) ] ; + if $(rproperties[1]) != "@error" { # TODO: issue a warning when requirements change properties, but @@ -508,7 +511,7 @@ rule typed-target ( name : project : type : sources * : requirements * : default-build * ) { basic-target.__init__ $(name) : $(project) - : $(sources) : $(requirements) : $(defailt-build) ; + : $(sources) : $(requirements) : $(default-build) ; self.type = $(type) ; diff --git a/new/testing.jam b/new/testing.jam new file mode 100644 index 000000000..af0605730 --- /dev/null +++ b/new/testing.jam @@ -0,0 +1,56 @@ +# Copyright (C) Vladimir Prus 2002. 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. + +# Testing support. + +import targets ; +import class : class new ; +import property ; + +rule unit-test-target-class ( name : project : sources * : requirements * + : default-build ) +{ + typed-target.__init__ $(name) : $(project) : EXE : $(sources) + : $(requirements) : $(default-build) ; + + rule construct ( source-targets * : properties * ) + { + local result = + [ typed-target.construct $(source-targets) : $(properties) ] ; + local exe = $(result[1]) ; + local timestamp = [ new virtual-target $(self.name) : : $(self.project) + : [ $(exe).subvariant ] ] ; + $(timestamp).suffix "passed" ; + + local a = [ new action $(timestamp) : $(exe) : testing.run ] ; + $(timestamp).action $(a) ; + return $(timestamp) ; + } +} + +class unit-test-target-class : typed-target ; + +rule run +{ +} + +actions run +{ + $(>) && touch $(<) +} + + + +rule unit-test ( target-name : sources * : requirements * ) +{ + # TODO: what to do with default build? + targets.main-target-alternative + $(target-name) [ CALLER_MODULE ] unit-test-target-class : 2 : 3 + : $(sources) : $(requirements) : $(default-build) ; +} + +IMPORT $(__name__) : unit-test : : unit-test ; + + diff --git a/new/type.jam b/new/type.jam index 7b080f7a0..af2fdc0b3 100644 --- a/new/type.jam +++ b/new/type.jam @@ -102,7 +102,7 @@ rule type ( suffix ) } -rule main-target-rule ( name : sources * : requirements * : default-build ? ) +rule main-target-rule ( name : sources * : requirements * : default-build * ) { # First find requuired target type, which is equal to the name used to # invoke us. diff --git a/new/version.jam b/new/version.jam new file mode 100644 index 000000000..1f00b34aa --- /dev/null +++ b/new/version.jam @@ -0,0 +1,17 @@ + +rule boost-build ( ) +{ + return "V2 (Milestone 2)" ; +} +rule jam ( ) +{ + local v = [ modules.peek : JAM_VERSION ] ; + return $(v:J=.) ; +} + + +rule print ( ) +{ + ECHO "Boost.Build" [ boost-build ] ; + ECHO "Boost.Jam" [ jam ] ; +} diff --git a/test/BoostBuild.py b/test/BoostBuild.py index 4d7b33048..65dc02a00 100644 --- a/test/BoostBuild.py +++ b/test/BoostBuild.py @@ -8,6 +8,7 @@ import shutil import string import types import time +import tempfile # # FIXME: this is copy-pasted from TestSCons.py @@ -166,6 +167,7 @@ class Tester(TestCmd.TestCmd): if stderr: print "STDERR ===================" print stderr + self.maybe_do_diff(self.stdout(), stdout) self.fail_test(1) if not stderr is None and not match(self.stderr(), stderr): @@ -175,6 +177,7 @@ class Tester(TestCmd.TestCmd): print stderr print "Actual STDERR ============" print self.stderr() + self.maybe_do_diff(self.stderr(), stderr) self.fail_test(1) self.tree = build_tree(self.workdir) @@ -298,6 +301,21 @@ class Tester(TestCmd.TestCmd): print actual self.fail_test(1) + def maybe_do_diff(self, actual, expected): + if os.environ.has_key("DO_DIFF") and os.environ["DO_DIFF"] != '': + + e = tempfile.mktemp("expected") + a = tempfile.mktemp("actual") + open(e, "w").write(expected) + open(a, "w").write(actual) + print "DIFFERENCE" + if os.system("diff -u " + e + " " + a): + print "Unable to compute difference" + os.unlink(e) + os.unlink(a) + else: + print "Set environmental variable 'DO_DIFF' to examine difference." + # Helpers def mul(self, *arguments): if len(arguments) == 0: diff --git a/test/project_test1.py b/test/project_test1.py index 3f494c6d6..d3b647bc7 100644 --- a/test/project_test1.py +++ b/test/project_test1.py @@ -25,7 +25,7 @@ Projects: * Project root: %(root-dir-prefix)sdir2 * Parent project: (none) * Requirements: /home/ghost/build/boost-cvs -* Default build: debug +* Default build: * Source location: %(root-dir-prefix)sdir2 * Projects to build: @@ -42,7 +42,7 @@ Projects: * Project root: %(root-dir)s * Parent project: (none) * Requirements: multi /home/ghost/local/include -* Default build: debug +* Default build: * Source location: %(root-dir)s * Projects to build: dir dir2 diff --git a/test/project_test3.py b/test/project_test3.py index 7231638d2..602eebb88 100644 --- a/test/project_test3.py +++ b/test/project_test3.py @@ -15,7 +15,6 @@ Did not find a project-root.jam file there or in any of its parent directories. Please consult the documentation at 'http://www.boost.org'. """) - t.set_tree("project-test3") t.run_build_system() diff --git a/test/project_test4.py b/test/project_test4.py index dfff7eecc..f8ed60f4c 100644 --- a/test/project_test4.py +++ b/test/project_test4.py @@ -61,14 +61,14 @@ t.copy("Jamfile4", "Jamfile") expected="""warning: skipping build of project at lib2 """ -t.run_build_system(stdout=expected, status=None) +t.run_build_system("rtti=on", stdout=expected, status=None) t.copy("lib2/Jamfile2", "lib2/Jamfile") expected="""warning: skipping build of project /mylib at lib2 """ -t.run_build_system(stdout=expected, status=None) +t.run_build_system("rtti=on", stdout=expected, status=None) # We don't yet make targets depend on Jamfile, so need to start from scratch t.set_tree("project-test4") diff --git a/test/test_all.py b/test/test_all.py index ab9059b68..3534024ed 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -26,3 +26,4 @@ import path_features import relative_sources import no_type import chain +import default_build diff --git a/v2/bison.jam b/v2/bison.jam new file mode 100644 index 000000000..4a7c2453e --- /dev/null +++ b/v2/bison.jam @@ -0,0 +1,20 @@ + +import generators ; + +feature.feature bison.prefix : : free ; +type.register Y : y ; +generators.register-standard bison.bison : Y : C H ; + +rule bison ( dst dst_header : src : properties * ) +{ + local r = [ property.select bison.prefix : $(properties) ] ; + if $(r) + { + PREFIX_OPT on $(<) = -p $(r:G=) ; + } +} + +actions bison +{ + bison $(PREFIX_OPT) -d -o $(<[1]) $(>) +} \ No newline at end of file diff --git a/v2/build/project.jam b/v2/build/project.jam index ac882f37f..cd023b3c6 100644 --- a/v2/build/project.jam +++ b/v2/build/project.jam @@ -115,7 +115,11 @@ rule lookup-with-load ( id : current-location ) if ! $(location) { # Try to load the project at the specified location - location = [ MATCH (.*)@(.*) : $(project-id) ] ; + location = [ MATCH (.*)@(.*) : $(id) ] ; + if ! $(location) + { + location = "." ; + } location = [ path.root $(location[1]) $(current-location) ] ; if [ find-jamfile $(location) ] { @@ -216,8 +220,8 @@ rule find-target ( id : current-location ) else if $(explicit) { print.wrapped-text - "The target id" $(id) " specified by project at" $(current-location) - "is invalid" ; + "The target id" $(id) ",specified by project at" $(current-location) + "is invalid (missing 'use-project'?)" ; EXIT ; } } @@ -378,10 +382,6 @@ local rule initialize ( $(attributes).set requirements : [ $(pattributes).get requirements ] : exact ; } - else - { - $(attributes).set default-build : debug ; - } } # Associate the given id with the given location diff --git a/v2/build/property.jam b/v2/build/property.jam index 55d418659..7b9c6a2c7 100644 --- a/v2/build/property.jam +++ b/v2/build/property.jam @@ -11,6 +11,7 @@ import errors : error ; # 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. +# 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. @@ -20,14 +21,16 @@ rule refine ( properties * : requirements * : feature-space ? ) local result ; local error ; - - + # All the elements of requirements should be present in the result # Record them so that we can handle 'properties'. for local r in $(requirements) { - # Note: cannot use local here, so take an ugly name - __require__$(r:G) = $(r:G=) ; + if ! [ MATCH (:) : $(r) ] + { + # Note: cannot use local here, so take an ugly name + __require__$(r:G) = $(r:G=) ; + } } for local p in $(properties) @@ -84,6 +87,41 @@ rule refine ( properties * : requirements * : feature-space ? ) } } +# Removes all conditional properties which conditions are not met +# For those with met conditions, removes the condition. +rule evaluate-conditionals ( properties * ) +{ + local base ; + local conditionals ; + for local p in $(properties) + { + if [ MATCH (:) : $(p) ] + { + conditionals += $(p) ; + } + else + { + base += $(p) ; + } + } + + local result = $(base) ; + for local p in $(conditionals) + { + # Separate condition and property + local s = [ MATCH (.*):(.*) : $(p) ] ; + # Split condition into individual properties + local c = [ regex.split $(s[1]) "," ] ; + # Evaluate condition + if $(c) in $(base) + { + result += $(s[2]) ; + } + } + return $(result) ; +} + + # Helper for as-path, below. Orders properties with the implicit ones # first, and within the two sections in alphabetical order of feature # name. @@ -307,6 +345,16 @@ local rule __test__ ( ) : refine gcc : off : $(test-space) ; + assert.result gcc off off:FOO + : refine gcc : off off:FOO + : $(test-space) + ; + + assert.result gcc release off MY_RELEASE + : evaluate-conditionals gcc release off + release,off:MY_RELEASE + ; + assert.result debug : as-path off debug : $(test-space) diff --git a/v2/build/targets.jam b/v2/build/targets.jam index 3473f7d91..3eb0c3ea3 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -70,6 +70,9 @@ rule abstract-target ( name # name of the target in Jamfile # of some problem returns a list with "@error" as the first element # and explanation in all others. (CONSIDER: need some utilities for # this method of error reporting? 'is-error'?) + # + # If 'properties' are empty or consist of lonely xxx, + # uses default set(s) of properties. rule generate ( properties * ) { errors.error "method should be defined in derived classes" ; @@ -280,11 +283,10 @@ rule main-target ( name : project ) # allowed to be propagated. local ref = [ project.attribute $(self.project) requirements ] $(properties) ; + ref = [ property.refine $(properties) : $(ref) ] ; + ref = [ property.evaluate-conditionals $(ref) ] ; ref = [ property.take free : [ property.remove incidental : $(ref) ] ] ; - local pr = [ property.take free : [ property.remove incidental : - [ project.attribute $(self.project) requirements ] ] ] ; - # Process all vtargets that will be created if this main target # is created. local all-targets = @@ -334,21 +336,20 @@ rule basic-target ( name : project self.requirements = $(requirements) ; self.default-build = $(default-build) ; - # Applies default-build if 'properties' are empty. + # Applies default-build if 'properties' are empty or + # have only single element. # Generates sources. Calls 'construct' # This method should not be overriden. # - # Note: historical perspectives of this rule are not clear.... - # since generators will be allowed to change requirements as they - # search from targets to sources, we won't be able to call - # generate on sources right here, because we don't know properties - # that should be used. rule generate ( properties * ) { - if ! $(properties) + if ! $(properties) || $(properties:G) = { # CONSIDER: I'm really not sure if this is correct... - properties = [ build-request.expand $(self.default-build) ] ; + # FIXME: as in 'build-system' we stick default toolset + properties = [ build-request.expand $(properties) + $(self.default-build) ] ; + local result = ; for local p in $(properties) { @@ -368,6 +369,8 @@ rule basic-target ( name : project local rproperties = [ property.refine $(properties) : $(self.requirements) ] ; + rproperties = [ property.evaluate-conditionals $(rproperties) ] ; + if $(rproperties[1]) != "@error" { # TODO: issue a warning when requirements change properties, but @@ -508,7 +511,7 @@ rule typed-target ( name : project : type : sources * : requirements * : default-build * ) { basic-target.__init__ $(name) : $(project) - : $(sources) : $(requirements) : $(defailt-build) ; + : $(sources) : $(requirements) : $(default-build) ; self.type = $(type) ; diff --git a/v2/build/type.jam b/v2/build/type.jam index 7b080f7a0..af2fdc0b3 100644 --- a/v2/build/type.jam +++ b/v2/build/type.jam @@ -102,7 +102,7 @@ rule type ( suffix ) } -rule main-target-rule ( name : sources * : requirements * : default-build ? ) +rule main-target-rule ( name : sources * : requirements * : default-build * ) { # First find requuired target type, which is equal to the name used to # invoke us. diff --git a/v2/build/version.jam b/v2/build/version.jam new file mode 100644 index 000000000..1f00b34aa --- /dev/null +++ b/v2/build/version.jam @@ -0,0 +1,17 @@ + +rule boost-build ( ) +{ + return "V2 (Milestone 2)" ; +} +rule jam ( ) +{ + local v = [ modules.peek : JAM_VERSION ] ; + return $(v:J=.) ; +} + + +rule print ( ) +{ + ECHO "Boost.Build" [ boost-build ] ; + ECHO "Boost.Jam" [ jam ] ; +} diff --git a/v2/gcc.jam b/v2/gcc.jam index 024be9b64..371f25252 100644 --- a/v2/gcc.jam +++ b/v2/gcc.jam @@ -36,7 +36,7 @@ rule compile ( target : sources * : property-set * ) actions compile { - g++ $(OPTIONS) -c -o $(<) $(>) + g++ -ftemplate-depth-100 $(OPTIONS) -c -o $(<) $(>) } rule link ( target : sources * : property-set * ) diff --git a/v2/lex.jam b/v2/lex.jam index f573994ec..f766bae27 100644 --- a/v2/lex.jam +++ b/v2/lex.jam @@ -1,6 +1,10 @@ import type ; import generators ; +import feature ; +import property ; + +feature.feature flex.prefix : : free ; type.register LEX : l ; @@ -8,9 +12,14 @@ generators.register-standard lex.lex : LEX : C ; rule lex ( target : source : properties * ) { + local r = [ property.select flex.prefix : $(properties) ] ; + if $(r) + { + PREFIX on $(<) = $(r:G=) ; + } } actions lex { - flex -o$(<) $(>) + flex -P$(PREFIX) -o$(<) $(>) } \ No newline at end of file diff --git a/v2/test/BoostBuild.py b/v2/test/BoostBuild.py index 4d7b33048..65dc02a00 100644 --- a/v2/test/BoostBuild.py +++ b/v2/test/BoostBuild.py @@ -8,6 +8,7 @@ import shutil import string import types import time +import tempfile # # FIXME: this is copy-pasted from TestSCons.py @@ -166,6 +167,7 @@ class Tester(TestCmd.TestCmd): if stderr: print "STDERR ===================" print stderr + self.maybe_do_diff(self.stdout(), stdout) self.fail_test(1) if not stderr is None and not match(self.stderr(), stderr): @@ -175,6 +177,7 @@ class Tester(TestCmd.TestCmd): print stderr print "Actual STDERR ============" print self.stderr() + self.maybe_do_diff(self.stderr(), stderr) self.fail_test(1) self.tree = build_tree(self.workdir) @@ -298,6 +301,21 @@ class Tester(TestCmd.TestCmd): print actual self.fail_test(1) + def maybe_do_diff(self, actual, expected): + if os.environ.has_key("DO_DIFF") and os.environ["DO_DIFF"] != '': + + e = tempfile.mktemp("expected") + a = tempfile.mktemp("actual") + open(e, "w").write(expected) + open(a, "w").write(actual) + print "DIFFERENCE" + if os.system("diff -u " + e + " " + a): + print "Unable to compute difference" + os.unlink(e) + os.unlink(a) + else: + print "Set environmental variable 'DO_DIFF' to examine difference." + # Helpers def mul(self, *arguments): if len(arguments) == 0: diff --git a/v2/test/project_test1.py b/v2/test/project_test1.py index 3f494c6d6..d3b647bc7 100644 --- a/v2/test/project_test1.py +++ b/v2/test/project_test1.py @@ -25,7 +25,7 @@ Projects: * Project root: %(root-dir-prefix)sdir2 * Parent project: (none) * Requirements: /home/ghost/build/boost-cvs -* Default build: debug +* Default build: * Source location: %(root-dir-prefix)sdir2 * Projects to build: @@ -42,7 +42,7 @@ Projects: * Project root: %(root-dir)s * Parent project: (none) * Requirements: multi /home/ghost/local/include -* Default build: debug +* Default build: * Source location: %(root-dir)s * Projects to build: dir dir2 diff --git a/v2/test/project_test3.py b/v2/test/project_test3.py index 7231638d2..602eebb88 100644 --- a/v2/test/project_test3.py +++ b/v2/test/project_test3.py @@ -15,7 +15,6 @@ Did not find a project-root.jam file there or in any of its parent directories. Please consult the documentation at 'http://www.boost.org'. """) - t.set_tree("project-test3") t.run_build_system() diff --git a/v2/test/project_test4.py b/v2/test/project_test4.py index dfff7eecc..f8ed60f4c 100644 --- a/v2/test/project_test4.py +++ b/v2/test/project_test4.py @@ -61,14 +61,14 @@ t.copy("Jamfile4", "Jamfile") expected="""warning: skipping build of project at lib2 """ -t.run_build_system(stdout=expected, status=None) +t.run_build_system("rtti=on", stdout=expected, status=None) t.copy("lib2/Jamfile2", "lib2/Jamfile") expected="""warning: skipping build of project /mylib at lib2 """ -t.run_build_system(stdout=expected, status=None) +t.run_build_system("rtti=on", stdout=expected, status=None) # We don't yet make targets depend on Jamfile, so need to start from scratch t.set_tree("project-test4") diff --git a/v2/test/test_all.py b/v2/test/test_all.py index ab9059b68..3534024ed 100644 --- a/v2/test/test_all.py +++ b/v2/test/test_all.py @@ -26,3 +26,4 @@ import path_features import relative_sources import no_type import chain +import default_build diff --git a/v2/tools/make.jam b/v2/tools/make.jam index 77a963f2d..16bb9ee4a 100644 --- a/v2/tools/make.jam +++ b/v2/tools/make.jam @@ -14,7 +14,7 @@ import type : type ; import regex ; rule make-target-class ( name : project : sources * : requirements * - : make-rule + : default-build ) + : make-rule + : default-build * ) { basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements) : $(default-build) ; diff --git a/v2/tools/testing.jam b/v2/tools/testing.jam new file mode 100644 index 000000000..af0605730 --- /dev/null +++ b/v2/tools/testing.jam @@ -0,0 +1,56 @@ +# Copyright (C) Vladimir Prus 2002. 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. + +# Testing support. + +import targets ; +import class : class new ; +import property ; + +rule unit-test-target-class ( name : project : sources * : requirements * + : default-build ) +{ + typed-target.__init__ $(name) : $(project) : EXE : $(sources) + : $(requirements) : $(default-build) ; + + rule construct ( source-targets * : properties * ) + { + local result = + [ typed-target.construct $(source-targets) : $(properties) ] ; + local exe = $(result[1]) ; + local timestamp = [ new virtual-target $(self.name) : : $(self.project) + : [ $(exe).subvariant ] ] ; + $(timestamp).suffix "passed" ; + + local a = [ new action $(timestamp) : $(exe) : testing.run ] ; + $(timestamp).action $(a) ; + return $(timestamp) ; + } +} + +class unit-test-target-class : typed-target ; + +rule run +{ +} + +actions run +{ + $(>) && touch $(<) +} + + + +rule unit-test ( target-name : sources * : requirements * ) +{ + # TODO: what to do with default build? + targets.main-target-alternative + $(target-name) [ CALLER_MODULE ] unit-test-target-class : 2 : 3 + : $(sources) : $(requirements) : $(default-build) ; +} + +IMPORT $(__name__) : unit-test : : unit-test ; + +