Boost logo

Boost-Build :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-01-12 19:10:57


----- Original Message -----
From: "Brad King" <brad.king_at_[hidden]>

> David,
>
> I took some time today to learn a bit more about Jam. I've come up with a
> sample implementation for the multiple testing back-ends approach
> suggested by Doug. I'm interested in your thoughts on the attached file.
>
> Each of the two dummy testing back-ends uses a different "mapping"
> approach to be able to have targets that don't conflict with the other
> testing system. Neither one is very pretty. Do you have a suggestion for
> an alternative?
>
> # Try running this with one of the following commands:
> #
> # jam list-tests
> # jam invoke-foo
> # jam invoke-bar
> #

If you're going to use the module feature (good idea), it would also be a
good idea to take advantage of the facilities in the tools/build/new
subdirectory. Just set your BOOST_BUILD_PATH to find tools/build/new before
tools/build. Then each module is a separate .jam file and you use the
'import' (lower-case) rule to load them and manipulate namespaces.

> # Module "test" provides commands used by developers to describe tests.
> # This is the testing front-end.
> module test
> {
> # Testing commands just copy their arguments for later use by a
back-end.
> rule compile # name : sources : requirements
> {
> gTEST_COMPILE_NAMES = $(gTEST_COMPILE_NAMES) $(<) ;
> gTEST_COMPILE_SOURCES($(<)) = $(2) ;
> gTEST_COMPILE_REQUIREMENTS($(<)) = $(3) ;
> }

Try this approach instead:

module local test-names ;
rule compile ( name : sources + : requirements * )
{
test-names += $(name) ;
module local $(name).sources = $(sources) ;
module local $(name).requirements = $(requirements) ;
}

actions quietly list
{
echo $(test-names) ;
}

# I had a special "target" module for this kind of functionality.
# It would be the interface to all targets. Also thought about
# Using the prototype class system (tools/build/new/class.jam) for
# targets, where each target is an instance.

rule sources ( target ) { return $(target).sources ; }
rule requirements ( target ) { return $(target).requirements ; }

>
# --------------------------------------------------------------------------

--
> # Example invocations. Can be done before any test actions are defined.
> test.compile test1 : source1 ;
> test.compile test2 : source2 : reqs2 ;
>
>
# --------------------------------------------------------------------------
--
> # Module "foo" provides one testing system.
> module foo
> {
> actions quietly foo-actions
> {
> echo foo $(gFOO_COMPILE_NAMES($(<))) : $(gFOO_COMPILE_SOURCES($(<)))
> }
>
> rule invoke
> {
> for local t in $(gTEST_COMPILE_NAMES)
> {
> DEPENDS $(<) : foo_$(t) ;
> gFOO_COMPILE_NAMES(foo_$(t)) = $(t) ;
> gFOO_COMPILE_SOURCES(foo_$(t)) = $(gTEST_COMPILE_SOURCES($(t))) ;
> gFOO_COMPILE_REQUIREMENTS(foo_$(t)) =
$(gTEST_COMPILE_REQUIREMENTS($(t))) ;
> foo-actions foo_$(t) ;
> }
> }
> }
>
> # Let user choose the "foo" testing system with "jam invoke-foo".
> foo.invoke invoke-foo ;
>
>
# --------------------------------------------------------------------------
--
> # Module "bar" provides another, separate testing system.
> module bar
> {
> actions quietly bar-actions
> {
> echo bar $(gBAR_MAP($(<))) :
$(gTEST_COMPILE_SOURCES($(gBAR_MAP($(<)))))
> }
>
> rule invoke
> {
> for local t in $(gTEST_COMPILE_NAMES)
> {
> DEPENDS $(<) : bar_$(t) ;
> gBAR_MAP(bar_$(t)) = $(t) ;
> bar-actions bar_$(t) ;
> }
> }
> }
>
> # Let user choose the "bar" testing system with "jam invoke-bar".
> bar.invoke invoke-bar ;
I like your approach overall. This is compatible with the "declarative
Jamfile" idea we've been discussing on jamboost.
-Dave
 

Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk