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:
20
new/bison.jam
Normal file
20
new/bison.jam
Normal 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]) $(>)
|
||||
}
|
||||
@@ -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 ] ;
|
||||
|
||||
@@ -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 * )
|
||||
|
||||
11
new/lex.jam
11
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$(<) $(>)
|
||||
}
|
||||
@@ -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) ;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
56
new/testing.jam
Normal 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 ;
|
||||
|
||||
|
||||
@@ -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
17
new/version.jam
Normal 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 ] ;
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -26,3 +26,4 @@ import path_features
|
||||
import relative_sources
|
||||
import no_type
|
||||
import chain
|
||||
import default_build
|
||||
|
||||
20
v2/bison.jam
Normal file
20
v2/bison.jam
Normal 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]) $(>)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) ;
|
||||
|
||||
|
||||
@@ -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
17
v2/build/version.jam
Normal 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 ] ;
|
||||
}
|
||||
@@ -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 * )
|
||||
|
||||
11
v2/lex.jam
11
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$(<) $(>)
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -26,3 +26,4 @@ import path_features
|
||||
import relative_sources
|
||||
import no_type
|
||||
import chain
|
||||
import default_build
|
||||
|
||||
@@ -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
56
v2/tools/testing.jam
Normal 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 ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user