# jam

The Jam/MR Executable Program
Jam/MR 2.2

## USAGE

    	jam [ -a ] [ -n ] [ -v ] [ -d debug ] [ -f rulesfile ... ]
    	    [ -j jobs ] [ -s var=value ... ] [ -t target ... ]
    	    [  target ... ]

## DESCRIPTION

jam, the Jam/MR executable program, recursively builds target files from source files using dependency and build specification rules defined in rulesfile. jam parses rulesfile to identify targets and sources, examines the filesystem to determine which targets need updating, and issues OS commands to update targets.

Normally, rulesfile is compiled into jam, allowing jam to be run as a stand-alone program. A base set of build rules is provided in the file "Jambase", and is described in Using Jamfiles and Jambase and the Jambase Reference. For general information, refer to the Jam/MR Language document.

If target is provided on the command line, jam attempts to build target; otherwise jam attempts to build the target 'all'.

## OPTIONS

jam may be invoked with the following options:

           -a     Build all targets anyway, even if they are up-to-date.

           -d<n>  Enable cummulative debugging levels from 1 to <n>.
    	      Interesting values are:

                  1 Show actions (the default)
                  2 Show "quiet" actions and display all action text
                  3 Show dependency analysis, and target/source timestamps/paths
    	      4 Show shell arguments
    	      5 Show rule invocations and variable expansions
    	      6 Show directory/header file/archive scans
    	      7 Show variable settings
    	      8 Show variable fetches
    	      9 Show variable manipulation, scanner tokens

           -d+<n> Enable debugging level <n>.

           -d0    Turn off all debugging levels.  Only errors are not
                  suppressed.

           -f<rulesfile>
                  Read <rulesfile> instead of Jambase.

           -j<n>
                  Run  up to <n> shell commands concurrently (UNIX
                  only).  The default is 1.

           -n     Don't actually execute the updating actions, but do
                  everything else.  This changes the debug level default
    	      to -d2.

           -s<var>=<value>
                  Set  the variable <var> to <value>, overriding both
                  internal variables and variables imported from  the
                  environment.

           -t<target>
                  Rebuild <target>, even if it is up-to-date, and/or build
    	      dependencies of <target> as if <target> were newer.

           -v     Print the version of jam and exit.

## OPERATION

jam has three phases of operation: parsing, binding, and updating.

### Parsing

In the parsing phase, jam reads the rules file(s), evaluates variables, identifies and invokes rules, identifies targets, and builds the dependency graph.

Which rules files get read depends on the site-specific implementation of jam. The normal implementation is this: jam reads the Jambase rules file, the text of which is stored inside the jam executable itself. Jambase may "include" other rules files, and the last rule invoked from Jambase is "include Jamfile", which reads file "Jamfile" from the current directory. Jamfile is expected to specify which targets get built from the source files in the current directory. (All of this is explained in detail in Using Jamfiles and Jambase.) If there's no Jamfile in the current directory, jam emits a message and exits.

Environment variable settings are imported into Jam/MR variables. To pass a value to a variable on the jam command line, overriding the variable's environment value, use the -s option. To see variable assignments made during jam's execution, use the -d+7 option.

Rules are defined in rules files using the Jam/MR language, and are invoked in rules files after they are defined. Targets are identified by rule invocations. At the completion of the parsing phase, all targets are uniquely identified and a dependency graph is constructed.

### Binding

After parsing, jam recursively descends the dependency graph and binds every file target with a location in the filesystem. The existence and modification times of the bound files are used to determine which targets need updating. If jam detects a circular dependency in the graph, it issues a warning.

A file target is bound with a location as follows:

- If $(LOCATE) is set, the target is bound to the path described by the first element in $(LOCATE).

- If $(LOCATE) is not set, and the target has any updating actions associated with it, the target is bound to the current directory of the jam invocation.

- If $(LOCATE) is not set, and the target has no updating actions associated with it, and $(SEARCH) is set, jam searches the directories in the $(SEARCH) list. The first directory in the list in which the target is found becomes the target's bound path. If the target is not found, it is bound to the current directory of the jam invocation.

- If neither $(SEARCH) nor $(LOCATE) are set, the target is bound to the current directory of the jam invocation.

- If the target's identifier contains a rooted pathname, none of the above applies, and the target's bound location is that path.

- Unrooted pathnames used in $(SEARCH), $(LOCATE), or target identifiers are relative to the current directory where jam was invoked.

- Target-specific values of $(SEARCH) and $(LOCATE) always have precedence over global values in binding.

After binding each target, jam determines whether the target needs updating, and marks the target if necessary for the updating phase. A target is marked for updating for any of these three reasons:

- It is missing.
- Its filesystem modification time is older than any of its sources.
- Any of its sources are marked for updating.

For targets of the built-in rules ALWAYS, LEAVES, NOCARE, TEMPORARY, NOTFILE, and NOUPDATE, jam's updating behavior is slightly different:

> ALWAYS
>   The target is always updated.
> LEAVES
>   The target is only updated if it is missing or if its leaf sources are newer. Leaf sources are those dependencies of the target that have no dependencies themselves.
> NOCARE
>   The target is ignored if it is missing and has no updating actions. Normally, jam issues a warning and skips other targets that depend on missing targets without updating actions.
> TEMPORARY
>   If the target is missing, then its source's modification time is used when comparing against dependencies.
> NOTFILE
>   The target is only updated if any of its sources are marked for updating.
> NOUPDATE
>   The target is only updated if it is missing. Also, if it exists, it will appear eternally old; that is, older than anything that depends on it.

If $(HDRSCAN) is set on a file target, jam scans the file for header file include lines. It scans the file by matching each line against a regexp(3) pattern that has ()'s surrounding the included file name. The pattern is provided by the user through the special variable $(HDRSCAN) (see HDRPATTERN in Jambase for an example). The result of the scan is formed into a rule invocation, with the scanned file as the target and the found included file names as the sources. The rule invoked is named by the special variable $(HDRRULE). jam only scans files if $(HDRSCAN) is set, and $(HDRSCAN) is normally set target-specific.

Between binding and updating, jam announces the number of targets to be updated.

### Updating

After binding, jam again recursively descends the dependency graph, this time executing the update actions for each target marked for update during the binding phase. If a target's updating actions fail, then all targets which depend on it are skipped.

The -j flag instructs jam to build more than one target at a time. If there are multiple actions on a single target, they are run sequentially.

The special variable $(JAMSHELL) gives jam a command execution shell to be used instead of /bin/sh. This variable's value must be a multi-element list, corresponding to the argument vector for the command shell. An element "%" is replaced with the command string to execute. An element "!" is replaced with the multiprocess slot number, which is (inclusively) between 1 and the maximum number of concurrent jobs specified with the -j flag (default 1). If no element of the list is "%", the command string is tacked on as the last argument. The default value is: "/bin/sh -c %".

## DIAGNOSTICS

In addition to generic error messages, jam may emit one of the following:

           warning: unknown rule X

                  A  rule  was invoked that has not been defined with
                  an "actions" or "rule" statement.

           using N temp target(s)

                  Targets marked as being temporary (but  nonetheless
                  present) have been found.

           updating N target(s)

                  Targets are out-of-date and will be updated.

           can't find N target(s)

                  Source  files  can't  be  found  and  there  are no
                  actions to create them.

           can't make N target(s)

                  Due to sources not being found, other targets  cannot be made.

           warning: X depends on itself

                  A  target  depends  on  itself  either  directly or
                  through its sources.

           don't know how to make X

                  A target is not present and no  actions  have  been
                  defined to create it.

           X skipped for lack of Y

                  A  source failed to build, and thus a target cannot
                  be built.

           warning: using independent target X

                  A target that does is not a dependency of any other
                  target is being referenced with $(<) or $(>).

           X removed

                  jam  removed  a  partially built target after being
                  interrupted.

## BUGS, LIMITATIONS

The -j flag can cause jam to get confused when single actions update more than one target at a time. jam may try to execute actions to build those targets' dependencies before the targets themselves have all been built.

With the -j flag, errors from failed commands can get staggeringly mixed up. Also, because targets tend to get built in a quickest-first ordering, dependency information must be quite exact. Finally, beware of parallelizing commands that drop fixed-named files into the current directory, like yacc(1) does.

A poorly set $(JAMSHELL) is likely to result in silent failure.

## SEE ALSO

- Using Jamfiles and Jambase
- Jambase Reference
- The Jam/MR Language

Documentation and source are available at www.perforce.com/jam/jam.html.

## AUTHOR

Jam/MR's author is Christopher Seiwald (seiwald@perforce.com). Documentation is provided by Perforce Software, Inc.

Back to top.

Copyright 1997 Perforce Software, Inc.
Comments to info@perforce.com
Last updated: Oct 19, 1997