[jamming] Jamming with subdirectories

Russell rjshaw at iprimus.com.au
Fri Feb 7 23:31:42 PST 2003

Ingo Weinhold wrote:
 >>On Wed, 5 Feb 2003, Russell wrote:
>>I've also made it so that myprog.exe is put into the objs 
>>SubDir TOP;
>>LOCATE_TARGET = objs ;
>>MainFromObjects myprog : main.o serial.o ;
>>LOCATE on main.o = main ;
>>LOCATE on serial.o = serial ;
>>In Jamrules, i've made gcc generate myprog.exe as well as a myprog.map
>>file. However, despite trying a few different ways, i can't get myprog.map
>>to go into the 'objs' directory; it just ends up in the top directory. There
>>seems to be dozens of possible ways to do that. What would be the right way
>>that runs with the philosophy of jam?
> This depends on how your Link rule does look like now. You can for 
> instance use the LOCATE variable in the actions to construct the full 
> path of your mapfile. In general there is, AFAIK, no nice way to deal 
> nicely with generating more than one target with a rule.

After experimenting and reading http://public.perforce.com/public/jam/src/Jambase
dozens of times, i came up with a new rule that looks kool, and i thought it might
be a good one to add to jambase, if there isn't an obvious alternative that i've

I call it MvAfter (move after). You use it when an action generates an output
file that you're primarily interested in (such as the .exe output of a linker),
and another secondary file that is a side-effect from the same action (such as
a map file from a linker). MvAfter makes it easy to move the secondary file to
any directory, *after* the primary action has been done.

This is an example top-level Jamfile:

SubDir TOP ;
# generate myprog.exe and myprog.map
MainFromObjects myprog : main.o serial.o ;
# move $(TOP)/myprog.map to $(TOP)/objs/myprog.map after myprog.exe is generated.
MvAfter myprog.map : myprog.exe ;
LOCATE on main.o = main ;
LOCATE on serial.o = serial ;
SubInclude TOP main ;
SubInclude TOP serial ;

In Jamrules:

rule MvAfter
# MvAfter secondary_file_name : file_name_resulting_from_primary_action

   MakeLocate $(<) : $(LOCATE_TARGET) ;
   Depends $(<) : $(>) ;
   Depends all : $(<) ;
   Clean clean : $(<) ;

actions MvAfter
   $(MV) $(<:BS) $(<) ;

I still haven't really got the hang of where and when to use grists.
Can this code be refined? I've only tested it a few times so far.

More information about the jamming mailing list