JamPlus manual
Multiple Passes

Overview

Stock Jam was built as a highly efficient single pass build system where all targets must be known during the Parsing Phase. When the Updating Phase is complete, Jam assumed the build is finished and exits.

JamPlus adds a facility to enable multiple passes on the dependency graph, allowing 'unknown' dependencies to be discovered during one pass and handled in the next pass.

Usage

To initiate a second Jam pass, the QueueJamfile rule must be executed. The Jamfile to be queued may already exist, or it may be generated during the current pass or any previous pass.

Example 1

###############################################################################
# Jamfile.jam
###############################################################################
# If run without the Jambase, set the 'all' and 'clean' targets to be
# pseudotargets. If 'clean' isn't a pseudotarget, then Jam considers it
# a file. When using the 'clean' target, it will have the appearance
# of working in the multipass system, because it is always missing.
NotFile all clean ;
# Queue Pass2.jam up for the next pass.
QueueJamfile Pass2.jam ;

###############################################################################
# Pass2.jam
###############################################################################
Echo Pass 2 ;
# Use the silly syntax for writing a file to the disk in an action.
# I hope to revamp this soon.
actions WriteFile
{
^^($(1)|$(CONTENTS)) ;
}
# Insert Pass3.jam into the 'all' target. If it isn't there, the file
# won't get generated, but QueueJamfile will attempt to run it anyway,
# resulting in an error.
Depends all : Pass3.jam ;
# Set the contents of Pass3.jam. The Clean instruction is put directly
# in Pass3.jam. It can't exist before Pass3.jam exists, or Jam will
# simply report an error when trying to delete the file.
CONTENTS on Pass3.jam = "Echo Pass 3 written ;
Clean clean : Pass3.jam ;
" ;
WriteFile Pass3.jam ;
# Without the Always, any changes to CONTENTS will not be written. The
# only time Pass3.jam will be written is when it doesn't exist. An
# alternative way to do this would be to enable the dependency cache and
# UseCommandLine Pass3.jam : [ on Pass3.jam Var CONTENTS ] ;
Always Pass3.jam ;
# Queue the generated Pass3.jam. It will have been written by the time
# JamPlus' multipass Jamfile reader kicks in.
QueueJamfile Pass3.jam ;

Gotchas

Multiple passes are filled with "gotchas" or, at the very least, more complexity. Thoughts on this are listed below.

When a build is initiated and a target specified on the command line, the target must exist in the dependency graph. If the target is not in the dependency graph, the build system won't know what to do.