Webmaster  |  Imprint 
Platinum
Platinum C++ Framework
Main  |  License  |  Documentation  |  Download  |  Support 

Building

Overview

The Jam build-tool provides a versatile, unified build process across many platforms including cross-compilation, build-configuration, automated unit-tests, and concurrent execution of build steps. This is a a step-by-step introduction to the Jam-based build system, demonstrating the usage of jam on a Windows NT build host, on POSIX-based systems such as UNIX, Linux, Mac OS-X or QNX and show how to cross-compile.


Build Instructions

Starting the build process

The jam tool must be invoked in the project root, where the files named 'Jambase', 'Jamrule' and 'Jamfile' are located. A precompiled binary of the jam program is provided for Windows platforms and a POSIX shell-script for all other platforms, which builds the jam executable the first time it is excuted.

If jam is run without any arguments, default build options are attempted to be deduced from the environment. This will work well from a unix shell or the 'build command shell' provided by Microsoft visual studio installations.

To start a build with default build options simply change to the project root directory and execute the jam binary (-q means stop on first error). The command below builds the project on Windows when executed in the 'build command shell':

jam.exe -q

Accordingly, on POSIX systems, a script named jam.sh can be used to build the jam executable first and then the project in one simple step. The script builds the jam binary the first time it is executed and passes on any command-line arguments. The following command builds a project on POSIX hosts:

./jam.sh -q

NOTE:
After a checkout the jam-script may needs to be made executable with the chmod command:

chmod +x ./jam.sh

Building specific targets

All artefacts that are created during the build process are refered to as 'targets'. A target can be a binary file, such as a executable or a so-called pseudo-target, which usually references other targets. All targets build a dependency tree and if jam is invoked to build a target, all dependencies will be resolved automatically and be built first. To build a specific target of the project simply invoke jam with a target name. The following command will build the target program.bin and all its dependencies:

jam.sh program.bin

Some important pseudo-targets are named all, lib or exe. The target 'all' will build all targets in the dependency tree. 'lib' will build only libraries and 'exe' only exectuables, respectively. When jam is called without specifying any targets the pseudo-target 'all' is assumed. This is the same as explicitly calling jam to build the target 'all'. To build all libraries and their dependencies in a project, invoke jam like so:

jam.sh lib

Rebuilding targets

To completely rebuild a target and its dependencies, the command line parameter -a can be passed to jam. The option -a can be used with or without a specific target. Thus the following command will rebuild the whole project:

jam.exe -a

A specific target can be rebuild by combining -a and a target name. The target program.bin will be completely rebuild with the following command:

jam.exe -a program.bin

Cleaning the project

The pseudo-target 'clean' plays a special role in the jam build system. All artefacts that are created during the build process are dependents of the 'clean' peseudo-target. When jam is invoked with the target clean, all artefacts will be deleted if they exist. Therefore the following command will remove all artefacts that were created by a build with default options:

jam.sh clean

Build Verification Tests

The pseudo-target 'test' causes jam to build all unit-test and execute them. If a unit-test fails the whole build will be reported to have failed. The target test is not a dependent of the target all, so unit-tests are not built and executed by default. The following example builds the whole projects and executes the unit-test.

jam.sh -q test

Common Build Options

Various build options can be set to control how jam builds the targets, for example if a release or debug version should be built. Build options are set by special jam variables before or when jam is executed. A jam variable can be set with the command line option -s followed by a variable/value pair separated by the equal sign (-sVARIABLE=VALUE) or by setting a environment variable with the same name. When jam is invoked, all environment variables will be available as jam variables in the build scripts.

One important jam variable is named CONFIG and can be set to 'debug' or 'release' to build either a debug or release version of a project. To build a release version of a project, use the following command:

jam.sh -sCONFIG=release

Most variables have default values or are deduced from environment variables. The default for CONFIG is 'debug'. The following table gives an overview which jam variables are used to enable certain build options:

Target Operating System (TARGET_OS): nt, linux, qnxnto, wince, macox, solarix, aix
Target Platform (TARGET_OSPLAT): x86, ppc, arm, mips, sh4, sparc
Configuration (CONFIG): debug, release
Compiler/Toolchain (TOOLSET): vc7, vc8, vc9, gcc, icpp, qcc, xlc, sunpro, mingw

More than one variable can be set when jam is invoked. The following command builds a release version with the gnu compiler toolset on a POSIX host:

./jam.sh -sCONFIG=release -sTOOLSET=gcc

Compiling for Linux/Unix/Mac OS-X

Compiling for Linux or Mac OS-X with the GNU compiler is done from a normal shell. The default value for the TOOLSET is gcc already, so it doesn't have to be set explicitly. The following command builds a release version on a Unix system:

./jam.sh -sCONFIG=release

The default TOOLSET on a Unix host may not be gcc, but the compiler/linker of the respective vendor. For example, the default TOOLSET on AIX is the XLC compiler and the default TOOSET on Solaris is the Sun Workshop compiler. The Gnu compiler can be used on these systems by setting the TOOLSET to gcc explicitly.

Compiling for Windows NT/XP with Visual Studio 7/8

The Microsoft visual studio installation contains a special 'build command shell'. It differs from a regular command shell in that more environment variables are set. If the build command shell is not used, the VISUALC variable has to be set either as environment variable or with -s when jam is invoked. If the path to the visual studio installation contains whitespace the path has to be put in quotes. The following command demonstrates how a build can be started from a regular console on windows to build with VisualC++ 2005 (vc8):

jam.exe -sVISUALC="C:\Programme\Microsoft Visual Studio 2005" -sTOOLSET=vc8

If the special 'build command shell' is used, VISUALC is determined from other environment variables and does not have to be specified. Also, the TOOLSET is deduced from the environment and does not have to be specified. If the express version of Visual Studio 2005 is used, the path to the Platform SDK must be specified with -sPLATFORMSDK=path_to_PlatformSDK. To build with VisualC++ 2003, set the TOOLSET to vc7. It is not possible to build vc7 targets from the 'build command shell' provided by a Microsoft visual studio 8 installation or vice versa.

Compiling Windows CE targets

Windows CE targets need to be cross compiled under Windows NT/XP. Therefore the TARGET_OS and TARGET_OSPLAT variables need to be set when jam is invoked. No build command shell for embedded targets is provided by Microsoft, so the path to the Visual studio installation has to be set and a regular command shell has to be used. The following command builds for ARM CPU's:

jam.exe -sVISUALC="C:\Programme\Microsoft Visual Studio 8" 
        -sTOOLSET=vc8 -sTARGET_OS=wince -sTARGET_OSPLAT=arm

Compiling QNX targets

QNX targets can be cross compiled or directly compiled on a QNX host. Building with jam on a QNX host is not different from building on unix systems. To build on a QNX system simply execute the shell script:

./jam.sh

Cross compiling can be done on either a QNX host for another CPU or on a Windows NT/XP host. For cross compiling the TARGET_OS and TARGET_OSPLAT variables need to be set. The following command will build a project on a Windows NT/XP host for QNX systems with X86 processors.

jam.exe -sTARGET_OS=qnxnto -sTARGET_OSPLAT=x86

To cross compile for QNX on a QNX host the TARGET_OSPLAT needs to be set:

./jam.sh -sTARGET_OSPLAT=ppc


An Introduction to Jam

Usage

jam [ -a ] [ -g ] [ -n ] [ -q ] [ -v ]
    [ -d debug ] 
    [ -f jambase ] 
    [ -j jobs ] 
    [ -o actionsfile ] 
    [ -s var=value ] 
    [ -t target ] 
    [ target ... ]

Description

Jam is a program construction tool, like make(1).

Jam recursively builds target files from source files, using dependency information and updating actions expressed in the Jambase file, which is written in jam's own interpreted language. The default Jambase is compiled into jam and provides a boilerplate for common use, relying on a user-provide file "Jamfile" to enumerate actual targets and sources.

The Jambase is described in the Jambase Reference and the document Using Jamfiles and Jambase.

Command Line Options

If target is provided on the command line, jam builds target; otherwise jam builds the target 'all'.

Jam may be invoked with the following options:

-a Build all targets anyway, even if they are up-to-date.
-d c Turn on display option c and off the default display (summary info and actions):
a
Show summary info, actions, quiet actions, and the use of temporary targets
c
Show the names of files that cause rebuilds, i.e. new sources, missing targets, etc.
d
Display a dependency graph (in jam syntax).
m
Display the dependency analysis, and target/source timestamps and paths
x
Show shell arguments
-d n Enable cummulative debugging levels from 1 to n. Interesting values are:
1
Show actions and summary info (the default)
3
Old name for -dm (described above)
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.
-d 0 Turn off all debugging levels. Only errors are emitted.
-f jambase Read jambase instead of using the built-in Jambase. Multiple -f flags are permitted.
-g Build targets with the newest sources first, rather than in the order of appearance in the Jambase/Jamfiles.
-j n Run up to n shell commands concurrently (UNIX and NT only). The default is 1.
-n Don't actually execute the updating actions, but do everything else. This changes the debug level to -dax.
-o file Write the updating actions to the specified file instead of running them (or outputting them, as on the Mac).
-q Quit quickly (as if an interrupt was received) as soon as any target build fails.
-s var=value Set the variable var to value, overriding both internal variables and variables imported from the environment.
-t target Rebuild target and everything that depends on it, even if it is up-to-date.
-v Print the version of jam and exit.

Program Operation

Jam has four phases of operation: start-up, parsing, binding, and updating.

Start-up

Upon start-up, jam imports environment variable settings into jam variables. Environment variables are split at blanks with each word becoming an element in the variable's list of values. Environment variables whose names end in PATH are split at $(SPLITPATH) characters (e.g., ":" for Unix).

To set a variable's value on the 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.

Parsing

In the parsing phase, jam reads and executes the Jambase file, by default the built-in one. It is written in the jam language. See Language below. The last action of the Jambase is to read (via the "include" rule) a user-provided file called "Jamfile".

Collectively, the purpose of the Jambase and the Jamfile is to name built target and source files, construct the dependency graph among them, and associate build actions with targets. The Jambase defines boilerplate rules and variable assignments, and the Jamfile uses these to specify the actual relationship among the target and source files. See the Jambase Reference and the document Using Jamfiles and Jambase for information.

Binding

Binding
After parsing, jam recursively descends the dependency graph and binds every file target with a location in the filesystem.

Targets
Any string value in jam can represent a target, and it does so if the DEPENDS or INCLUDES rules make it part of the dependency graph. Build targets are files to be updated. Source targets are the files used in updating build targets. Build targets and source targets are collectively referred to as file targets, and frequently build targets are source targets for other build targets. Pseudotargets are symbols which represent dependencies on other targets, but which are not themselves associated with any real file.

A file target's identifier is generally the file's name, which can be absolutely rooted, relative to the directory of jam's invocation, or simply local (no directory). Most often it is the last case, and the actual file path is bound using the $(SEARCH) and $(LOCATE) special variables. See SEARCH and LOCATE Variables below. A local filename is optionally qualified with "grist," a string value used to assure uniqueness. A file target with an identifier of the form file(member) is a library member (usually an ar(1) archive on UNIX).

The use of $(SEARCH) and $(LOCATE) allows jam to separate the the location of files from their names, so that Jamfiles can refer to files locally (i.e. relative to the Jamfile's directory), yet still be usable when jam is invoked from a distant directory. The use of grist allows files with the same name to be identified uniquely, so that jam can read a whole directory tree of Jamfiles and not mix up same-named targets.

Update Determination
After binding each target, jam determines whether the target needs updating, and if so marks the target for the updating phase. A target is normally so marked if it is missing, it is older than any of its sources, or any of its sources are marked for updating. This behavior can be modified by the application of special built-in rules. See Modifying Binding below.

Header File Scanning
During the binding phase, jam also performs header file scanning, where it looks inside source files for the implicit dependencies on other files caused by C's #include syntax. This is controlled by the special variables $(HDRSCAN) and $(HDRRULE). 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. Note that this is the only case where rules are invoked outside the parsing phase. See HDRSCAN and HDRRULE Variables below.

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 other targets which depend on that target 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 -g flag reorders builds so that targets with newest sources are built first. Normally, they are built in the order of appearance in the Jamfiles.

Language Features

Overview

Jam has a interpreted, procedural language with a few select features to effect program construction. Statements in jam are rule (procedure) definitions, rule invocations, updating action definitions, flow-of-control structures, variable assignments, and sundry language support.

Lexical Features

Jam treats its input files as whitespace-separated tokens, with two exceptions: double quotes (") can enclose whitespace to embed it into a token, and everything between the matching curly braces ({}) in the definition of a updating actions is treated as a single string. A backslash (\) can escape a double quote, or any single whitespace character.

Jam requires whitespace (blanks, tabs, or newlines) to surround all tokens, including the colon (:) and semicolon (;) tokens.

Jam keywords (as mentioned in this document) are reserved and generally must be quoted with double quotes (") to be used as arbitrary tokens, such as variable or target names.

Datatype

Jam's only data type is a one-dimensional list of arbitrary strings. They arise as literal (whitespace-separated) tokens in the Jambase or included files, as the result of variable expansion of those tokens, or as the return value from a rule invocation.

Rules

The basic jam language entity is called a rule. A rule is simply a procedure definition, with a body of jam statements to be run when the rule is invoked. The syntax of rule invocation make it possible to write Jamfiles that look a bit like Makefiles.

Rules take up to 9 arguments ($(1) through $(9), each a list) and can have a return value (a single list). A rule's return value can be expanded in a list by enclosing the rule invocation with [ and ].

Updating Actions

A rule may have updating actions associated with it, in which case arguments $(1) and $(2) are treated as built targets and sources, respectively. Updating actions are the OS shell commands to execute when updating the built targets of the rule.

When an rule with updating actions is invoked, those actions are added to those associated with its built targets ($(1)) before the rule's procedure is run. Later, to build the targets in the updating phase, the actions are passed to the OS command shell, with $(1) and $(2) replaced by bound versions of the target names. See Binding above.

Statements

Jam's langauge has the following statements:

rulename field1 : field2 : ... : fieldN ;

Invoke a rule. A rule is invoked with values in field1 through fieldN (9 max). They may be referenced in the procedure's statements as $(1) through $(<9>N). $(<) and $(>) are synonymous with $(1) and $(2).

rulename undergoes variable expansion. If the resulting list is more than one value, each rule is invoked with the same arguments, and the result of the invocation is the concatenation of all the results.

actions [ modifiers ] rulename { commands }

Define a rule's updating actions, replacing any previous definition. The first two arguments may be referenced in the action's commands as $(1) and $(2) or $(<) and $(>).

The following action modifiers are understood:

actions bind vars $(vars) will be replaced with bound values.
actions existing $(>) includes only source targets currently existing.
actions ignore The return status of the commands is ignored.
actions piecemeal commands are repeatedly invoked with a subset of $(>) small enough to fit in the command buffer on this OS.
actions quietly The action is not echoed to the standard output.
actions together The $(>) from multiple invocations of the same action on the same built target are glommed together.
actions updated $(>) includes only source targets themselves marked for updating.

break

Breaks out of the closest enclosing for or while loop.

continue

Jumps to the end of the closest enclosing for or while loop.

for var in list { statements }

Executes statements for each element in list, setting the variable var to the element value.

if cond { statements } [ else statement ]

Does the obvious; the else clause is optional. cond is built of:
a true if any a element is a non-zero-length string
a = b list a matches list b string-for-string
a != b list a does not match list b
a < b a[i] string is less than b[i] string, where i is first mismatched element in lists a and b
a <= b every a string is less than or equal to its b counterpart
a > b a[i] string is greater than b[i] string, where i is first mismatched element
a >= b every a string is greater than or equal to its b counterpart
a in b true if all elements of a can be found in b, or if a has no elements
! cond condition not true
cond && cond conjunction
cond || cond disjunction
( cond ) precedence grouping

include file ;

Causes jam to read the named file. The file is bound like a regular target (see Binding above) but unlike a regular target the include file cannot be built. Marking an include file target with the NOCARE rule makes it optional: if it is missing, it causes no error.

The include file is inserted into the input stream during the parsing phase. The primary input file and all the included file(s) are treated as a single file; that is, jam infers no scope boundaries from included files.

local vars [ = values ] ;

Creates new vars inside to the enclosing {} block, obscuring any previous values they might have. The previous values for vars are restored when the current block ends. Any rule called or file included will see the local and not the previous value (this is sometimes called Dynamic Scoping). The local statement may appear anywhere, even outside of a block (in which case the previous value is restored when the input ends). The vars are initialized to values if present, or left uninitialized otherwise.

on target statement ;

Run statement under the influence of target's target-specific variables. These variables become local copies during statement's run, but they may be updated as target-specific variables using the usual "variable on targets =" syntax.

return values ;

Within a rule body, the return statement sets the return value for an invocation of the rule and terminates the rule's execution.

rule rulename [ : vars ] { statements }

Define a rule's procedure, replacing any previous definition. If vars are provided, they are assigned the values of the parameters ($(1) to $(9)) when statements are executed, as with the local statement.

switch value
{
case pattern1 : statements ;
case pattern2 : statements ;
...
}

The switch statement executes zero or one of the enclosed statements, depending on which, if any, is the first case whose pattern matches value. The pattern values are not variable-expanded. The pattern values may include the following wildcards:
? match any single character
* match zero or more characters
[chars] match any single character in chars
[^chars] match any single character not in chars
\x match x (escapes the other wildcards)

while cond { statements }

Repeatedly execute statements while cond remains true upon entry. (See the description of cond expression syntax under if, above).

Variables

Jam variables are lists of zero or more elements, with each element being a string value. An undefined variable is indistinguishable from a variable with an empty list, however, a defined variable may have one more elements which are null strings. All variables are referenced as $(variable).

Variables are either global or target-specific. In the latter case, the variable takes on the given value only during the target's binding, header file scanning, and updating; and during the "on target statement" statement.

A variable is defined with:

variable = elements ;
variable += elements ;
variable ?= elements ;
variable on targets = elements ;
variable on targets += elements ;
variable on targets ?= elements ;

The first three forms set variable globally. The last three forms set a target-specific variable. The = operator replaces any previous elements of variable with elements; the += operation adds elements to variable's list of elements; the ?= operator sets variable only if it was previously unset. The last form "variable on targets ?= elements" checks to see if the target-specific, not the global, variable is set. (The ?= operator also has an old form "default =".)

Variables referenced in updating commands will be replaced with their values; target-specific values take precedence over global values. Variables passed as arguments ($(1) and $(2)) to actions are replaced with their bound values; the "bind" modifier can be used on actions to cause other variables to be replaced with bound values. See Action Modifiers above.

Jam variables are not re-exported to the environment of the shell that executes the updating actions, but the updating actions can reference jam variables with $(variable).

Variable Expansion

During parsing, jam performs variable expansion on each token that is not a keyword or rule name. Such tokens with embedded variable references are replaced with zero or more tokens. Variable references are of the form $(v) or $(vm), where v is the variable name, and m are optional modifiers.

Variable expansion in a rule's actions is similar to variable expansion in statements, except that the action string is tokenized at whitespace regardless of quoting.

The result of a token after variable expansion is the product of the components of the token, where each component is a literal substring or a list substituting a variable reference. For example:


$(X) -> a b c
t$(X) -> ta tb tc
$(X)z -> az bz cz
$(X)-$(X) -> a-a a-b a-c b-a b-b b-c c-a c-b c-c

The variable name and modifiers can themselves contain a variable reference, and this partakes of the product as well:


$(X) -> a b c
$(Y) -> 1 2
$(Z) -> X Y
$($(Z)) -> a b c 1 2

Because of this product expansion, if any variable reference in a token is undefined, the result of the expansion is an empty list. If any variable element is a null string, the result propagates the non-null elements:


$(X) -> a ""
$(Y) -> "" 1
$(Z) ->
*$(X)$(Y)* -> *a* *a1* ** *1*
*$(X)$(Z)* ->

A variable element's string value can be parsed into grist and filename-related components. Modifiers to a variable are used to select elements, select components, and replace components. The modifiers are:

[n] Select element number n (starting at 1). If the variable contains fewer than n elements, the result is a zero-element list.
[n-m] Select elements number n through m.
[n-] Select elements number n through the last.
:B Select filename base.
:S Select (last) filename suffix.
:M Select archive member name.
:D Select directory path.
:P Select parent directory.
:G Select grist.
:U Replace lowercase characters with uppercase.
:L Replace uppercase characters with lowercase.
:chars Select the components listed in chars.
:G=grist Replace grist with grist.
:D=path Replace directory with path.
:B=base Replace the base part of file name with base.
:S=suf Replace the suffix of file name with suf.
:M=mem Replace the archive member name with mem.
:R=root Prepend root to the whole file name, if not already rooted.
:E=value Use value instead if the variable is unset.
:J=joinval Concatentate list elements into single element, separated by joinval.

On VMS, $(var:P) is the parent directory of $(var:D); on Unix and NT, $(var:P) and $(var:D) are the same.

Built-in Rules

Jam has twelve built-in rules, all of which are pure procedure rules without updating actions. They are in three groups: the first builds the dependency graph; the second modifies it; and the third are just utility rules.

Dependency Building

DEPENDS targets1 : targets2 ;
Builds a direct dependency: makes each of targets1 depend on each of targets2. Generally, targets1 will be rebuilt if targets2 are themselves rebuilt are or are newer than targets1.

INCLUDES targets1 : targets2 ;
Builds a sibling dependency: makes any target that depends on any of targets1 also depend on each of targets2. This reflects the dependencies that arise when one source file includes another: the object built from the source file depends both on the original and included source file, but the two sources files don't depend on each other. For example:

DEPENDS foo.o : foo.c ;
INCLUDES foo.c : foo.h ;

"foo.o" depends on "foo.c" and "foo.h" in this example.

Modifying Binding

The six rules ALWAYS, LEAVES, NOCARE, NOTFILE, NOUPDATE, and TEMPORARY modify the dependency graph so that jam treats the targets differently during its target binding phase. See Binding above. Normally, jam updates a target if it is missing, if its filesystem modification time is older than any of its dependencies (recursively), or if any of its dependencies are being updated. This basic behavior can be changed by invoking the following rules:

ALWAYS targets ;
Causes targets to be rebuilt regardless of whether they are up-to-date (they must still be in the dependency graph). This is used for the clean and uninstall targets, as they have no dependencies and would otherwise appear never to need building. It is best applied to targets that are also NOTFILE targets, but it can also be used to force a real file to be updated as well.

LEAVES targets ;
Makes each of targets depend only on its leaf sources, and not on any intermediate targets. This makes it immune to its dependencies being updated, as the "leaf" dependencies are those without their own dependencies and without updating actions. This allows a target to be updated only if original source files change.

NOCARE targets ;
Causes jam to ignore targets that neither can be found nor have updating actions to build them. Normally for such targets jam issues a warning and then skips other targets that depend on these missing targets. The HdrRule in Jambase uses NOCARE on the header file names found during header file scanning, to let jam know that the included files may not exist. For example, if a #include is within an #ifdef, the included file may not actually be around.

NOTFILE targets ;
Marks targets as pseudotargets and not real files. No timestamp is checked, and so the actions on such a target are only executed if the target's dependencies are updated, or if the target is also marked with ALWAYS. The default jam target "all" is a pseudotarget. In Jambase, NOTFILE is used to define several addition convenient pseudotargets.

NOUPDATE targets ;
Causes the timestamps on targets to be ignored. This has two effects: first, once the target has been created it will never be updated; second, manually updating target will not cause other targets to be updated. In Jambase, for example, this rule is applied to directories by the MkDir rule, because MkDir only cares that the target directory exists, not when it has last been updated.

TEMPORARY targets ;
Marks targets as temporary, allowing them to be removed after other targets that depend upon them have been updated. If a TEMPORARY target is missing, jam uses the timestamp of the target's parent. Jambase uses TEMPORARY to mark object files that are archived in a library after they are built, so that they can be deleted after they are archived.

Utility Rules
The remaining rules are utility rules.

ECHO args ;
Echo args ;
echo args ;
Blurts out the message args to stdout.

EXIT args ;
Exit args ;
exit args ;
Blurts out the message args to stdout and then exits with a failure status.

GLOB directories : patterns ;
Scans directories for files matching patterns, returning the list of matching files (with directory prepended). patterns uses the same syntax as in the switch statement. Only useful within the [ ] construct, to change the result into a list.

MATCH regexps : list ;
Matches the egrep(1) style regular expressions regexps against the strings in list. The result is the concatenation of matching () subexpressions for each string in list, and for each regular expression in regexps. Only useful within the [ ] construct, to change the result into a list.

Built-in Variables

This section discusses variables that have special meaning to jam.

SEARCH and LOCATE Variables

These two variables control the binding of file target names to locations in the file system. Generally, $(SEARCH) is used to find existing sources while $(LOCATE) is used to fix the location for built targets.

Rooted (absolute path) file targets are bound as is. Unrooted file target names are also normally bound as is, and thus relative to the current directory, but the settings of $(LOCATE) and $(SEARCH) alter this:

  • If $(LOCATE) is set then the target is bound relative to the first directory in $(LOCATE). Only the first element is used for binding.
  • If $(SEARCH) is set then the target is bound to the first directory in $(SEARCH) where the target file already exists.
  • If the $(SEARCH) search fails, the target is bound relative to the current directory anyhow.

Both $(SEARCH) and $(LOCATE) should be set target-specific and not globally. If they were set globally, jam would use the same paths for all file binding, which is not likely to produce sane results. When writing your own rules, especially ones not built upon those in Jambase, you may need to set $(SEARCH) or $(LOCATE) directly. Almost all of the rules defined in Jambase set $(SEARCH) and $(LOCATE) to sensible values for sources they are looking for and targets they create, respectively.

HDRSCAN and HDRRULE Variables

These two variable control header file scanning. $(HDRSCAN) is an egrep(1) pattern, with ()'s surrounding the file name, used to find file inclusion statements in source files. Jambase uses $(HDRPATTERN) as the pattern for $(HDRSCAN). $(HDRRULE) is the name of a rule to invoke with the results of the scan: the scanned file is the target, the found files are the sources. $(HDRRULE) is run under the influence of the scanned file's target-specific variables.

Both $(HDRSCAN) and $(HDRRULE) must be set for header file scanning to take place, and they should be set target-specific and not globally. If they were set globally, all files, including executables and libraries, would be scanned for header file include statements.

The scanning for header file inclusions is not exact, but it is at least dynamic, so there is no need to run something like makedepend(GNU) to create a static dependency file. The scanning mechanism errs on the side of inclusion (i.e., it is more likely to return filenames that are not actually used by the compiler than to miss include files) because it can't tell if #include lines are inside #ifdefs or other conditional logic. In Jambase, HdrRule applies the NOCARE rule to each header file found during scanning so that if the file isn't present yet doesn't cause the compilation to fail, jam won't care.

Also, scanning for regular expressions only works where the included file name is literally in the source file. It can't handle languages that allow including files using variable names (as the Jam language itself does).

Platform Identifier Variables

A number of Jam built-in variables can be used to identify runtime platform:

OSOS identifier string
OSPLATUnderlying architecture, when applicable
MACtrue on MAC platform
NTtrue on NT platform
OS2true on OS2 platform
UNIXtrue on Unix platforms
VMStrue on VMS platform

Jam Version Variables

JAMDATETime and date at jam start-up.
JAMUNAMEOuput of uname(1) command (Unix only)
JAMVERSIONjam version, as reported by jam -v.

JAMSHELL Variable

When jam executes a rule's action block, it forks and execs a shell, passing the action block as an argument to the shell. The invocation of the shell can be controlled by $(JAMSHELL). The default on Unix is, for example:

JAMSHELL = /bin/sh -c % ;

The % is replaced with the text of the action block.

Jam does not directly support building in parallel across multiple hosts, since that is heavily dependent on the local environment. To build in parallel across multiple hosts, you need to write your own shell that provides access to the multiple hosts. You then reset $(JAMSHELL) to reference it.

Just as jam expands a % to be the text of the rule's action block, it expands a ! to be the multi-process slot number. The slot number varies between 1 and the number of concurrent jobs permitted by the -j flag given on the command line. Armed with this, it is possible to write a multiple host shell. For example:


#!/bin/sh

# This sample JAMSHELL uses the SunOS on(1) command to execute a
# command string with an identical environment on another host.

# Set JAMSHELL = jamshell ! %
#
# where jamshell is the name of this shell file.
#
# This version handles up to -j6; after that they get executed
# locally.

case $1 in
1|4) on winken sh -c "$2";;
2|5) on blinken sh -c "$2";;
3|6) on nod sh -c "$2";;
*) eval "$2";;
esac

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 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 proceed as if the targets were built even though they are still under construction.

For parallel building to be successful, the dependencies among files must be properly spelled out, as targets tend to get built in a quickest-first ordering. Also, beware of un-parallelizable commands that drop fixed-named files into the current directory, like yacc(1) does.

With the -j flag, errors from failed commands can get staggeringly mixed up.

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

Author

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


Setting up Projects

Overview

jam, the Jam executable program, recursively builds target files from source files using dependency and build specifications defined in Jam rules files. jam parses the rules files to identify targets and sources, examines the filesystem to determine which targets need updating, and issues OS commands to update targets. Jam requires a few files and one directory to be present to compile a project.

A base rules file called "Jambase" is provided with the Jam distribution and is normally located in the project root. The Jambase file defines rules and variables which support standard software build operations, like compiling, linking, etc. When jam is invoked, the Jambase will be loaded, if none is present the project root, a builtin Jambase is used. The external Jambase references further scripts from a 'jam' subdirectory, which must be located in the project root as well.

When the Jambase rules are used, jam reads Jambase, then reads a file called "Jamfile" in the current directory. The Jamfile describes what to do with the source files in its directory. It may also cause Jamfiles in other directories to be read.

Under certain circumstances, the first Jamfile read also causes a site-specific "Jamrules" file to be read. The Jamrules file is an optional set of rule and variable definitions used to define site-specific processing.

The Basic Jamfile

Jamfiles contain rule invocations, which usually look like:

    RuleName targets : targets ;

The target(s) to the left of the colon usually indicate what gets built, and the target(s) to the right of the colon usually indicate what it is built from.

A Jamfile can be as simple as this:

    Main myprog : main.c util.c ;
This specifies that there is a main.c and util.c file in the same directory as the Jamfile, and that those source files should be compiled and linked into an executable called myprog. If you cd to the directory where this Jamfile lives, you can see the exactly how jam would build myprog with:
    jam -n
Or, you can actually build myprog with the command:
    jam

Whitespace

Jamfile elements are delimited by whitespace (blanks, tabs, or newlines). Elements to be delimited include rule names, targets, colons, and semicolons. A common mistake users make is to forget the whitespace, e.g.,
    Main myprog: main.c util.c ; #WRONG!
Jam doesn't distinguish between a typo and a target called "myprog:", so if you get strange results, the first thing you should check for in your Jamfile is missing whitespace.

Filenames, Target Identifiers, and Buildable Targets

Consider this Jamfile:

    Main myprog : main.c util.c ;                   
    LinkLibraries myprog : libtree ;     
    Library libtree : treemake.c treetrav.c ;    

The Main rule specifies that an executable called myprog will be built. The compiled main.c and util.c objects will be linked to produce myprog. The LinkLibraries rule specifies that libtree will be linked into myprog as well. The Library rule specifies which source files will be compiled and archived into the libtree library.

The Jamfile above refers to targets like "myprog" and "libtree". However, depending on the platform you're building on, the actual filenames of those targets could be "myprog.exe" and "libtree.lib". Most Jambase rules supply the actual filenames of targets, so that Jamfiles themselves need not make any platform-specific filename references.

The jam program builds up a list of unique target identifiers. Unless you are using the SubDir rules (described later), the default identifier for a file target is its filename. In the above example, the target identifiers are the filenames: myprog.exe, libtree.lib, main.obj, etc.

While all Jambase rules refer to "targets", not all targets are buildable. There are two kinds of buildable targets: file targets and pseudotargets. File targets are objects that can be found in the filesystem. Pseudotargets are symbolic, and represent other targets.

You can use any buildable target on the jam command line to build a subset of defined targets. For example:

        jam libtree.a 
on Unix builds the libtree library and all the compiled objects that go in it.

Pseudotargets

Most Jambase rules that define file targets also define pseudotargets which are dependent on types of file targets. For example, Jambase defines a pseudotarget called "lib", which is dependent on file targets created by the Library rule. So the command:

        jam lib
used with the above example would cause the libtree library to be built. Also, there is one pseudotarget built into jam itself, called "all". Jambase sets "all" dependent on (almost) all other targets.

In the unfortunate case where you have a buildable target whose name is the same as one of the Jambase pseudotargets, you'll have problems with the conflicting target name. Your workaround choices are:

  1. Change the name of your buildable file or directory that conflicts.

  2. Modify your Jambase and change the name of the conflicting pseudotarget. (Pseudotargets are defined in Jambase using the NOTFILE rule.)

  3. Use grist on the conflicting target name in your Jamfile. E.g., instead of
        File lib : libfoo.a ;
        
    try
        File <dir>lib : libfoo.a ;
        

Dependencies

Jambase rules set dependencies on targets, so that if you update a source file, all the file targets that depend on that source file, and only the ones that depend on that source file, will be updated (rebuilt) the next time you run jam.

Here are some of the dependencies that get set when jam runs on NT using the example Jamfile above:

Target   Depends on
myprog.exemain.obj, util.obj, libtree.lib
libtree.libtreemake.obj, treetrav.obj
treetrav.objtreetrav.c

Furthermore, the Main and Library rules set up recursive header scanning on their source targets. So after jam has finished parsing the Jamfile and setting the rule-driven dependencies, it scans the source files for "#include" lines. All #include files found during this scan become dependencies of the compiled object. E.g., all header files used to compile treetrav.c would be made dependencies of treetrav.obj.

As a result, when you run jam, it will rebuild targets if either the source files change or the header files change. You can't tell by looking at a Jamfile which header files are dependencies, but you can easily display those dependencies with:

    jam -nd+3

Rule Ordering

Rules which specify dependencies, like the Main, Library, and LinkLibrary rules, can be invoked in any order. jam figures out the order in which targets are built from their dependencies.

Some rules, however, set variables which are used by subsequent rule invocations, and their ordering is important. For example, the SubDir* rules (discussed later) must be invoked in a particular order.

Detailed Jambase Specifications

This document describes how to use various Jambase rules from a functional point of view. You can see the summary of available Jambase rules in the Jambase Reference. The detailed specifications for any Jambase rule can be found by reading the rule definition itself in the Jambase file.

Handling Directory Trees

The SubDir* rules are used to define source code directory hierarchies. With SubDir and SubInclude, you can use jam to build software from source files and Jamfiles spread across many directories, as is typical for large projects. The SubDir* rules unify an entire source code tree so that jam can read in all the Jamfiles in one pass and compute dependencies across the entire project.

To use the SubDir* rules, you must:

  1. Preface the Jamfile in each directory with an invocation of the SubDir rule.

  2. Place at the root of the tree a file named Jamrules. This file could be empty, but in practice it contains user-provided rules and variable definitions that are shared throughout the tree. Examples of such definitions are library names, header directories, install directories, compiler flags, etc. This file is good candidate for automatic customizing with autoconf(GNU).

  3. Optionally, set an environment variable pointing to the root directory of the srouce tree. The variable's name is left up to you, but in these examples, we use TOP.

SubDir Rule

The SubDir rule must be invoked before any rules that refer to the contents of the directory - it is best to put it at the top of each Jamfile. For example:

    # Jamfile in $(TOP)/src/util directory.

    SubDir TOP src util ;

    Main myprog : main.c util.c ;                   
    LinkLibraries myprog : libtree ;     
    Library libtree : treemake.c treetrav.c ;    
This compiles four files in $(TOP)/src/util, archives two of the objects into libtree, and links the whole thing into myprog. Outputs are placed in the $(TOP)/src/util directory.

This doesn't appear to be any different from the previous example that didn't have a SubDir rule, but two things are happening behind the scenes:

The SubDir rule takes as its first argument the root variable's name and takes as subsequent arguments the directory names leading from the root to the directory of the current Jamfile. Note that the name of the subdirectory is given as individual elements: the SubDir rule does not use system-specific directory name syntax.

SubInclude Rule

The SubInclude rule is used in a Jamfile to cause another Jamfile to be read in. Its arguments are in the same format as SubDir's.

The recommended practice is only to include one level of subdirectories at a time, and let the Jamfile in each subdirectory include its own subdirectories. This allows a user to sit in any arbitrary directory of the source tree and build that subtree. For example:

       # This is $(TOP)/Jamfile, top level Jamfile for mondo project.

       SubInclude TOP src ;
       SubInclude TOP man ;
       SubInclude TOP misc ;
       SubInclude TOP util ;
If a directory has both subdirectories of its own as well as files that need building, the SubIncludes should be either before the SubDir rule or be at the end of the Jamfile - not between the SubDir and other rule invocations. For example:
    # This is $(TOP)/src/Jamfile:

    SubDir TOP src ;

    Main mondo : mondo.c ;
    LinkLibraries mondo : libmisc libutil ;
    
    SubInclude TOP src misc ;
    SubInclude TOP src util ;

(jam processes all the Jamfiles it reads as if it were reading one single, large Jamfile. Build rules like Main and LinkLibraries rely on the preceding SubDir rule to set up source file and output file locations, and SubIncludes rules read in Jamfiles that contain SubDir rules. So if you put a SubIncludes rule between a SubDir and a Main rule, jam will try to find the source files for the Main rule in the wrong directory.)

Variables Used to Handle Directory Trees

The following variables are set by the SubDir rule and used by the Jambase rules that define file targets:

SEARCH_SOURCE The SubDir targets (e.g., "TOP src util") are used to construct a pathname (e.g., $(TOP)/src/util), and that pathname is assigned to $(SEARCH_SOURCE). Rules like Main and Library use $(SEARCH_SOURCE) to set search paths on source files.
LOCATE_SOURCE Initialized by the SubDir rule to the same value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET is set. $(LOCATE_SOURCE) is used by rules that build generated source files (e.g., Yacc and Lex) to set location of output files. Thus the default location of built source files is the directory of the Jamfile that defines them.
LOCATE_TARGET Initalized by the SubDir rule to the same value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET is set. $(LOCATE_TARGET) is used by rules that build binary objects (e.g., Main and Library) to set location of output files. Thus the default location of built binaray files is the directory of the Jamfile that defines them.
ALL_LOCATE_TARGET If $(ALL_LOCATE_TARGET) is set, LOCATE_SOURCE and and LOCATE_TARGET are set to $(ALL_LOCATE_TARGET) instead of to $(SEARCH_SOURCE). This can be used to direct built files to be written to a location outside of the source tree, and enables building from read-only source trees.
SOURCE_GRIST The SubDir targets are formed into a string like "src!util" and that string is assigned to SOURCE_GRIST. Rules that define file targets use $(SOURCE_GRIST) to set the "grist" attribute on targets. This is used to assure uniqueness of target identifiers where filenames themselves are not unique. For example, the target identifiers of $(TOP)/src/client/main.c and $(TOP)/src/server/main.c would be <src!client>main.c and <src!server>main.c.

The $(LOCATE_TARGET) and $(SEARCH_SOURCE) variables are used extensively by rules in Jambase: most rules that generate targets (like Main, Object, etc.) set $(LOCATE) to $(LOCATE_TARGET) for the targets they generate, and rules that use sources (most all of them) set $(SEARCH) to be $(SEARCH_SOURCE) for the sources they use.

$(LOCATE) and $(SEARCH) are better explained in The Jam Executable Program but in brief they tell jam where to create new targets and where to find existing ones, respectively.

Note that you can reset these variables after SubDir sets them. For example, this Jamfile builds a program called gensrc, then runs it to create a source file called new.c:


       SubDir TOP src util ;
       Main gensrc : gensrc.c ;
       LOCATE_SOURCE = $(NEWSRC) ;
       GenFile new.c : gensrc ;
       
By default, new.c would be written into the $(TOP)/src/util directory, but resetting LOCATE_SOURCE causes it to be written to the $(NEWSRC) directory. ($(NEWSRC) is assumed to have been set elsewhere, e.g., in Jamrules.)

VMS Notes

On VMS, the logical name table is not imported as is the environment on UNIX. To use the SubDir and related rules, you must set the value of the variable that names the root directory. For example:
              TOP = USR_DISK:[JONES.SRC] ;

              SubInclude TOP util ;
The variable must have a value that looks like a directory or device. If you choose, you can use a concealed logical. For example:
              TOP = TOP: ;

              SubInclude TOP util ;
The : at the end of TOP makes the value of $(TOP) look like a device name, which jam respects as a directory name and will use when trying to access files. TOP must then be defined from DCL:
              $ define/job/translation=concealed TOP DK100:[USERS.JONES.SRC.]
Note three things: the concealed translation allows the logical to be used as a device name; the device name in the logical (here DK100) cannot itself be concealed logical (VMS rules, man); and the directory component of the definition must end in a period (more VMS rules).

Building Executables and Libraries

The rules that build executables and libraries are: Main, Library, and LinkLibraries.

Main Rule

The Main rule compiles source files and links the resulting objects into an executable. For example:
              Main myprog : main.c util.c ;
This compiles main.c and util.c and links main.o and util.o into myprog. The object files and resulting executable are named appropriately for the platform.

Main can also be used to build shared libraries and/or dynamic link libraries, since those are also linked objects. Though, this feature is deprecated and the rule SharedLibrary should be used instead.


        Main driver$(SUFSHR) : driver.c ;
    
Normally, Main uses $(SUFEXE) to determine the suffix on the filename of the built target. To override it, you can supply a suffix explicity. In this case, $(SUFSHR) is assumed to be the OS-specific shared library suffix, defined in Jamrules with something like:
        if $(UNIX)      { SUFSHR = .so ; }
        else if $(NT)   { SUFSHR = .dll ; }
    

Main uses the Objects rule to compile source targets.

Library Rule

The Library rule compiles source files, archives the resulting object files into a library, and then deletes the object files. For example:
              Library libstring : strcmp.c strcpy.c strlen.c ;
              Library libtree : treemake.c treetrav.c ;
This compiles five source files, archives three of the object files into libstring and the other two into libtree. Actual library filenames are formed with the $(SUFLIB) suffix. Once the objects are safely in the libraries, the objects are deleted.

Library uses the Objects rule to compile source files.

SharedLibrary Rule

The rule 'SharedLibrary' compiles source files and links the resulting objects into a shared library. For example:
              SharedLibrary example : example.c util.c ;
This compiles example.c and util.c and links example.o and util.o into example. The object files and resulting executable are named appropriately for the platform. Main uses the Objects rule to compile source targets.

Normally, SharedLibrary uses $(SUFLIB) and $(SUFDLL) to determine the prefix/suffix on the filename of the built target. Under windows the resulting library will be called example.dll and a import library called example.lib will be created. Under unix, one shared library called libexample.so will be created. To override it, you can supply a prefix/suffix explicity.

LinkLibraries Rule

To link executables or shared libraries with built static libraries, use the LinkLibraries rule. For example:
              Main myprog : main.c util.c ;
              LinkLibraries myprog : libstring libtree ;

              SharedLibrary mydll : dll.c stuff.c ;
              LinkLibraries mydll : libstring libtree ;
The LinkLibraries rule does two things: it makes the libraries dependencies of the executable, so that they get built first; and it makes the libraries show up on the command line that links the executable. The ordering of the lines above is important, because the preceeding Main or SharedLibrary Rule type its target.

You can put multiple libraries on a single invocation of the LinkLibraries rule, or you can provide them in multiple invocations. In both cases, the libraries appear on the link command line in the order in which they were encountered. You can also provide multiple executables to the LinkLibraries rule, if they need the same libraries, e.g.:

              LinkLibraries prog1 prog2 prog3 : libstring libtree ;

The LinkLibraries rule accepts a third optional parameter to add linker flags to the command line that links the target. The rule does so by settimg the LINKLIBS variable on the targets specified in the first argument. The following example uses the linker flags conatined in FLAGS when myprog is linked:

              Main myprog : main.c util.c ;
              LinkLibraries myprog : libstring libtree : $(FLAGS) ;

LinkSharedLibraries Rule

To link executables or shared libraries with built shared libraries, use the LinkSharedLibraries rule. For example:
              Main myprog : main.c util.c ;
              LinkSharedLibraries myprog : example ;

              SharedLibrary mydll : dll.c stuff.c ;
              LinkSharedLibraries mydll : example ;
The LinkSharedLibraries rule does two things: it makes the libraries dependencies of the executable, so that they get built first; and it makes the libraries show up on the command line that links the executable. The ordering of the lines above is important, because the preceeding Main or SharedLibrary Rules type its target.

You can put multiple libraries on a single invocation of the LinkSharedLibraries rule, or you can provide them in multiple invocations. In both cases, the libraries appear on the link command line in the order in which they were encountered. E. g.:

              LinkSharedLibraries myprog : example1 example2 ;

The LinkSharedLibraries rule accepts a third optional parameter to add linker flags to the command line that links the executable or shared library. The following example assumes that a variable FLAGS contains additional linker flags:

              Main myprog : main.c util.c ;
              LinkSharedLibraries myprog : libstring libtree : $(FLAGS) ;

The LinkSharedLibraries rule accepts a third optional parameter to add linker flags to the command line that links the target. The rule does so by settimg the LINKLIBS variable on the targets specified in the first argument. The following example uses the linker flags conatined in FLAGS when myprog is linked:

              Main myprog : main.c util.c ;
              LinkSharedLibraries myprog : libstring libtree : $(FLAGS) ;

LinkFlags Rule

The LinkFlags adds specific linker flag for a target such as an executable or shared library. For example:
              Main myprog : main.c util.c ;
              LinkFlags myprog : $(FLAGS) ;

              SharedLibrary mydll : dll.c stuff.c ;
              LinkFlags mydll : $(FLAGS) ;
This adds the linker flags contained in $(FLAGS) to the to the command line that links the targets myprog or mydll. It is possible to link against external libraries by adding the actual link command flag.

Variables Used in Building Executables and Libraries

AR Archive command, used for Library targets.
SUFEXE *Suffix on filenames of executables referenced by Main and LinkLibraries.
SUFDLL *Suffix on filenames of shared libraries referenced by SharedLibrary and LinkSharedLibraries.
LINK Link command, used for Main targets.
LINKFLAGS Linker flags.
LINKLIBS Link libraries that aren't dependencies. (See note below.)
EXEMODE *File permissions on Main targets.
MODE Target-specific file permissions on Main targets (set from $(EXEMODE))
RANLIB Name of ranlib program, if any.

Variables above marked with "*" are used by the Main, Library, and LinkLibraries rules. Their values at the time the rules are invoked are used to set target-specific variables.

All other variables listed above are globally defined, and are used in actions that update Main and Library targets. This means that the global values of those variables are used, uness target-specific values have been set. (For instance, a target-specific MODE value is set by the Main rule.) The target-specific values always override global values.

Note that there are several ways to specify link libraries for executables:

For example:

    #In Jamrules:
              if $(UNIX) { X11LINKLIBS = -lXext -lX11 ; }
              if $(NT)   { X11LINKLIBS = libext.lib libX11.lib ; }

    #In Jamfile:

              Main xprog : xprog.c ;

              LinkFlags xprog : $(X11LINKLIBS) ;
              # Or: LINKLIBS on xprog$(SUFEXE) = $(X11LINKLIBS) ;

              LinkLibraries xprog : libxutil ;
              # Or: LinkLibraries xprog : libxutil : $(X11LINKLIBS) ;

              Library libxutil : xtop.c xbottom.c xutil.c ;
This example uses the Jam syntax "variable on target" to set a target-specific variable. In this way, only xprog will be linked with this special $(X11LINKLIBS), even if other executables were going to be built by the same Jamfile. Note that when you set a variable on a target, you have to specify the target identifer exactly, which in this case is the suffixed filename of the executable. The actual link command line on Unix, for example, would look something like this:
              cc -o xprog xprog.o libxutil.a -lXext -lX11

Compiling

Compiling of source files occurs normally as a byproduct of the Main or Library rules, which call the rules described here. These rules may also be called explicitly if the Main and Library behavior doesn't satisfy your requirements.

Objects Rule

The Main and Library rules call the Objects rule on source files. Compiled object files built by the Objects rule are a dependency of the obj pseudotarget, so "jam obj" will build object files used in Main and Library rules.

Target identifiers created by the Objects rule have grist set to $(SOURCE_GRIST). So given this Jamfile:

        SubDir TOP src lock ;
        Main locker : lock.c ;
       
the object file created is lock.o (or lock.obj) and its target identifier is <src!lock>lock.o (or <src!lock>lock.obj).

You can also call Objects directly. For example:

              Objects a.c b.c c.c ;
This compiles a.c into a.o, b.c into b.o, etc. The object file suffix is supplied by the Objects rule.

Object Rule

Objects gets its work done by calling the Object rule on each of the source files. You could use the Object rule directly. For example, on Unix, you could use:
              Object foo.o : foo.c ;

However, the Object rule does not provide suffixes, and it does not provide the grist needed to construct target identifiers if you are using the SubDir* rules. A portable and robust Jamfile would need to invoke Object thus:
          Object <src!util>foo$(SUFOBJ) : <src!util>foo.c ;
    
which is inelegant and clearly shows why using Objects is better than using Object.

If there's any advantage to the Object rule, it's that it doesn't require that the object name bear any relationship to the source. It is thus possible to compile the same file into different objects. For example:


              Object a.o : foo.c ;
              Object b.o : foo.c ;
              Object c.o : foo.c ;
This compiles foo.c (three times) into a.o, b.o, and c.o. Later examples show how this is useful.

The Object rule looks at the suffix of the source file and calls the appropriate rules to do the actual preprocessing (if any) and compiling needed to produce the output object file. The Object rule is capable of the generating of an object file from any type of source. For example:

              Object grammar$(SUFOBJ) : grammar.y ;
              Object scanner$(SUFOBJ) : scanner.l ;
              Object fastf$(SUFOBJ) : fastf.f ;
              Object util$(SUFOBJ) : util.c ;
An even more elegant way to get the same result is to let the Objects rule call Object:
              Objects grammar.y scanner.l fastf.f util.c ;
    

In addition to calling the compile rules, Object sets up a bunch of variables specific to the source and target files. (See Variables Used in Compiling, below.)

Cc, C++, Yacc, Lex, Fortran, As, etc. Rules

The Object rule calls compile rules specific to the suffix of the source file. (You can see which suffixes are supported by looking at the Object rule definition in Jambase.) Because the extra work done by the Object rule, it is not always useful to call the compile rules directly. But the adventurous user might attempt it. For example:

              Yacc grammar.c : grammar.y ;
              Lex scan.c : scan.l ;
              Cc prog.o : prog.c ;
These examples individually run yacc(1), lex(1), and the C compiler on their sources.

UserObject Rule

Any files with suffixes not understood by the Object rule are passed to the UserObject rule. The default definition of UserObject simply emits a warning that the suffix is not understood. This Jambase rule definition is intended to be overridden in Jamrules with one that recognizes the project-specific source file suffixes. For example:
    #In Jamrules:

              rule UserObject
              {
                  switch $(>)
                  {
                  case *.rc   : ResourceCompiler $(<) : $(>) ;
                  case *      : ECHO "unknown suffix on" $(>) ;
                  }
              }

              rule ResourceCompiler
              {
                  DEPENDS $(<) : $(>) ;
          Clean clean : $(<) ;
              }

              actions ResourceCompiler
              {
                  rc /fo $(<) $(RCFLAGS) $(>)
              }


    #In Jamfile:

              Library liblock : lockmgr.c ;
          if $(NT) { Library liblock : lock.rc ; }

In this example, the UserObject definition in Jamrules allows *.rc files to be handle as regular Main and Library sources. The lock.rc file is compiled into lock.obj by the "rc" command, and lock.obj is archived into a library with other compiled objects.

LibraryFromObjects Rule

Sometimes the Library rule's straightforward compiling of source into object modules to be archived isn't flexible enough. The LibraryFromObjects rule does the archiving (and deleting) job of the Library rule, but not the compiling. The user can make use of the Objects or Object rule for that. For example:
              LibraryFromObjects libfoo.a : max.o min.o ;
              Object max.o : maxmin.c ;
              Object min.o : maxmin.c ;
              ObjectCcFlags max.o : -DUSEMAX ;
              ObjectCcFlags min.o : -DUSEMIN ;
This Unix-specific example compiles the same source file into two different objects, with different compile flags, and archives them. (The ObjectCcFlags rule is described shortly.) Unfortunately, the portable and robust implementation of the above example is not as pleasant to read:

          SubDir TOP foo bar ;
              LibraryFromObjects libfoo$(SUFLIB) : <foo!bar>max$(SUFOBJ)
                                       <foo!bar>min$(SUFOBJ) ;
              Object <foo!bar>min$(SUFOBJ) : <foo!bar>maxmin.c ;
              Object <foo!bar>max$(SUFOBJ) : <foo!bar>maxmin.c ;
          ObjectCcFlags <foo!bar>min$(SUFOBJ) : -DUSEMIN ;
          ObjectCcFlags <foo!bar>max$(SUFOBJ) : -DUSEMAX ;
       
Note that, among other things, you must supply the library file suffix when using the LibraryFromObjects rule.

MainFromObjects Rule

Similar to LibraryFromObjects, MainFromObjects does the linking part of the Main rule, but not the compiling. MainFromObjects can be used when there are no objects at all, and everything is to be loaded from libraries. For example:
              MainFromObjects testprog ;
              LinkLibraries testprog : libprog ;
              Library libprog : main.c util.c ;
On Unix, say, this generates a link command that looks like:
              cc -o testprog libprog.a

Linking purely from libraries is something that doesn't work everywhere: it depends on the symbol "main" being undefined when the linker encounters the library that contains the definition of "main".

Variables Used in Compiling

The following variables control the compiling of source files:

C++ The C++ compiler command
CC The C compiler command
C++FLAGS
CCFLAGS
Compile flags, used to create or update compiled objects
SUBDIRC++FLAGS
SUBDIRCCFLAGS
Additonal compile flags for source files in this directory.
OPTIM Compiler optimization flag. The Cc and C++ actions use this as well as C++FLAGS or CCFLAGS.
HDRS Non-standard header directories; i.e., the directories the compiler will not look in by default and which therefore must be supplied to the compile command. These directories are also used by jam to scan for include files.
STDHDRS Standard header directories, i.e., the directories the compiler searches automatically. These are not passed to the compiler, but they are used by jam to scan for include files.
SUBDIRHDRS Additional paths to add to HDRS for source files in this directory.
LEX The lex(1) command
YACC The yacc(1) command

The Cc rule sets a target-specific $(CCFLAGS) to the current value of $(CCFLAGS) and $(SUBDIRCCFLAGS). Similarly for the C++ rule. The Object rule sets a target-specific $(HDRS) to the current value of $(HDRS) and $(SUBDDIRHDRS).

$(CC), $(C++), $(CCFLAGS), $(C++FLAGS), $(OPTIM), and $(HDRS) all affect the compiling of C and C++ files. $(OPTIM) is separate from $(CCFLAGS) and $(C++FLAGS) so they can be set independently.

$(HDRS) lists the directories to search for header files, and it is used in two ways: first, it is passed to the C compiler (with the flag -I prepended); second, it is used by HdrRule to locate the header files whose names were found when scanning source files. $(STDHDRS) lists the header directories that the C compiler already knows about. It does not need passing to the C compiler, but is used by HdrRule.

Note that these variables, if set as target-specific variables, must be set on the target, not the source file. The target file in this case is the object file to be generated. For example:

              Library libximage : xtiff.c xjpeg.c xgif.c ;

              HDRS on xjpeg$(SUFOBJ) = /usr/local/src/jpeg ;
              CCFLAGS on xtiff$(SUFOBJ) = -DHAVE_TIFF ;
This can be done more easily with the rules that follow.

ObjectCcFlags, ObjectC++Flags, ObjectHdrs Rules

$(CCFLAGS), $(C++FLAGS) and $(HDRS) can be set on object file targets directly, but there are rules that allow these variables to be set by referring to the original source file name, rather than to the derived object file name. ObjectCcFlags adds object-specific flags to the $(CCFLAGS) variable, ObjectC++Flags adds object-specific flags to the $(C++FLAGS) variable, and ObjectHdrs add object-specific directories to the $(HDRS) variable. For example:
    #In Jamrules:
        if $(NT) { CCFLAGS_X = /DXVERSION ;
               HDRS_X = \\\\SPARKY\\X11\\INCLUDE\\X11 ;
                 }

    #In Jamfile:
              Main xviewer : viewer.c ;
              ObjectCcFlags viewer.c : $(CCFLAGS_X) ;
              ObjectHdrs viewer.c : $(HDRS_X) ;
The ObjectCcFlags and ObjectHdrs rules take .c files as targets, but actually set $(CCFLAGS) and $(HDRS) values on the .obj (or .o) files. As a result, the action that updates the target .obj file uses the target-specific values of $(CCFLAGS) and $(HDRS).

SubDirCcFlags, SubDirC++Flags, SubDirLinkFlags, SubDirHdrs, SubDirObjects Rules

SubDirCcFlags, SubDirC++Flags and SubDirHdrs set the values of $(SUBDIRCCFLAGS), $(SUBDIRC++FLAGS), $(SUBDIRLINKFLAGS) and $(SUBDIRHDRS) which are used by the Cc, C++, Link, and Object rules when setting the target-specific values for $(CCFLAGS), $(C++FLAGS), $(LINKFLAGS) and $(HDRS). The SubDir rule clears these variables out, and thus they provide directory-specific values of $(CCFLAGS), $(C++FLAGS) and $(HDRS). The SubDirObjects rule sets the default location for all object files generated by the Object rule in a specific directory. For example:
    #In Jamrules:
          GZHDRS = $(TOP)/src/gz/include ;
          GZFLAG = -DGZ ;
          OBJS = $(TOP)/objs

    #In Jamfile:
          SubDir TOP src gz utils ;

          SubDirHdrs $(GZHDRS) ;
          SubDirCcFlags $(GZFLAG) ;
          SubDirObjects $(OBJS) ;

          Library libgz : gizmo.c ;
          Main gizmo : main.c ;
          LinkLibraries gizmo : libgz ;
All .c files in this directory will be compiled with $(GZFLAG) as well as the default $(CCFLAG), and the include paths used on the compile command will be $(GZHDRS) as well as the default $(HDRS). All objects will be generated in $(TOP)/objs.

Header File Processing

One of the functions of the Object rule is set up scanning of source files for (C style) header file inclusions. To do so, it sets the special variables $(HDRSCAN) and $(HDRRULE) as target-specific variables on the source file. The presence of these variables triggers a special mechanism in jam for scanning a file for header file inclusions and invoking a rule with the results of the scan. The $(HDRSCAN) variable is set to an egrep(1) pattern that matches "#include" statements in C source files, and the $(HDRRULE) variable is set to the name of the rule that gets invoked as such:
              $(HDRRULE) source-file : included-files ;

This rule is supposed to set up the dependencies between the source file and the included files. The Object rule uses HdrRule to do the job. HdrRule itself expects another variable, $(HDRSEARCH), to be set to the list of directories where the included files can be found. Object does this as well, setting $(HDRSEARCH) to $(HDRS) and $(STDHDRS).

The header file scanning occurs during the "file binding" phase of jam, which means that the target-specific variables (for the source file) are in effect. To accomodate nested includes, one of the HdrRule's jobs is to pass the target-specific values of $(HDRRULE), $(HDRSCAN), and $(HDRSEARCH) onto the included files, so that they will be scanned as well.

HdrRule Rule

Normally, HdrRule is not invoked directly; the Object rule (called by Main and Library) invokes it.

If there are special dependencies that need to be set, and which are not set by HdrRule itself, you can define another rule and let it invoke HdrRule. For example:

    #In Jamrules:
              rule BuiltHeaders
              {
                      DEPENDS $(>) : mkhdr$(SUFEXE) ;
                      HdrRule $(<) : $(>) ;
              }

    #In Jamfile:
              Main mkhdr : mkhdr.c ;
              Main ugly : ugly.c ;

              HDRRULE on ugly.c = BuiltHeaders ;

This example just says that the files included by "ugly.c" are generated by the program "mkhdr", which can be built from "mkhdr.c". During the binding phase, jam will scan ugly.c, and if it finds an include file, ughdr.h, for example, it will automatically invoke the rule:
              BuiltHeaders ugly.c : ughdr.h ;
       
By calling HdrRule at the end of BuiltHeaders, all the gadgetry of HdrRule takes effect and it doesn't need to be duplicated.

Variables Used for Header Scanning

HDRPATTERN Default scan pattern for "include" lines.
HDRSCAN Scan pattern to use. This is a special variable: during binding, if both HDRSCAN and HDRRULE are set, scanning is activated on the target being bound. The HdrRule and Object rules sets this to $(HDRPATTERN) on their source targets.
HDRRULE Name of rule to invoked on files found in header scan. The HdrRule and Object rules set this to "HdrRule" on their source targets. This is also a special variable; it's the only jam variable that can hold the name of a rule to be invoked.
HDRSEARCH Search paths for files found during header scanning. This is set from $(HDRS) and $(STDHDRS), which are described in the Compiling section. jam will search $(HDRSEARCH) directories for the files found by header scans.

The Object rule sets HDRRULE and HDRSCAN specifically for the source files to be scanned, rather than globally. If they were set globally, jam would attempt to scan all files, even library archives and executables, for header file inclusions. That would be slow and probably not yield desirable results.

Copying Files

File Rule

The File rule copies one file to another. The target name needn't be the same as the source name. For example:
    switch $(OS)
    {
           case NT*  : File config.h : confignt.h ;
       case *    : File config.h : configunix.h ;
    }
    LOCATE on config.h = $(LOCATE_SOURCE) ;
This creates a config.h file from either confignt.h or configunix.h, depending on the current build platform.

The File rule does not use the LOCATE_SOURCE variable set by the SubDir rule (although it does use SEARCH_SOURCE), which means you have to set the copied file's output directory yourself. That's done by setting the special LOCATE variable on the target, as shown above, or with the MakeLocate rule described below.

Bulk Rule

The Bulk rule is a shorthand for many invocations of the File rule when all files are going to the same directory. For example:
    #In Jamrules:
              DISTRIB_GROB = d:\\distrib\\grob ;

    #In Jamfile:
              Bulk $(DISTRIB_GROB) : grobvals.txt grobvars.txt ;
This causes gobvals.txt and grobvars.txt to be copied into the $(DISTRIB_GROB) directory.

HardLink Rule

The Unix-only HardLink rule makes a hard link (using ln(1)) from the source to the target, if there isn't one already. For example:
              HardLink config.h : configunix.h ;

Shell Rule

The Shell rule is like the File rule, except that on Unix it makes sure the first line of the target is "#!/bin/sh" and sets the permission to make the file executable. For example:
              Shell /usr/local/bin/add : add.sh ;

You can also use $(SHELLHEADER) to dictate what the first line of the copied file will be. For example:

              Shell /usr/local/bin/add : add.awk ;
              SHELLHEADER on /usr/local/bin/add = "#!/bin/awk -f" ;

This installs an awk(1) script.

Variables Used When Copying Files

FILEMODE Default file permissions for copied files
SHELLMODE Default file permissions for Shell rule targets
MODE File permissions set on files copied by File, Bulk, and Shell rules. File and Shell sets a target-specific MODE to the current value of $(FILEMODE) or $(SHELLMODE), respectively.
SHELLHEADER String to write in first line of Shell targets (default is #!/bin/sh).

Installing Files

Jambase provides a set of Install* rules to copy files into an destination directory and set permissions on them. On Unix, the install(1) program is used. If the destination directory does not exist, jam creates it first.

All files copied with the Install* rules are dependencies of the install pseudotarget, which means that the command "jam install" will cause the installed copies to be updated. Also, "jam uninstall" will cause the installed copies to be removed.

The Install* rules are:

InstallBin Copies file and sets its permission to $(EXEMODE). You must specify the suffixed executable name. E.g.:
InstallBin $(BINDIR) : thing$(SUFEXE) ;
           
InstallFile Copies file and sets its permission to $(FILEMODE). E.g.:
InstallFile $(DESTDIR) : readme.txt ;
           
InstallLib Copies file and sets its permission to $(FILEMODE). You must specify the suffixed library name. E.g.:
InstallLib $(LIBDIR) : libzoo$(SUFLIB) ;
           
InstallMan Copies file into the mann subdirectory of the target directory and sets its permission to $(FILEMODE). E.g., this copies foo.5 into the $(DESTDIR)/man5 directory:
InstallMan $(DESTDIR) : foo.5 ;
           
InstallShell Copies file and sets its permission to $(SHELLMODE). E.g.:
InstallShell $(DESTDIR) : startup ;
           

Variables

The following variables control the installation rules:

INSTALL The install program (Unix only)
FILEMODE Default file permissions on readable files.
EXEMODE Default file permission executable files.
SHELLMODE Default file permission on shell script files.
MODE Target-specific file permissions

The Install rules set a target-specific MODE to the current value of $(FILEMODE), $(EXEMODE), or $(SHELLMODE), depending on which Install rule was invoked.

The directory variables are just defined for convenience: they must be passed as the target to the appropriate Install rule. The $(INSTALL) and mode variables must be set (globally) before calling the Install rules in order to take effect.

Miscellaneous Rules

Clean Rule

The Clean rule defines files to be removed when you run "jam clean". Any site-specific build rules defined in your Jamrules should invoke Clean so that outputs can be removed. E.g.,

    rule ResourceCompiler
    {
       DEPENDS $(<) : $(>) ;
       Clean clean : $(<) ;
    }

Most Jambase rules invoke the Clean rule on their built targets, so "jam clean" will remove all compiled objects, libraries, executables, etc.

MakeLocate Rule

MakeLocate is a single convenient rule that creates a directory, sets LOCATE on a target to that directory, and makes the directory a dependency of the target. It is used by many Jambase rules, and can be invoked directly, e.g.:
        GenFile data.tbl : hxtract data.h ;
        MakeLocate data.tbl : $(TABLEDIR) ;
      
In this example, the File rule creates data.tbl from data.h. The MakeLocate causes data.tbl to be written into the $(TABLEDIR) directory; and if the directory doesn't exist, it is created first.

The MakeLocate rule can be used to build targets introduced by Main, Library or SharedLibrary at a specific location.

        Main myprog : main.c ;
        MakeLocate myprog : $(OUTPUT) ;
      
In the example above the program 'myprog' is built at the location specified by the variable OUTPUT.

The MakeLocate rule invokes another Jambase rule, MkDir, to (recursively) create directories. MkDir uses the $(MKDIR) variable to determine the platform-specific command that creates directories.

RmTemps Rule

Some intermediate files are meant to be temporary. The RmTemps rule can be used to cause jam to delete them after they are used.

RmTemps must be:

For example:
        SubDir TOP src big ;
        GenFile big.y : joinfiles part1.y part2.y part3.y ;
        Main bigworld : main.c big.y ;
        RmTemps bigworld$(SUFEXE) : <src!big>big.y ;
    
This causes big.y to be deleted after it has been used to create the bigworld executable. The exact target identifier of big.y is <src!big>big.y (the GenFile and Main rules tack on the grist automatically); the exact target identifier of the bigworld executable is bigworld$(SUFEXE).


Jambase Reference

Jambase is a base set of Jam rules which provide roughly make-like functionality for jam, the Jam executable program. This document is a reference guide to the rules, pseudotargets, and variables defined in Jambase for use in Jamfiles.

Jambase Rules

As obj.o : source.s ;

Assemble the file source.s. Called by the Object rule.
Bulk directory : sources ;
Copies sources into directory.
Cc object : source ;
Compile the file source into object, using the C compiler $(CC), its flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS). Called by the Object rule.
C++ obj.o : source.cc ;
Compile the C++ source file source.cc. Called by the Object rule.
Chmod target ;
(Unix and VMS only.) Change file permissions on target to target-specific $(MODE) value set by Link, File, Install*, and Shell rules.
Clean clean : targets ;
Removes existing targets when clean is built. clean is not a dependency of all, and must be built explicitly for targets to be removed.
FDefines defines ;
Expands a list of definitions into a list of compiler (or preprocessor) switches (such as -Dsymbol=val on Unix) to pass the definitions.
File target : source ;
Copies source into target.
FIncludes dirs ;
Expands a list of directories into a list of compiler (or preprocessor) switches (such as -Idir on Unix) to add the directories to the header inclusion search path.
Fortran obj.o : source.f ;
Compile the Fortran source file source.f. Called by the Object rule.
FQuote files ;
Returns each of files suitably quoted so as to hide shell metacharacters (such as whitespace and filename matching wildcards) from the shell.

GenFile target : image sources ;

Runs the command "image target sources" to create target from sources and image. (where image is an executable built by the Main rule.)
HardLink target : source ;
Makes target a hard link to source, if it isn't one already. (Unix only.)
HdrRule source : headers ;
Arranges the proper dependencies when the file source includes the files headers through the "#include" C preprocessor directive.

This rule is not intended to be called explicitly. It is called automatically during header scanning on sources handled by the Object rule (e.g., sources in Main or Library rules).

InstallBin dir : sources ;
Copy sources into dir with mode $(EXEMODE).
InstallLib dir : sources ;
Copy sources into dir with mode $(FILEMODE).
InstallMan dir : sources ;
Copy sources into the appropriate subdirectory of dir with mode $(FILEMODE). The subdirectory is mans, where s is the suffix of each of sources.
InstallShell dir : sources ;
Copy sources into dir with mode $(SHELLMODE).
Lex source.c : source.l ;
Process the lex(1) source file source.l and rename the lex.yy.c to source.c. Called by the Object rule.
Library library : sources ;
Compiles sources and archives them into library. The intermediate objects are deleted. Calls Objects and LibraryFromObjects.

If Library is invoked with no suffix on library, the $(SUFLIB) suffix is used.

LibraryFromObjects library : objects ;
Archives objects into library. The objects are then deleted.

If library has no suffix, the $(SUFLIB) suffix is used.

Link image : objects ;
Links image from objects and sets permissions on image to $(EXEMODE). Image must be actual filename; suffix is not supplied. Called by Main.
LinkLibraries image : libraries : flags ;
Makes image depend on libraries and includes them during the linking. The flags are added to the link command line. The libraries must be static libraries built in this project.

Image may be referenced without a suffix in this rule invocation; LinkLibraries supplies the suffix. Must follow a Main, Library or SharedLibrary rule for the same target

LinkSharedLibraries image : libraries ;
Makes image depend on libraries and includes them during the linking. libraries must be shared libraries built in this project

Image may be referenced without a suffix in this rule invocation; LinkSharedLibraries supplies the suffix. Mustfollow a Main, Library or SharedLibrary rule for the same target

Main image : sources ;
Compiles sources and links them into image. Calls Objects and MainFromObjects.

Image may be referenced without a suffix in this rule invocation; Main supplies the suffix.

MainFromObjects image : objects ;
Links objects into image. Dependency of exe. MainFromObjects supplies the suffix on image filename.
MakeLocate target : dir ;
Creates dir and causes target to be built into dir.
MkDir dir ;
Creates dir and its parent directories.
Object object : source ;
Compiles a single source file source into object. The Main and Library rules use this rule to compile source files.

Causes source to be scanned for "#include" directives and calls HdrRule to make all included files dependedencies of object.

Calls one of the following rules to do the actual compiling, depending on the suffix of source:

             *.c:   Cc 
             *.cc:  C++ 
             *.cpp: C++
             *.C:   C++ 
             *.l:   Lex 
             *.y:   Yacc
             *.*:   UserObject
ObjectC++Flags source : flags ;
ObjectCcFlags source : flags ;
Add flags to the source-specific value of $(CCFLAGS) or $(C++FLAGS) when compiling source. Any file suffix on source is ignored.
ObjectDefines object : defines ;
Adds preprocessor symbol definitions to the (gristed) target-specific $(CCDEFS) for the object.
ObjectHdrs source : dirs ;
Add dirs to the source-specific value of $(HDRS) when scanning and compiling source. Any file suffix on source is ignored.
Objects sources ;
For each source file in sources, calls Object to compile the source file into a similarly named object file.
RmTemps targets : sources ;
Marks sources as temporary with the TEMPORARY rule, and deletes sources once targets are built. Must be the last rule invoked on targets. Used internally by LibraryFromObjects rule.
Setuid images ;
Sets the setuid bit on each of images after linking. (Unix only.) SharedLibrary library : sources : flags ;
Compiles sources and links them into library. The flags are added to the link command line. Calls Objects and SharedLibraryFromObjects.

If SharedLibrary is invoked with no suffix on library, the $(SUFDLL) suffix is used.

SoftLink target : source ;
Makes target a symbolic link to source, if it isn't one already. (Unix only.)
SubDir TOP d1 ... dn ;
Sets up housekeeping for the source files located in $(TOP)/d1/.../dn:

TOP is the name of a variable; d1 thru dn are elements of a directory path.

SubDirC++Flags flags ;
SubDirCcFlags flags ;
Adds flags to the compiler flags for source files in SubDir's directory.
SubDirHdrs d1 ... dn ;
Adds the path d1/.../dn/ to the header search paths for source files in SubDir's directory. d1 through dn are elements of a directory path.
SubInclude VAR d1 ... dn ;
Reads the Jamfile in $(VAR)/d1/.../dn/.
Shell image : source ;
Copies source into the executable sh(1) script image. Ensures that the first line of the script is $(SHELLHEADER) (default #!/bin/sh).
Undefines images : symbols ;
Adds flags to mark symbols as undefined on link command for images. Images may be referenced unsuffixed; the Undefines rule supplies the suffix.
UserObject object : source ;
This rule is called by Object for source files with unknown suffixes, and should be defined in Jamrules with a user-provided rule to handle the source file types not handled by the Object rule. The Jambase UserObject rule merely issues a complaint when it encounters source with files suffixes it does not recognize.
Yacc source.c : source.y ;
Process the yacc(1) file source.y and renamed the resulting y.tab.c and y.tab.h to source.c. Produces a y.tab.h and renames it to source.h. Called by the Object rule.

Jambase Pseudotargets

There are two kinds of Jam targets: file targets and pseudotargets. File targets are objects that can be found in the filesystem. Pseudotargets are symbolic, and usually represent other targets. Most Jambase rules that define file targets also define pseudotargets which are dependent on types of file targets. The Jambase pseudotargets are:

exe Executables linked by the Main or MainFromObjects rules
lib Libraries created by the Library or LibraryFromObjects rules
obj Compiled objects used to create Main or Library targets
dirs Directories where target files are written
file Files copied by File and Bulk rules
shell Files copied by Shell rule
clean Removal of built targets (except files copied by Install* rules)
install Files copied by Install* rules
uninstall Removal of targets copied by Install* rules

In addition, Jambase makes the jam default target "all" depend on "exe", "lib", "obj", "files", and "shell".

Jambase Variables

Most of the following variables have default values for each platform; refer to the Jambase file to see what those defaults are.

ALL_LOCATE_TARGET

Alternative location of built targets. By default, Jambase rules locate built targets in the source tree. By setting $(ALL_LOCATE_TARGET) in Jamrules, you can cause jam to write built targets to a location outside the source tree.
ALL_LOCATE_OBJECTS
Alternative location of built objects. By default, Jambase rules locate built targets in the source tree. By setting $(ALL_LOCATE_OBJECTS) in Jamrules, you can cause jam to write built objects to a location outside the source tree.
AR
The archive command used to update Library and LibraryFromObjects targets.
AS
The assembler for As rule targets.
ASFLAGS
Flags handed to the assembler for As.
AWK
The name of awk interpreter, used when copying a shell script for the Shell rule.
BCCROOT
Selects Borland compile and link actions on NT.
BINDIR
Not longer used. (I.e., used only for backward compatibility with the obsolete INSTALLBIN rule.)
CC
C compiler used for Cc rule targets.
CCFLAGS
Compile flags for Cc rule targets. The Cc rule sets target-specific $(CCFLAGS) values on its targets.
C++
C++ compiler used for C++ rule targets.
C++FLAGS
Compile flags for C++ rule targets. The C++ rule sets target-specific $(C++FLAGS) values on its targets.
CHMOD
Program (usually chmod(1)) used to set file permissions for Chmod rule.
CP
The file copy program, used by File and Install* rules.
CRELIB
If set, causes the Library rule to invoke the CreLib rule on the target library before attempting to archive any members, so that the library can be created if needed.
CW
On Macintosh, the root of the Code Warrior Pro 5 directory.
DEFINES
Preprocessor symbol definitions for Cc and C++ rule targets. The Cc and C++ rules set target-specific $(CCDEFS) values on their targets, based on $(DEFINES). (The "indirection" here is required to support compilers, like VMS, with baroque command line syntax for setting symbols).
DOT
The operating system-specific name for the current directory.
DOTDOT
The operating system-specific name for the parent directory.
EXEMODE
Permissions for executables linked with Link, Main, and MainFromObjects, on platforms with a Chmod action.
FILEMODE
Permissions for files copied by File or Bulk, on platforms with a Chmod action.
FORTRAN
The Fortran compiler used by Fortran rule.
FORTRANFLAGS
Fortran compiler flags for Fortran rule targets.
GROUP
(Unix only.) The group owner for Install* rule targets.
HDRGRIST
If set, used by the HdrRule to distinguish header files with the same name in diffrent directories.
HDRPATTERN
A regular expression pattern that matches C preprocessor "#include" directives in source files and returns the name of the included file.
HDRRULE
Name of the rule to invoke with the results of header file scanning. Default is "HdrRule".

This is a jam-special variable. If both HDRRULE and HDRSCAN are set on a target, that target will be scanned for lines matching $(HDRSCAN), and $(HDDRULE) will be invoked on included files found in the matching $(HDRSCAN) lines.

HDRS
Directories to be searched for header files. This is used by the Object rule to: (See STDHDRS.)
HDRSCAN
Regular expression pattern to use for header file scanning. The Object rule sets this to $(HDRPATTERN). This is a jam-special variable; see HDRRULE.
HDRSEARCH
Used by the HdrRule to fix the list of directories where header files can be found for a given source file.
INSTALLGRIST
Used by the Install* rules to grist paths to installed files; defaults to "installed".
JAMFILE
Default is "Jamfile"; the name of the user-written rules file found in each source directory.
JAMRULES
Default is "Jamrules"; the name of a rule definition file to be read in at the first SubDir rule invocation.
KEEPOBJS
If set, tells the LibraryFromObjects rule not to delete object files once they are archived.
LEX
The lex(1) command and flags.
LIBDIR
Not longer used. (I.e., used only for backward compatibility with the obsolete INSTALLLIB rule.)
LINK
The linker. Defaults to $(CC).
LINKFLAGS
Flags handed to the linker. Defaults to $(CCFLAGS).
LINKLIBS
List of external libraries to link with. The target image does not depend on these libraries.
LN
The hard link command for HardLink rule.
LOCATE_SOURCE
Used to set the location of generated source files. The Yacc, Lex, and GenFile rules set LOCATE on their targets to $(LOCATE_SOURCE). $(LOCATE_SOURCE) is initialized by the SubDir rule to the source directory itself. (Also, see ALL_LOCATE_TARGET.)
LOCATE_TARGET
Used to set the location of built binary targets. The Object rule, and hence the Main and Library rules, set LOCATE on their targets to $(LOCATE_TARGET). $(LOCATE_TARGET) is initialized by the SubDir rule to the source directory itself. (See ALL_LOCATE_TARGET.)
MANDIR
Not longer used. (I.e., used only for backward compatibility with the obsolete INSTALLMAN rule.)
MKDIR
The 'create directory' command used for the MkDir rule.
MODE
The target-specific file mode (permissions) for targets of the Shell, Setuid, Link, and Install* rules. Used by the Chmod action; hence relevant to NT and VMS only.
MSVC
Selects Microsoft Visual C 16-bit compile & link actions on NT.
MSVCNT
Selects Microsoft Visual C NT 5.0 and earlier compile & link actions on NT.
MSVCDIR
Selects Microsoft Visual C NT 6.0 and later compile & link actions on NT. These are identical to versions 5.0 and earlier -- it just seems Microsoft changed the name of the variable.
MV
The file rename command and options.
NEEDLIBS
The list of libraries used when linking an executable. Used by the Link rule.
NOARSCAN
If set, indicates that library members' timestamps can't be found, and prevents the individual objects from being deleted, so that their timestamps can be used instead.
NOARUPDATE
If set, indicates that libraries can't be updated, but only created whole.
OPTIM
The C compiler flag for optimization, used by Cc and C++ rules.
OSFULL
The concatenation of $(OS)$(OSVER)$(OSPLAT), used when jam builds itself to determine the target binary directory. $(OS) and $(OSPLAT) are determined by jam at its compile time (in jam.h). $(OSVER) can optionally be set by the user.
OWNER
The owner of installed files. Used by Install* rules.
RANLIB
The name of the ranlib command. If set, causes the Ranlib action to be applied after the Archive action to targets of the Library rule.
RELOCATE
If set, tells the Cc rule to move the output object file to its target directory because the cc command has a broken -o option.
RM
The command and options to remove a file.
SEARCH_SOURCE
The directory to find sources listed with Main, Library, Object, Bulk, File, Shell, InstallBin, InstallLib, and InstallMan rules. This works by setting the jam-special variable SEARCH to the value of $(SEARCH_SOURCE) for each of the rules' sources. The SubDir rule initializes SEARCH_SOURCE for each directory.
SHELLHEADER
A string inserted to the first line of every file created by the Shell rule.
SHELLMODE
Permissions for files installed by Shell rule.
SOURCE_GRIST
Set by the SubDir to a value derived from the directory name, and used by Objects and related rules as 'grist' to perturb file names.
STDHDRS
Directories where headers can be found without resorting to using the flag to the C compiler. The $(STDHDRS) directories are used to find headers during scanning, but are not passed to the compiler commands as -I paths.
SUBDIR
The path from the current directory to the directory last named by the SubDir rule.
TOP
The path from the current directory to the directory that has the Jamrules file. Used by the SubDir rule.
SUFEXE
The suffix for executable files, if none provided. Used by the Main rule.
SUFLIB
The suffix for libraries. Used by the Library and related rules.
SUFOBJ
The suffix for object files. Used by the Objects and related rules.
UNDEFFLAG
The flag prefixed to each symbol for the Undefines rule (i.e., the compiler flag for undefined symbols).
WATCOM
Selects Watcom compile and link actions on OS2.
YACC
The yacc(1) command.
YACCFILES
The base filename generated by yacc(1).
YACCFLAGS
The yacc(1) command flags.
YACCGEN
The suffix used on generated yacc(1) output.


Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
Copyright 2006-2008 Marc Boris Duerner
Comments to info@perforce.com
Last updated: Nov 5, 2008

Copyright © 2003-2007 The Pt Development Team
Pt 1.0