I am a newbie and struggling with understanding how to create new rules with Boost Build V2, and although I learned something from the previous email, I still have not been able to achieve what I want in the way of support for CxxTest unit testing framework.  For now, let’s just deal with the creation of test executables (set aside the automatic running that is supplied by testing.jam. 


I would like to be able to define a rule/action/generator (whatever is appropriate) to be able to support the following two scenarios:


1) Given a test suite class declaration in FooTS.h and definition in FooTS.cpp, I would like to be able use cxxtestgen.pl to create a FooTS_runner.cpp from FooTS.h (not FooTS.cxh as discussed in the previous email below).  Then I would like to create the executable by compiling and linking FooTS.cpp and FooTS_runner.cpp together.


2) I would like to be able to also create a single runner from multiple *TS.h files and link all of the pertinent files together into one larger executable.  Something like:


     cxxtestgen.pl -o global_runner.cpp Foo1TS.h Foo2TS.h ...

     CC -o global_runner Foo1TS.cpp Foo2TS.cpp ... global_runner.cpp



For Scenario #1, I started to hack the "run" rule from testing.jam, but I keep getting stuck on the generation of the *_runner.cpp file and getting all of the dependencies to come out correctly.  This is what I tried:


   actions gen-cxxtest-runner-source


      cxxtestgen.pl -o $(<) $(>)



   # I added an initial argument and changed from 'sources +' to 'sources *'

   rule run ( test-suite : sources * : args * : input-files * :

              requirements * : target-name ? : default-build * )


      gen-cxxtest-runner-source $(test_suite)_runner.cpp $(test_suite).h ;

      sources += $(test_suite).cpp $(test_suite)_runner.cpp ;


      # The rest is the same as the run rule in testing.jam



My Jamfile would contain:


   run FooTS : : : : <some CxxTest-specific requirements> ;


and I get the following message when I try to build:


   # Unable to find file or target named FooTS_runner.cpp


I am guessing that this is wrong because at the time the rule is parse it can’t find the runner.cpp.  If so, then I need help understanding how to get Boost Jam/Build to understand that the action will be fired to generate it.  Not to mention the fact that it needs to get created in the appropriate subdirectory of ./bin...


Also any advice on how to tweak the rules so that it can support scenario #2 above as well?


Thanks in advance for any help you all can give,






-----Original Message-----
From: McMillan, Scott
Sent: Wednesday, January 10, 2007 9:02 AM
To: Boost.Build developer's and user's list
Subject: RE: [Boost-build] Trying to create CxxTest support


> > generators.register-standard cxxtest.gencxx-file : CXXTEST_H : CPP ;

> ........

> > exe FooTS_runner : FooTS.cpp FooTS_runner.cxh : /* other requirements */

> ........

> >

> > Notice that I had to add the "_runner" to the cxh file so that there

> > would not be two FooTS.o files (one from FooTS.cpp and one from

> > processing FooTS.cxh and compiling the result).


> >

> > It is unsatisfying to rename the header file this way


> Try:


> generators.register-standard cxxtest.gencxx-file : CXXTEST_H : CPP(%_runner) ;


> that should append the _runner suffix to the generated CPP automatically.


That is the solution for Item 1 below.  Thanks.


> > 1) If I wanted to continue with the .cxh approach, is writing a custom

> > generator the way to process FooTS.cxh into FooTS_runner.cpp.  If so

> > could someone please help me as it is neither clear what method to

> > override (generate-targets?) nor how to do it to accomplish this task.


> You could have overriden generate-targets to append _runner to the name

> of the output target.


I tried to do this but I just don't understand the contents of the various arguments and what needs to be returned to be able to write the appropriate method.  It would be helpful to my education to see an example doing it this way (even though I prefer the solution above).


> > 2) Ultimately I would like to get back to something closer I have with

> > our current Imakefile system which was to define a new rule that took

> > FooTS as the argument (I would settle for a rule that had to take

> > FooTS.h and FooTS.cpp as arguments), generates FooTS_runner.cpp from

> > FooTS.h and compiled and linked FooTS.cpp and FooTS_runner.cpp into an

> > executable called FooTS_runner.


> Would:


>     exe FooTS_runner : FooTS.cpp FooTS.h ;


> work, as soon as _runner is automatically appended? Or you want something

> different?


I am not sure what you are asking.  I don't think that I want exactly the line above in my Jamfiles because that would imply that there would be two different behaviours in my code for the exe rule.  Note that I do build applications with the exe rule that does not require this generation of *_runner.cpp files from header files, so I am wondering how would a developer distinguish when a cxxtest application is being built and when a normal application needs to be built.  Please clarify if I am off-base here.


I think what I would prefer is a new rule that allows me to write something like:


     cxxtest_exe FooTS_runner : FooTS.cpp FooTS.h ;


and have it recognize that it is FooTS.h that needs to be used to generate the FooTS_runner.cpp file.


Just so you know where we are coming from now is that the Imake template that we use (we actually use two to distinguish between unit and performance test targets) only takes the test suite name, i.e. FooTS, and assumes that FooTS.cpp and FooTS.h exist and generate all the necessary make targets from that.