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

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]
This commit is contained in:
Vladimir Prus
2002-10-07 13:34:14 +00:00
parent 4b5d5cc6e4
commit 4115276dec
31 changed files with 433 additions and 66 deletions

20
new/bison.jam Normal file
View File

@@ -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]) $(>)
}

View File

@@ -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) <toolset>gcc ] ;
if $(properties)
{
if ! <toolset> in $(properties:G)
{
properties = <toolset>gcc $(properties) ;
}
expanded = [ build-request.expand $(properties) ] ;
}
else
{
# If properties contain only <toolset>, the 'generate' method of
# 'abstract-target' will apply its default-build clause.
expanded = <toolset>gcc ;
}
local target-ids = [ $(build-request).get-at 1 ] ;

View File

@@ -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 * )

View File

@@ -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$(<) $(>)
}

View File

@@ -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) ;

View File

@@ -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

View File

@@ -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 <toolset>gcc : <rtti>off : $(test-space)
;
assert.result <toolset>gcc <rtti>off <rtti>off:<define>FOO
: refine <toolset>gcc : <rtti>off <rtti>off:<define>FOO
: $(test-space)
;
assert.result <toolset>gcc <variant>release <rtti>off <define>MY_RELEASE
: evaluate-conditionals <toolset>gcc <variant>release <rtti>off
<variant>release,<rtti>off:<define>MY_RELEASE
;
assert.result debug
: as-path <optimization>off <variant>debug
: $(test-space)

View File

@@ -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 <toolset>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 <toolset> 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) = <toolset>
{
# 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) ;

56
new/testing.jam Normal file
View File

@@ -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 ;

View File

@@ -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.

17
new/version.jam Normal file
View File

@@ -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 ] ;
}

View File

@@ -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:

View File

@@ -25,7 +25,7 @@ Projects:
* Project root: %(root-dir-prefix)sdir2
* Parent project: (none)
* Requirements: <include>/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: <threading>multi <include>/home/ghost/local/include
* Default build: debug
* Default build:
* Source location: %(root-dir)s
* Projects to build: dir dir2

View File

@@ -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()

View File

@@ -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")

View File

@@ -26,3 +26,4 @@ import path_features
import relative_sources
import no_type
import chain
import default_build

20
v2/bison.jam Normal file
View File

@@ -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]) $(>)
}

View File

@@ -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

View File

@@ -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 <toolset>gcc : <rtti>off : $(test-space)
;
assert.result <toolset>gcc <rtti>off <rtti>off:<define>FOO
: refine <toolset>gcc : <rtti>off <rtti>off:<define>FOO
: $(test-space)
;
assert.result <toolset>gcc <variant>release <rtti>off <define>MY_RELEASE
: evaluate-conditionals <toolset>gcc <variant>release <rtti>off
<variant>release,<rtti>off:<define>MY_RELEASE
;
assert.result debug
: as-path <optimization>off <variant>debug
: $(test-space)

View File

@@ -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 <toolset>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 <toolset> 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) = <toolset>
{
# 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) ;

View File

@@ -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.

17
v2/build/version.jam Normal file
View File

@@ -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 ] ;
}

View File

@@ -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 * )

View File

@@ -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$(<) $(>)
}

View File

@@ -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:

View File

@@ -25,7 +25,7 @@ Projects:
* Project root: %(root-dir-prefix)sdir2
* Parent project: (none)
* Requirements: <include>/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: <threading>multi <include>/home/ghost/local/include
* Default build: debug
* Default build:
* Source location: %(root-dir)s
* Projects to build: dir dir2

View File

@@ -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()

View File

@@ -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")

View File

@@ -26,3 +26,4 @@ import path_features
import relative_sources
import no_type
import chain
import default_build

View File

@@ -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) ;

56
v2/tools/testing.jam Normal file
View File

@@ -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 ;