This section will describe the basics of the Boost.Jam language—just enough for writing Jamfiles. For more information, please see the Boost.Jam documentation.
Boost.Jam has an interpreted, procedural language. On the lowest level, a Boost.Jam program consists of variables and rules (the Jam term for functions). They are grouped into modules—there is one global module and a number of named modules. Besides that, a Boost.Jam program contains classes and class instances.
Syntantically, a Boost.Jam program consists of two kind of elements—keywords (which have a special meaning to Boost.Jam) and literals. Consider this code:
a = b ;
which assigns the value b
to the variable a
. Here, =
and ;
are
keywords, while a
and b
are
literals.
All syntax elements, even keywords, must be separated by spaces. For
example, omitting the space character before ;
will lead to a syntax error.
If you want to use a literal value that is the same as some keyword, the value can be quoted:
a = "=" ;
All variables in Boost.Jam have the same
type—list of strings. To define a variable one assigns a value to
it, like in the previous example. An undefined variable is the same as a
variable with an empty value. Variables can be accessed using the
$(
syntax. For example:
variable
)
a = $(b) $(c) ;
Rules are defined by specifying the rule name, the parameter names, and the allowed value list size for each parameter.
ruleexample
(parameter1
:parameter2 ?
:parameter3 +
:parameter4 *
) { # rule body }
When this rule is called, the list passed as the first argument must have exactly one value. The list passed as the second argument can either have one value of be empty. The two remaining arguments can be arbitrarily long, but the third argument may not be empty.
The overview of Boost.Jam language statements is given below:
helper 1 : 2 : 3 ; x = [ helper 1 : 2 : 3 ] ;
This code calls the named rule with the specified arguments. When the result of the call must be used inside some expression, you need to add brackets around the call, like shown on the second line.
if cond { statements } [ else { statements } ]
This is a regular if-statement. The condition is composed of:
Literals (true if at least one string is not empty)
Comparisons: a
where operator
boperator
is one of
=
, !=
, <
,
>
, <=
or >=
. The
comparison is done pairwise between each string in the left and
the right arguments.
Logical operations: ! a
, a && b
,
a || b
Grouping: ( cond )
for var in list { statements }
Executes statements for each element in list, setting the variable
var
to the element value.
while cond { statements }
Repeatedly execute statements while cond remains true upon entry.
return values ;
This statement should be used only inside a rule and returns
values
to the caller of the rule.
importmodule
; importmodule
:rule
;
The first form imports the specified module. All rules from that
module are made available using the qualified name:
. The second
form imports the specified rules only, and they can be called using
unqualified names.
module
.rule
Sometimes, you need to specify the actual command lines to be used when creating targets. In the jam language, you use named actions to do this. For example:
actions create-file-from-another { create-file-from-another $(<) $(>) }
This specifies a named action called
create-file-from-another
. The text inside braces is the
command to invoke. The $(<)
variable will be
expanded to a list of generated files, and the $(>)
variable will be expanded to a list of source files.
To adjust the command line flexibly, you can define a rule with the same name as the action and taking three parameters—targets, sources and properties. For example:
rule create-file-from-another ( targets * : sources * : properties * ) { if <variant>debug in $(properties) { OPTIONS on $(targets) = --debug ; } } actions create-file-from-another { create-file-from-another $(OPTIONS) $(<) $(>) }
In this example, the rule checks if a certain build property is specified.
If so, it sets the variable OPTIONS
that is then used
inside the action. Note that the variables set "on a target" will be
visible only inside actions building that target, not globally. Were
they set globally, using variable named OPTIONS
in
two unrelated actions would be impossible.
More details can be found in the Jam reference, the section called “Rules”.