mirror of
https://github.com/boostorg/build.git
synced 2026-02-15 13:02:11 +00:00
2106 lines
81 KiB
HTML
2106 lines
81 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
<head>
|
||
|
||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||
|
||
<title>Boost Build System</title>
|
||
</head>
|
||
|
||
<body bgcolor="#FFFFFF" text="#000000">
|
||
|
||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align= "center" width="277" height="86">
|
||
|
||
<h1>Boost Build System</h1>
|
||
|
||
<h2><a name="synopsis">Synopsis</a></h2>
|
||
|
||
<p>Boost.Build is a system for large project software construction built on
|
||
Boost Jam, a descendant of "<a
|
||
href="http://www.perforce.com/jam/jam.html">Perforce Jam</a>", an
|
||
open-source make replacement<a href="#1">[1]</a>. Key features are:
|
||
|
||
<ul>
|
||
<li>A simple target description language
|
||
|
||
<li>Build with your choice (or multiple) toolsets from a single command
|
||
invocation
|
||
|
||
<li>Build your choice of basic variants (e.g. debug, release, profile...)
|
||
and subvariant modifications (e.g. inlining off) from a single command
|
||
invocation
|
||
|
||
<li>``Feature Normalization'' allows target configurations to be
|
||
described independently from the toolset used
|
||
|
||
<li>Modular toolset description files allow build instructions for
|
||
different toolsets to be described independently
|
||
|
||
<li>Multiple subproject support
|
||
|
||
<li>Automatic building of subproject dependencies
|
||
</ul>
|
||
|
||
<p><a href="#design_criteria">Here</a> are some of the design criteria that
|
||
led to these features.
|
||
|
||
<h2>Table of Contents</h2>
|
||
|
||
<ul>
|
||
<li><a href="#synopsis">Synopsis</a>
|
||
|
||
<li>
|
||
<a href="#getting_started">Getting Started</a>
|
||
|
||
<ul>
|
||
<li><a href="#installing_jam">Installing Jam</a>
|
||
|
||
<li><a href="#initiating">Initiating a Build</a>
|
||
|
||
<li><a href="#setting_variables">Setting Jam Variables</a>
|
||
|
||
<li><a href="#example_jamfile">An Example Jamfile</a>
|
||
|
||
<li><a href="#support_files">Support Files</a>
|
||
</ul>
|
||
|
||
<li>
|
||
<a href="#design">Basic Design and Terminology</a>
|
||
|
||
<ul>
|
||
<li><a href="#project_subproject">Projects and Subprojects</a>
|
||
|
||
<li><a href="#targets">Targets</a>
|
||
|
||
<li><a href="#features">Features and Properties</a>
|
||
|
||
<li><a href="#variants">Build Variants</a>
|
||
|
||
<li><a href="#subvariants">Subvariants</a>
|
||
|
||
<li><a href="#dependents">Dependent Targets</a>
|
||
</ul>
|
||
|
||
<li>
|
||
<a href="#usage">Usage</a>
|
||
|
||
<ul>
|
||
<li>
|
||
<a href="#command_line">The Command-Line</a>
|
||
|
||
<ul>
|
||
<li><a href="#user_targets">User Targets</a>
|
||
|
||
<li><a href="#user_globals">Global Variables</a>
|
||
</ul>
|
||
|
||
<li>
|
||
<a href="#subproject_jamfiles">Subproject Jamfiles</a>
|
||
|
||
<ul>
|
||
<li><a href="#subproject_rule">The <tt>subproject</tt> Rule</a>
|
||
<li><a href="#main_targets">Describing Main Targets</a>
|
||
<li><a href="#template_targets">Describing Template Targets</a>
|
||
<li><a href="#stage_targets">Describing Stage Targets</a>
|
||
<li><a href="#jamfile_example">Example</a>
|
||
</ul>
|
||
|
||
<li><a href="#feature_description">Feature Descriptions</a>
|
||
|
||
<li><a href="#variant_description">Variant Descriptions</a>
|
||
|
||
<li>
|
||
<a href="#toolset_description">Toolset Description Files</a>
|
||
|
||
<ul>
|
||
<li><a href="#toolset_example">Example</a>
|
||
</ul>
|
||
</ul>
|
||
|
||
<li>
|
||
<a href="#internals">Internals</a>
|
||
|
||
<ul>
|
||
<li><a href="#jam_fundamentals">Jam Fundamentals</a>
|
||
|
||
<li>
|
||
<a href="#core_extensions">Core Jam Extensions</a>
|
||
|
||
<ul>
|
||
<li><a href="#variable_quoting">Command-line and Environment Variable Quoting</a>
|
||
<li><a href="#jambase_replacement">Jambase Replacement</a>
|
||
<li><a href="#rule_indirection">Rule Indirection</a>
|
||
<li><a href="#argument_lists">Argument Lists</a>
|
||
|
||
<li>
|
||
<a href="#module_support">Module Support</a>
|
||
|
||
<ul>
|
||
<li><a href="#module_declaration">Declaration</a>
|
||
<li><a href="#module_locals">Local Variables</a>
|
||
<li><a href="#local_rules">Local Rules</a>
|
||
<li><a href="#RULENAMES_rule">The <tt>RULENAMES</tt> rule</a>
|
||
<li><a href="#IMPORT_rule">The <tt>IMPORT</tt> rule</a>
|
||
<li><a href="#EXPORT_rule">The <tt>EXPORT</tt> rule</a>
|
||
<li><a href="#CALLER_MODULE_rule">The <tt>CALLER_MODULE</tt> rule</a>
|
||
</ul>
|
||
|
||
<li><a href="#local_foreach">Local for Loop Variables</a>
|
||
<li><a href="#while_loops">While Loops</a>
|
||
<li><a href="#negative_indexing">Negative Indexing</a>
|
||
<li><a href="#BINDRULE">Target Binding Detection</a>
|
||
<li><a href="#FAIL_EXPECTED">Return Code Inversion</a>
|
||
<li><a href="#NOCARE">Ignoring Return Codes</a>
|
||
<li><a href="#SUBST_rule">The <tt>SUBST</tt> Rule</a>
|
||
<li><a href="#JAM_VERSION">The <tt>JAM_VERSION</tt> global variable</a>
|
||
<li>
|
||
<a href="#debugging_support">Debugging Support</a>
|
||
|
||
<ul>
|
||
<li><a href="#BACKTRACE_rule">The BACKTRACE rule</a>
|
||
<li><a href="#profiling">Profiling</a>
|
||
<li><a href="#parse_debugging">Parser Debugging</a>
|
||
<li><a href="#dependency_graph">Dependency Graph Output</a>
|
||
</ul>
|
||
</ul>
|
||
|
||
<li><a href="#target_names">Target Names</a>
|
||
|
||
<li><a href="#internal_globals">Global Variables</a>
|
||
</ul>
|
||
|
||
<li>
|
||
<a href="#design_criteria">Design Criteria</a>
|
||
|
||
<ul>
|
||
<li><a href="#assumptions">Assumptions</a>
|
||
|
||
<li><a href="#requirements">Requirements</a>
|
||
</ul>
|
||
|
||
<li><a href="#footnotes">Footnotes</a>
|
||
</ul>
|
||
|
||
<h2><a name="getting_started">Getting Started</a></h2>
|
||
|
||
<h3><a name="installing_jam">Installing Boost Jam</a></h3>
|
||
|
||
<ul>
|
||
<li>The Boost Jam sources are located in the <tt>tools/build/jam_src</tt>
|
||
subdirectory of the Boost installation.
|
||
|
||
<li>The <a href="http://public.perforce.com/public/jam/src/README">Jam
|
||
README</a> contains basic installation instructions.
|
||
|
||
|
||
<li>If you are installing on Windows, the make process may prompt you to set
|
||
some environment variables, and stop. Don't be alarmed; just follow the
|
||
instructions and start over. Please keep in mind that these variable settings
|
||
are case-sensitive. The variable settings necessary for bootstrapping
|
||
Jam are not needed once it has been built.
|
||
<li>Note that the supplied Makefile may require editing for your
|
||
platform; see the <a href=
|
||
"http://public.perforce.com/public/jam/src/README">Jam README</a> for
|
||
details. The Makefile is used for bootstrapping Jam; it builds Jam into a
|
||
subdirectory called <tt>bin.</tt><i>platform</i>.
|
||
</ul>
|
||
|
||
<h3><a name="initiating">Initiating a Build</a></h3>
|
||
|
||
<p>The easiest way to get going is to set the <tt>BOOST_ROOT</tt>
|
||
environment variable to point at the Boost installation directory, though
|
||
you can also set <tt>BOOST_ROOT</tt> on the command-line, using
|
||
<tt>-s...</tt>. You can use the <tt>TOOLS</tt> variable to indicate which
|
||
toolset(s) to build with, and the <tt>BUILD</tt> variable to describe how
|
||
you want things built. In most cases it should be sufficient to invoke Jam
|
||
with no variable settings. The following examples all assume that
|
||
<tt>BOOST_ROOT</tt> has been set in the environment.
|
||
|
||
<p>Here are some sample Boost Jam invocations:
|
||
|
||
<table border="1" summary="Sample Jam Invocations=">
|
||
<tr>
|
||
<th>Command Line(s)
|
||
|
||
<th>Effects
|
||
|
||
<tr>
|
||
<td>
|
||
<pre>
|
||
jam -sTOOLS=gcc my_target
|
||
</pre>
|
||
|
||
<td>default (debug) <tt><a href="#build">BUILD</a></tt> of
|
||
<tt>my_target</tt>with GCC
|
||
|
||
<tr>
|
||
<td>
|
||
<pre>jam -f<i>allyourbase-path</i> -sTOOLS="msvc gcc"</pre>
|
||
|
||
<td>default-build <tt>all</tt> with msvc and gcc
|
||
|
||
<tr>
|
||
<td>
|
||
<pre>
|
||
set TOOLS=msvc
|
||
jam
|
||
</pre>
|
||
|
||
<td>Set an NT environment variable to always build with MSVC<br>
|
||
default-build <tt>all</tt>.
|
||
|
||
<tr>
|
||
<td>
|
||
<pre>
|
||
jam -sBUILD=release
|
||
</pre>
|
||
|
||
<td>release build <tt>all</tt> with default <tt><a href=
|
||
"#tools">TOOLS</a></tt>:<br>
|
||
|
||
|
||
<tr>
|
||
<td><pre>jam -sBUILD="debug release"</pre>
|
||
|
||
<td>debug and release build <tt>all</tt>.
|
||
</table>
|
||
|
||
<h3><a name="setting_variables">Setting Jam Variables</a></h3>
|
||
|
||
<p>The "<tt>-s</tt>" options in the command lines above are
|
||
passing variable settings to the build system. There are actually three ways to do
|
||
that:
|
||
|
||
<ul>
|
||
<li>Jam picks up variable settings from your environment by default, so
|
||
you can set them there:
|
||
<blockquote><pre>
|
||
> <a href="#build">BUILD</a>="debug release" <i># assuming Unix</i>
|
||
> export <a href="#build">BUILD</a>
|
||
> jam ...
|
||
</pre></blockquote>
|
||
This approach can be OK for quick-and-dirty tests, but environment variable
|
||
settings tend to be unstable and non-uniform across users and machines, so
|
||
it's best not to rely on the environment much.
|
||
<li>Explicitly on the command-line, with the "<tt>-s</tt>"
|
||
option.
|
||
<li>Directly in Jam code. A project's <a href="#jamrules">Jamrules</a> file is a convenient place
|
||
to make global settings.
|
||
</ul>
|
||
|
||
<h3><a name="example_jamfile">An Example Jamfile</a></h3>
|
||
Here is an example of a simple subproject Jamfile. In this example, it is
|
||
assumed that the user has set <tt>BOOST_ROOT</tt>, either as an environment
|
||
variable, on the command-line or in the project's <tt><a href=
|
||
"#jamrules">Jamrules</a></tt> file:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
subproject foo/bar/baz ; # path to here from project root
|
||
|
||
# A static library called 'baz'
|
||
lib baz : baz1.cpp baz2.cpp # C++ sources
|
||
parser/src/baz4.ll # Lex->C++ sources
|
||
parser/src/baz5.yy # Yacc->C++ sources
|
||
: <include>$(BOOST_PARENT_DIRECTORY) # Put boost in #include path
|
||
;
|
||
|
||
# An executable called 'test'
|
||
exe test : <lib>baz # use the 'baz' library
|
||
baz_test.cpp # C++ source
|
||
: <include>$(BOOST_ROOT)
|
||
;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<p>That's it! The build system takes care of the rest. If the you want to
|
||
be able to build all subprojects from the project root directory, you can
|
||
add a Jamfile at the root:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
project-root ; # declare this to be the project root directory
|
||
# Read subproject Jamfiles
|
||
subinclude foo/bar/baz <font color="#7f7f7f">foo/bar/...</font> ;
|
||
<font color="#7f7f7f">subinclude a/b/c ...</font> ; # more subincludes
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<h3><a name="support_files">Support Files</a></h3>
|
||
|
||
|
||
<p>To use the build system, the following must be located in your project's root
|
||
directory, or in a directory specified in the <tt>BOOST_BUILD_PATH</tt> variable.
|
||
It is usually convenient to specify the <tt>BOOST_BUILD_PATH</tt> in your
|
||
project's <a href=
|
||
"#jamrules">Jamrules</a> file. The <a href="../../Jamrules">Boost Jamrules</a>
|
||
file shows an example.
|
||
<table border="1" summary="Support Files">
|
||
<tr>
|
||
<th>Filename(s)
|
||
|
||
<th>Meaning
|
||
|
||
<tr>
|
||
<td><i>toolset</i><tt>-tools.jam</tt>
|
||
|
||
<td>Feature-to-command-line mapping for <i>toolset</i>.
|
||
|
||
<tr>
|
||
<td><tt>features.jam</tt>
|
||
|
||
<td>Abstract toolset feature descriptions.
|
||
|
||
<tr>
|
||
<td><tt>boost-base.jam</tt>
|
||
|
||
<td>Boost build system-specific rule definitions.
|
||
|
||
<tr>
|
||
<td><tt>unit-tests.jam</tt>
|
||
|
||
<td>Unit tests and assertions for boost Jam code.
|
||
</table>
|
||
The <tt>boost-base.jam</tt> file is temporary, and will eventually be
|
||
compiled into our Jam executable.
|
||
|
||
<h2><a name="design">Basic Design and Terminology</a></h2>
|
||
This section gives an overview of the way that the system works, outlining
|
||
the system's capabilities and overall design. It also introduces the terminology
|
||
and concepts necessary to understand the sections on writing Jamfiles and command-line
|
||
invocations.
|
||
|
||
<h3><a name="project_subproject">Projects and Subprojects</a></h3>
|
||
|
||
<p>A <b>project</b> is a source directory tree containing at least one
|
||
<tt>Jamfile</tt>. The root directory of the project is known as the
|
||
<b>project root</b>. <a name="jamrules">The</a> root directory of a project
|
||
may contain a <tt>Jamrules</tt> file, which contains project-specific Jam
|
||
code. If the <tt>Jamrules</tt> file is not present when Jam is invoked, a
|
||
warning will be issued.
|
||
|
||
<p>Subdirectories containing <tt>Jamfile</tt>s are called <b>subproject
|
||
directories</b>. Each such <tt>Jamfile</tt> describes a <b>subproject</b>.
|
||
|
||
|
||
<p>The <b>build system installation directory</b> is a directory containing Jam
|
||
files describing compilers and build variants. The installation directory
|
||
can be specified implicitly by setting the variable <tt>BOOST_BUILD_PATH</tt>.
|
||
This lists a set of directories to search for the files comprising the build
|
||
system. If the installation directory is not specified, it is the same as
|
||
the project root, and <tt>BOOST_BUILD_PATH</tt> is set to include that directory.
|
||
<h3><a name="targets">Targets</a></h3>
|
||
|
||
<p>Each <tt>Jamfile</tt> describes one or more <b>main targets</b>.
|
||
|
||
<p>Each main target is an abstract description of one or more <b>built
|
||
targets</b> which are expressions of the corresponding main target under
|
||
particular compilers and build variants. Intermediate files such as
|
||
<tt>.o</tt>/<tt>.obj</tt> files generated by compiling <tt>.cpp</tt> files
|
||
as a consequence of building a main target are also referred to as built
|
||
targets. The term <b>build directory tree</b> refers to the location of
|
||
built target files.
|
||
|
||
<ul>
|
||
<li>By default, the build directory tree is overlaid with the project
|
||
directory tree, with targets generated into a subtree rooted at the
|
||
<tt>bin</tt> subdirectory of each subproject directory (the name of this
|
||
directory can be customized by changing the <tt>BIN_DIRECTORY</tt>
|
||
variable.
|
||
|
||
<li><a name="all_locate_target">If the variable
|
||
<tt>ALL_LOCATE_TARGET</tt> is set</a>, it specifies an alternate build
|
||
directory tree whose structure mirrors that of the project. In this case,
|
||
built targets of a subproject are generated into the corresponding
|
||
directory of the build directory tree.
|
||
</ul>
|
||
For each main target, there is a corresponding location in the build
|
||
directory tree known as the target's <b>build root</b>, where all
|
||
intermediate and final targets resulting from that main target are located.
|
||
|
||
|
||
<h3><a name="features">Features and Properties</a></h3>
|
||
|
||
<p>A <b>feature</b> is a normalized (toolset-independent) description of an
|
||
individual build parameter, such as whether inlining is enabled. Each
|
||
feature usually corresponds to a command-line option of one or more build
|
||
tools. Features come in four varieties:
|
||
|
||
<ol>
|
||
<li><b>Simple features</b> can take on any of several predetermined
|
||
values. For example, the feature <tt>optimization</tt> might take one of
|
||
the values <tt>off</tt>, <tt>speed</tt>, or <tt>space</tt>. Simple
|
||
features have a default value. The key aspect of simple features is that
|
||
they are assumed to affect link compatibility: object files generated
|
||
with different values for a simple feature are generated into a separate
|
||
directories, and (with a few exceptions) main targets generated with
|
||
different values won't be linked together.
|
||
|
||
<li><b>Free features</b> can either be single-valued, as above, or may
|
||
take on any number of user-specified values simultaneously. For example,
|
||
the <tt>define</tt> feature for a release build might have the values
|
||
<tt>NDEBUG</tt> and <tt>BOOST_RELEASE_BUILD</tt>. Free features are
|
||
assumed not to affect link compatibility.
|
||
|
||
<li><b>Path features</b> are free features whose values describe paths
|
||
which may be relative to the subproject (such as linked libraries or
|
||
<tt>#include</tt> search directories). The build system treats the values
|
||
of these features specially to ensure that they are interpreted relative
|
||
to the subproject directory regardless of the directory where Jam was
|
||
invoked.
|
||
|
||
<li><b>Dependency features</b> are path features whose values describe a
|
||
dependency of built targets. For example, an external library might be
|
||
specified with a dependency-feature: if the library is updated, the
|
||
target will be updated also. The <tt><library-file></tt> feature
|
||
works this way <a href="#2">[2]</a>.
|
||
</ol>
|
||
|
||
<p>A feature-value pair is known as a <b>build property</b>, or simply
|
||
<b>property</b>. The prefixes <i>simple</i>, <i>free</i>, <i>path</i>, and
|
||
<i>dependency</i> apply to properties in an analogous way to features.
|
||
|
||
<h3><a name="variants">Build Variants</a></h3>
|
||
|
||
<p>A build variant, or simply <b>variant</b> is a named set of build
|
||
properties describing how targets should be built. Typically you'll want at
|
||
least two separate variants: one for debugging, and one for your release
|
||
code.
|
||
|
||
<p>Built targets for distinct build variants and toolsets are generated in
|
||
separate parts of the build directory tree, known as the <b>variant
|
||
directories</b>. For example, a (sub)project with main targets <tt>foo</tt>
|
||
and <tt>bar</tt>, compiled with both GCC and KAI for <tt>debug</tt> and
|
||
<tt>release</tt> variants might generate the following structure (target
|
||
directories in <b>bold</b>).
|
||
|
||
<blockquote>
|
||
<pre>
|
||
bin
|
||
+-foo <font color="#7f7f7f"><--- foo's build root</font>
|
||
| +-gcc
|
||
| | +-<b>debug</b>
|
||
| | `-<b>release</b>
|
||
| `-kai
|
||
| +-<b>debug</b>
|
||
| `-<b>release</b>
|
||
`-bar <font color="#7f7f7f"><--- bar's build root</font>
|
||
+-gcc
|
||
| +-<b>debug</b>
|
||
| `-<b>release</b>
|
||
`-kai
|
||
+-<b>debug</b>
|
||
`-<b>release</b>
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<p>The properties constituting a variant may differ according to toolset,
|
||
so <tt>debug</tt> may mean a slightly different set of properties for two
|
||
different compilers.
|
||
|
||
<h3><a name="subvariants">Subvariants</a></h3>
|
||
|
||
<p>When a target is built with <i>simple</i> properties that don't exactly
|
||
match those specified in a build variant, the non-matching features are
|
||
called <b>subvariant features</b> and the target is located in a
|
||
<b>subvariant directory</b> beneath the directory of the base variant. This
|
||
can occur for two reasons:
|
||
|
||
<ol>
|
||
<li>
|
||
Some features are only relevant to certain compilers. When relevant
|
||
simple features have no value specified in the build variant, a value
|
||
must be chosen. Even when the default value is used, the target is
|
||
generated into a subvariant directory. For example, the
|
||
<tt>runtime-link</tt> feature may be unspecified in the <tt>debug</tt>
|
||
variant, but relevant to MSVC. In that case, a fragment of the target
|
||
tree might look like:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
bin
|
||
+-foo <font color="#7f7f7f"><--- foo's build root</font>
|
||
| +-msvc
|
||
| | +-debug
|
||
. . . `-<b>runtime-link-dynamic</b>
|
||
. . .
|
||
</pre>
|
||
</blockquote>
|
||
Because the default value of <tt>runtime-link</tt> is <tt>dynamic</tt>,
|
||
when the <tt>debug</tt> variant is requested, the
|
||
<tt>runtime-link-dynamic</tt> subvariant of foo is built.<br>
|
||
<br>
|
||
|
||
<li>
|
||
It is possible to request (either on the command-line, or as part of a
|
||
main target description) that particular subvariants be built. For
|
||
example, it may be desirable to generate builds that link to the
|
||
runtime both statically <i>and</i> dynamically. In that case, both
|
||
subvariant directories in the example above would be generated:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
bin
|
||
+-foo <font color="#7f7f7f"><--- foo's build root</font>
|
||
| +-msvc
|
||
| | +-debug
|
||
. . . +-<b>runtime-link-dynamic</b>
|
||
. . . `-<b>runtime-link-static</b>
|
||
. . .
|
||
</pre>
|
||
</blockquote>
|
||
</ol>
|
||
In no case will targets be built directly into <tt>bin/foo/msvc/debug</tt>,
|
||
since the <tt>debug</tt> variant doesn't include the <tt>runtime-link</tt>
|
||
feature, which is relevant to MSVC.
|
||
|
||
<p>When a subvariant includes multiple subvariant features, targets are
|
||
built into a subvariant directory whose path is determined by concatenating
|
||
the properties sorted in order of their feature names. For example, the
|
||
borland compiler, which uses different libraries depending on whether the
|
||
target is a console or GUI program, might create the following structure
|
||
for a DLL:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
bin
|
||
+-foo <font color="#7f7f7f"><--- foo's build root</font>
|
||
| +-msvc
|
||
| | +-debug
|
||
| | | +-runtime-link-dynamic
|
||
| | | | +-<b>user-interface-console</b>
|
||
| | | | `-<b>user-interface-gui</b>
|
||
. . . `-runtime-link-static
|
||
. . . +-<b>user-interface-console</b>
|
||
. . . `user-interface-gui<b></b>
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<p>Any configuration of properties for which a target is built, whether
|
||
base variant or subvariant, is known as a <b>build configuration</b>, or
|
||
simply a <b>build</b>.
|
||
|
||
<h3><a name="dependents">Dependent Targets</a></h3>
|
||
|
||
<p>When a main target depends on the product of a second main target (as
|
||
when an executable depends on and links to a static library), each build
|
||
configuration of the dependent target is depends on the
|
||
<i>corresponding</i> build of the dependency. Because only simple features
|
||
participate in build identity, the dependent and dependency targets may
|
||
have completely different free features. This puts the onus on the user for
|
||
ensuring link-compatibility when certain free properties are used. For
|
||
example, when <tt>assert()</tt> is used in header files, the preprocessor
|
||
symbol <tt>NDEBUG</tt> can impact link-compatibility of separate
|
||
compilation units. This danger can be minimized by encapsulating such
|
||
feature differences inside of build variants.
|
||
|
||
<h2><a name="usage">Usage</a></h2>
|
||
|
||
<p>This section describes how to start a build from the command-line and
|
||
how to write project and subproject Jamfiles. It also describes the other
|
||
files written in the Jam language: build-tool specification files, feature
|
||
descriptions files.
|
||
|
||
<h3><a name="command_line">The Command Line</a></h3>
|
||
|
||
<p>This section describes in detail how the build system can be invoked.
|
||
|
||
<h4><a name="user_targets">User Targets</a></h4>
|
||
|
||
<p>The Jam command line ends with an optional list of target names; if no
|
||
target names are supplied, the built-in pseudotarget <tt>all</tt> is built.
|
||
In a large project, naming targets can be dicey because of collisions. Jam
|
||
uses a mechanism called <a href="#grist">grist</a> to distinguish targets
|
||
that would otherwise have the same name. Fortunately, you won't often have
|
||
to supply grist at the command-line. When you declare a main target, a Jam
|
||
pseudotarget of the same name is created which depends on <i>all</i> of the
|
||
subvariants requested for your invocation of the build system. For example,
|
||
if your subproject declares:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
exe my_target : my_source1.cpp my_source2.c ;
|
||
</pre>
|
||
</blockquote>
|
||
and you invoke Jam with <tt>-sBUILD="debug release"<22>my_target</tt>, you
|
||
will build both the debug and release versions of <tt>my_target</tt>.
|
||
|
||
|
||
<p>These simple, ungristed names are called <b>user targets</b>, and are only
|
||
available for the subproject where Jam is invoked. That way, builds from the
|
||
top level (which may include many Jamfiles through the subinclude rule) and
|
||
builds of library dependencies (which may live in other subprojects), don't
|
||
collide. If it is necessary to refer more explicitly to a particular target
|
||
from the command-line, you will have to add ``grist''. Please see <a href="#target_names">this
|
||
section</a> for a more complete description of how to name particular targets
|
||
in a build.
|
||
<h4><a name="user_globals">Global Variables</a></h4>
|
||
|
||
<p>This is a partial list of global variables that can be set on the
|
||
command-line. Of course you are free to write your own Jam rules which
|
||
interpret other variables from the command-line. This list just details
|
||
some of the variables used by the build system itself. Note also that if
|
||
you don't like the default values you can override them in your project's
|
||
<tt><a href="#jamrules">Jamrules</a></tt> file.
|
||
|
||
<table border="1" summary="User Globals">
|
||
<tr>
|
||
<th>Variable <!-- <th>Meaning -->
|
||
|
||
<th>Default
|
||
|
||
<th>Example
|
||
|
||
<th>Notes
|
||
|
||
<tr>
|
||
<td rowspan="2"><tt><a name="tools">TOOLS</a></tt>
|
||
<!-- <td rowspan="2">Toolsets to build with -->
|
||
|
||
<td rowspan="2">Platform-dependent
|
||
|
||
<td><tt>-sTOOLS="gcc<63>msvc"</tt>
|
||
<td>build with gcc and msvc
|
||
|
||
<tr>
|
||
<td><tt>-sTOOLS=gcc</tt>
|
||
<td>build with gcc
|
||
|
||
<tr>
|
||
<td rowspan="4"><tt><a name="build">BUILD</a></tt>
|
||
<!-- <td rowspan="4">Build configuration (see -->
|
||
<!-- <a href="#default_build">here</a>). -->
|
||
|
||
|
||
<td rowspan="4"><tt>debug</tt>
|
||
|
||
<td><tt>-sBUILD=release</tt>
|
||
|
||
<td>build the <tt>release</tt> variant
|
||
|
||
<tr>
|
||
<td><tt>-sBUILD="debug release"</tt>
|
||
|
||
<td>build both <tt>debug</tt> and <tt>release</tt> variants
|
||
|
||
<tr>
|
||
<td><tt>-sBUILD="<optimization>speed"</tt>
|
||
|
||
<td>build a subvariant of the default variant (<tt>debug</tt>) with
|
||
optimization for speed.
|
||
|
||
<tr>
|
||
<td><tt>-sBUILD="debug release <runtime-link>static/dynamic"</tt>
|
||
|
||
|
||
<td>build subvariants of the debug and release variants that link to
|
||
the runtime both statically and dynamically.
|
||
|
||
<tr>
|
||
<td><tt>ALL_LOCATE_TARGET</tt>
|
||
<!-- <td>Alternate location for built targets (see <a -->
|
||
<!-- href="#all_locate_target">here</a>) -->
|
||
|
||
|
||
<td><i>empty</i>
|
||
|
||
<td><tt>-sALL_LOCATE_TARGET=~/build</tt>
|
||
|
||
<td>Generate all build results in the <tt>build</tt> subdirectory of the
|
||
user's home directory (UNIX).
|
||
</table>
|
||
|
||
<h3><a name="#subproject_jamfiles">SubProject Jamfiles</a></h3>
|
||
This section describes how to write a Jamfile for a subproject.
|
||
|
||
<h4><a name="subproject_rule">The <tt>subproject</tt> rule</a></h4>
|
||
|
||
<p>A subproject's Jamfile begins with an invocation of the
|
||
<tt>subproject</tt> rule that specifies the subproject's location relative
|
||
to the top of the project tree:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
subproject <i>path-from-top</i> ;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<p>The <tt>subproject</tt> rule tells the build system where to place built
|
||
targets from the subproject in case <tt>ALL_LOCATE_TARGET</tt> is used to
|
||
specify the build directory tree. If there is a Jamfile in the project root
|
||
directory, you should use the <tt>project-root</tt> rule instead:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
project-root ;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<h4><a name="main_targets">Describing Main Targets</a></h4>
|
||
|
||
<p>A main target is described using the following syntax:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
<i>target-type</i> <i>name</i> : <i>sources</i>
|
||
[ : <i>requirements</i> [ : <i><a href=
|
||
"#default_build">default-BUILD</a></i> ] ] ;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
|
||
<ul>
|
||
<li><i>target-type</i> may be one of <tt>exe</tt>, <tt>lib</tt>, <tt>dll</tt>,
|
||
<tt>stage</tt> or <tt>template</tt>. These are actually names of Jam rules.
|
||
Additional main target rules are possible; see <tt><a href=
|
||
"../../status/Jamfile">status/Jamfile</a></tt> or <tt><a href=
|
||
"../../libs/python/build/Jamfile">libs/python/build/Jamfile</a></tt> for
|
||
examples.<br>
|
||
<br>
|
||
<li><i>name</i> specifies the name of the main target, multiple targets with
|
||
the same name are allowed but only if they are of different types. Normally
|
||
this is not the name of the final target file generated. The target file
|
||
name depends on the type of target which controls how the base target
|
||
name is renamed to conform to platform conventions. For <tt>exe</tt>s
|
||
the name might be the same or <tt>*.exe</tt>. For <tt>lib</tt>s the name
|
||
might be <tt>*.lib</tt> or <tt>lib*.a</tt>. And for <tt>dll</tt>s the
|
||
name might be <tt>*.dll</tt> or <tt>lib*.so</tt>. For platform specific
|
||
naming consult the <tt><a href="allyourbase.jam">allyourbase.jam</a></tt>
|
||
file in the build system.<br>
|
||
<br>
|
||
<li><i>sources</i> is a list of paths to source files and dependency targets.
|
||
A dependency target path is preceded by <tt><template></tt>,
|
||
<tt><lib></tt>, <tt><dll></tt>, or <tt><exe></tt>,
|
||
and the final path component specifies the name of a main target in a Jamfile located
|
||
in the directory given by the initial path components. Paths may be absolute or
|
||
relative. The type of dependency is also used to decide how to link to it when needed.
|
||
Specifying a <tt><lib></tt> indicates the use of static linking,
|
||
as opposed to specifying a <tt><dll></tt> which uses dynamic linking.
|
||
For example in Unix static linking will be done directly, and dynamic
|
||
linking with the common "<tt>-l</tt>" liker flag and use of
|
||
<tt>LD_LIBRARY_PATH</tt>.<br>
|
||
<br>
|
||
<b>NOTE:</b> It is important to match up the type of source dependency
|
||
with the same type the dependency is built as. Trying to specify a source
|
||
dependency of <tt><lib></tt> when the target is defined as a <tt><dll></tt>
|
||
will cause an error.<br>
|
||
<br>
|
||
<li> <i><a name="target_requirements">requirements</a></i> specifies the build
|
||
properties intrinsic to the target. Requirements are given as sets of
|
||
optionally-<b>qualified build properties</b>:
|
||
<blockquote>
|
||
<pre>
|
||
[[<<i>compiler</i>>]<<i>variant</i>>]<<i>feature</i>><i>value</i>
|
||
</pre>
|
||
</blockquote>
|
||
<tt><<i>compiler</i>></tt> and <tt><<i>variant</i>></tt>,
|
||
if supplied, can be used to restrict the applicability of the requirement.
|
||
Either one may be replaced by <tt><*></tt>, which is the same as
|
||
omitting it.
|
||
<p>The system checks that simple feature requirements are not violated
|
||
by explicit subvariant build requests, and will issue a warning otherwise.
|
||
Free features specified as requirements are simply added to each corresponding
|
||
build configuration.<br>
|
||
<br>
|
||
<li> <i><a name="default_build">default-BUILD</a></i> specifies the configurations
|
||
that should be built if the <tt><a href=
|
||
"#build">BUILD</a></tt> variable is not otherwise specified. Any elements
|
||
not beginning with ``<tt><</tt>...<tt>></tt>'' refer to build variants.
|
||
Other elements use the same syntax as the <a href=
|
||
"#target_requirements">requirements</a> described above, except that multiple
|
||
values may be specified for a simple feature by separating them with a
|
||
slash, forming (qualified) <b>multi-valued properties</b>:
|
||
<blockquote>
|
||
<pre>
|
||
[[<<i>compiler</i>>]<<i>variant</i>>]<<i>feature</i>><i>value1</i>[/<i>value2</i>...]
|
||
</pre>
|
||
</blockquote>
|
||
When multiple values are specified, it causes <i>all</i> the implied configurations
|
||
to be built by default. It is also possible to prevent any default builds
|
||
from occurring on this target by using <code><suppress>true</code>
|
||
. This suppresses any local targets, either implicit or explicit, from
|
||
building. But, this does not prevent implied targets as required by a
|
||
dependency by another target to this one from being built. This is useful,
|
||
for example, for defining a set of libraries generically and having them
|
||
built only when another target like an exe is built. Such use might look
|
||
like:
|
||
<blockquote>
|
||
<pre>
|
||
lib basic : basic.cpp : : <suppress>true ;<br><br>exe test : test.cpp <lib>basic ;<br>
|
||
</pre>
|
||
</blockquote>
|
||
With that the <tt>basic</tt> library will only be built when the <tt>test</tt>
|
||
executable is built, and only the variations required by the executable
|
||
will be built.<br>
|
||
</li>
|
||
</ul>
|
||
|
||
<p><b>NOTE:</b> for simple features in both <i><a href=
|
||
"#target_requirements">requirements</a></i> and <i><a href=
|
||
"#default_build">default-BUILD</a></i>, more-specific qualification
|
||
overrides less-specific.
|
||
|
||
<h4><a name="template_targets">Describing Template Targets</a></h4>
|
||
|
||
<p>Template targets provide a way to handle commonalities between projects targets.
|
||
They have the same form as <a href="#main_targets">main targets</a> but do not
|
||
initiate build requests. A target that lists a template as a dependency inherits
|
||
all the settings from the template, i.e. the templates sources, requirements and
|
||
default build settings will be added to the targets settings. Paths mentioned in a
|
||
template definition are always relative to the subdirectory of the Jamfile
|
||
containing the templates definition, regardless of the subdirectory of the dependent
|
||
main target. Typically a project will have at least one template target that handles
|
||
defines, include paths and additional compiler flags common to all targets in the project.
|
||
|
||
<h4><a name="stage_targets">Describing Stage Targets</a></h4>
|
||
|
||
<p>Stage targets are a special kind of target that don't build a single file but
|
||
to a collection of files. The goal is to create a directory which is composed
|
||
of the various files that other targets generate, or individual files. When
|
||
built a stage target creates a directory with the same name as the target,
|
||
and copies the dependent files to it. The form of the target is the same as
|
||
that of <a href="#main_targets">main targets</a> with some differences...
|
||
|
||
<ul>
|
||
<li><i>target-type</i> is <tt>stage</tt>. See <tt><a href=
|
||
"../../libs/regex/build/Jamfile">libs/regex/build/Jamfile</a></tt> for an
|
||
example.<br>
|
||
<br>
|
||
<li><i>Name</i> specifies the name of the stage and is the name of the directory
|
||
created. <br>
|
||
<br>
|
||
<li><i>sources</i> is the same as main targets and one can list both generated
|
||
targets like <tt><exe>test_exe</tt> and individual files, but not
|
||
template targets.<br>
|
||
<br>
|
||
<li><i>Requirements</i> the build properties specified are used as with main
|
||
targets. But one additional type of requirement is possible: <tt><tag></tt>...
|
||
A tag specifies how to "augment" the names of the copied files.
|
||
This is needed to distinguish the various files if your collecting different
|
||
builds of the same targets. The syntax is:
|
||
<blockquote>
|
||
<pre>
|
||
<tag><<i>feature|variant</i>><i>value</i>
|
||
</pre>
|
||
</blockquote>
|
||
<br>
|
||
If the <tt><i>feature</i></tt> or <tt><i>variant</i></tt> is present for
|
||
the a target the file for that target is renamed to include the given
|
||
<tt><i>value</i></tt> between the basename and the suffix. Two special
|
||
<tt>tag</tt>s, <tt><tag><prefix></tt> and <tt><tag><postfix></tt>,
|
||
let one prepend and append a value to the "augmentation" respectively.<br>
|
||
<br>
|
||
<li> <i>default-BUILD</i> acts in the same manner as a main target.<br>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4><a name="jamfile_example">Example</a></h4>
|
||
|
||
<p>This artificially complex example shows how two executables called "foo"
|
||
and "fop" might be described in a Jamfile. All common settings are factored out
|
||
in the templates "base" and "executable". Foo is composed of the sources
|
||
<tt>./foo.cpp</tt> and <tt>./src/bar.cpp</tt> (specified relative to the
|
||
directory in which the Jamfile resides). Fop only has one sourcefile <tt>./fop.cpp</tt>.
|
||
Both executables link against the built target which results from building the target
|
||
<tt>baz</tt> as described in <tt>../bazlib/Jamfile</tt>.
|
||
|
||
<blockquote>
|
||
<pre>
|
||
template base :
|
||
## <a href="#target_requirements">Requirements</a> ##
|
||
: <include>../bazlib/include
|
||
<define>BUILDING_FOO=1
|
||
<release><define>FOO_RELEASE
|
||
<msvc><*><define>FOO_MSVC
|
||
<msvc><release><define>FOO_MSVC_RELEASE
|
||
<gcc><*><optimization>off
|
||
<gcc><release><optimization>space
|
||
<threading>multi
|
||
<sysinclude>/usr/local/foolib/include
|
||
|
||
## <a href="#default_build">default-BUILD</a> ##
|
||
: debug release
|
||
<debug><runtime-link>static/dynamic
|
||
;
|
||
|
||
template executable : <template>base <lib>../bazlib/baz ;
|
||
|
||
exe foo : <template>executable foo.cpp src/bar.cpp ;
|
||
|
||
exe fop : <template>executable fop.cpp ;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<p>The <a href="#target_requirements">requirements</a> section:
|
||
|
||
<ul>
|
||
<li>Adds <tt>../bazlib/include</tt> to the <tt>#include</tt> path
|
||
|
||
<li>Sets the preprocessor symbol <tt>BUILDING_FOO</tt> to <tt>1</tt>
|
||
|
||
<li>In the <tt>release</tt> builds, <tt>#define</tt>s
|
||
<tt>FOO_RELEASE</tt>.
|
||
|
||
<li>When built with MSVC, <tt>#define</tt>s <tt>FOO_MSVC</tt>.
|
||
|
||
<li>In <tt>release</tt> variants built with MSVC, <tt>#define</tt>s
|
||
<tt>FOO_MSVC_RELEASE</tt>.
|
||
|
||
<li>Most builds under GCC have optimization turned off, but...
|
||
|
||
<li>...GCC <tt>release</tt> builds require optimization for space.
|
||
|
||
<li>Requires multithread support on compilers where it's relevant.
|
||
|
||
<li>Adds <tt>/usr/local/foolib/include</tt> to the <tt>#include <*></tt> path
|
||
</ul>
|
||
|
||
<p>The <a href="#default_build">default-BUILD</a> section:
|
||
|
||
<ul>
|
||
<li>specifies that <tt>debug</tt> and <tt>release</tt> base variants are
|
||
built by default.
|
||
|
||
<li>on compilers where the feature is relevant, requests both statically-
|
||
and dynamically-linked subvariants of the debug variant.
|
||
</ul>
|
||
|
||
<h3><a name="feature_description">Feature Descriptions</a></h3>
|
||
|
||
<p> Features are described by stating the feature type (simple features are
|
||
specified with "<tt>feature</tt>"), followed by the feature
|
||
name. An optional second argument can be used to list the permissible values
|
||
of the feature. Examples can be found in <a href="features.jam">features.jam</a>.
|
||
|
||
<h3><a name="variant_description">Variant Descriptions</a></h3>
|
||
|
||
<p>Variants are described with the following syntax:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
variant <i>name</i> : [<<i>toolset-name</i>>]<<i>feature</i>>value... ;
|
||
</pre>
|
||
</blockquote>
|
||
The <tt>variant</tt> rule specifies the list of properties comprising a
|
||
variant. Properties may be optionally qualified with a toolset name, which
|
||
specifies that the property applies only to that toolset. One or
|
||
more parent variants may be specified to inherit the properties <20>from those
|
||
parent(s). For inherited properties precedence is given on a left to right
|
||
order, making the immediate properties override those in the parent(s). This
|
||
can be used to great effect for describing global properties that are shared
|
||
amongst various variants, and therefore targets. For example:
|
||
<blockquote>
|
||
<pre>
|
||
variant my-globals : <rtti>off ;
|
||
|
||
variant my-debug : my-globals debug ;
|
||
|
||
variant my-release : my-globals release ;
|
||
</pre>
|
||
</blockquote>
|
||
More examples can be found in <a href="features.jam">features.jam</a>.
|
||
|
||
<h3><a name="toolset_description">Toolset Description Files</a></h3>
|
||
|
||
<p>Toolset descriptions are located in the project's root directory, or a
|
||
directory specified by <tt>BOOST_BUILD_INSTALLATION</tt>, which may be set
|
||
in a <tt>Jamfile</tt> or the project's <tt><a href=
|
||
"#jamrules">Jamrules</a></tt> file. Each file is called
|
||
<i>toolset-name</i><tt>-tools.jam</tt>, where <i>toolset-name</i> is the
|
||
name of the toolset. The toolset description file has two main jobs:
|
||
|
||
<ol>
|
||
<li>
|
||
redefine the following rules:
|
||
|
||
<ul>
|
||
<li><tt>Link-action</tt> - links an executable from objects and
|
||
libraries
|
||
|
||
<li><tt>Archive-action</tt> - links a static library from object
|
||
files
|
||
|
||
<li><tt>C++-action</tt> - compiles a 'C++' file into an object file
|
||
|
||
<li><tt>Cc-action</tt> - compiles a 'C' file into an object file
|
||
</ul>
|
||
These rules should simply invoke the action part of a rule whose name
|
||
is uniquely defined for the toolset. For example,
|
||
|
||
<blockquote>
|
||
<pre>
|
||
rule C++-action
|
||
{
|
||
msvc-C++-action $(<) : $(>) ;
|
||
}
|
||
|
||
actions msvc-C++-action
|
||
{
|
||
cl -nologo -GX -c -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I$(HDRS) -I$(STDHDRS) -Fo$(<) -Tp$(>)
|
||
}
|
||
|
||
</pre>
|
||
</blockquote>
|
||
Note that <tt>Link-action</tt> may require special care: on platforms
|
||
where the global variable <tt>gEXPORT_SUFFIX(DLL)</tt> is defined (e.g.
|
||
Windows), the first argument may have two elements when linking a shared
|
||
library. The first is the shared library target, and the second is the
|
||
import library target, with suffix given by <tt>$(gEXPORT_SUFFIX(DLL))</tt>.
|
||
It will always have a third argument which is either ``<tt>EXE</tt>''
|
||
or ``<tt>DLL</tt>''. This can be used to dispatch to different actions
|
||
for linking DLLs and EXEs if necessary, but usually it will be easier
|
||
to take advantage of the special <tt><target-type></tt> feature,
|
||
which will have the same value using the <tt>flags</tt> rule described
|
||
below.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
Translate build settings given in the global <tt>gBUILD_PROPERTIES</tt>
|
||
variable into something that can be used by the toolset. The build
|
||
system provides the <tt>flags</tt> rule to help translate build
|
||
properties into elements of global variables which are later attached
|
||
to targets so that they can affect the build actions. The
|
||
<tt>flags</tt> rule is used as follows:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
flags <i>toolset variable condition</i> [: <i>value</i>...]
|
||
</pre>
|
||
</blockquote>
|
||
The parameters are:
|
||
|
||
<ul>
|
||
<li><i>toolset</i> - the name of the toolset
|
||
|
||
<li><i>variable</i> - the name of a global variable which can be used
|
||
to carry information to a command-line
|
||
|
||
<li>
|
||
<i>condition</i> - one one or more elements in the following forms:
|
||
|
||
|
||
<ol>
|
||
<li>a property-set of the form:
|
||
<tt><<i>feature</i>><i>value</i></tt>[<tt>/<<i>feature</i>>
|
||
<i>value</i></tt>...]
|
||
|
||
<li><tt><<i>feature</i>></tt>
|
||
</ol>
|
||
|
||
<li><i>values</i> - anything
|
||
</ul>
|
||
|
||
<p>Semantics only affect targets built with the specified toolset, and
|
||
depend on the target's build configuration:
|
||
|
||
<ol>
|
||
<li>if any specified property-set is a subset of the target's build
|
||
properties, the <i>values</i> specified in <tt>$(3)</tt> will be
|
||
appended once to <i>variable</i>.
|
||
|
||
<li>The value of each specified feature that participates in the target's
|
||
build properties is appended to <i>variable</i>. In either case,
|
||
the variable will be set "on" the target so it may be used in
|
||
the build actions.
|
||
</ol>
|
||
</ol>
|
||
|
||
<h4><a name="toolset_example">Example</a></h4>
|
||
|
||
<p>The description of the <tt>flags</tt> rule above is actually more
|
||
complicated than it sounds. For example, the following line might be used
|
||
to specify how optimization can be turned off for MSVC:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
flags msvc CFLAGS <optimization>off : /Od ;
|
||
</pre>
|
||
</blockquote>
|
||
It says that the string <tt>/Od</tt> should be added to the global <tt>CFLAGS</tt>
|
||
variable whenever a build configuration includes the property <tt><optimization>off</tt>.
|
||
|
||
<p>Similarly, in the following example,
|
||
|
||
<blockquote>
|
||
<pre>
|
||
flags msvc CFLAGS <runtime-build>release/<runtime-link>dynamic : /MD ;
|
||
</pre>
|
||
</blockquote>
|
||
we add <tt>/MD</tt> to the CFLAGS variable when both of the specified
|
||
conditions are satisfied. We could grab all of the values of the free
|
||
feature <tt><include></tt> in the <tt>HDRS</tt> variable as follows:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
flags msvc HDRS <include> ;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<p>The use of these variables should be apparent from the declaration of
|
||
<tt>actions msvc-C++-action</tt> in the previous section.
|
||
|
||
<h2><a name="internals">Internals</a></h2>
|
||
|
||
<h3><a name="jam_fundamentals">Jam Fundamentals</a></h3>
|
||
|
||
<p>This section is derived from the official Jam documentation and from my
|
||
experience using it and reading the Jambase rules. I repeat the information
|
||
here mostly because it is essential to understanding and using Jam, but is
|
||
not consolidated in a single place. Some of it is missing from the official
|
||
documentation altogether. I hope it will be useful to anyone wishing to
|
||
become familiar with Jam and the Boost build system.
|
||
|
||
<p>
|
||
|
||
<ul>
|
||
|
||
<li>
|
||
Jam ``<b>rules</b>'' are actually simple procedural entities. Think of
|
||
them as functions. Arguments are separated by colons.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
A Jam <b>target</b> is an abstract entity identified by an arbitrary
|
||
string. The build-in <tt>DEPENDS</tt> rule creates a link in the
|
||
dependency graph between the named targets.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
Note that the documentation for the built-in <tt>INCLUDES</tt> rule is
|
||
incorrect: <tt>INCLUDES targets1 : targets2</tt> causes
|
||
everything that depends on a member of <i>targets1</i> to depend on all
|
||
members of <i>targets2</i>. It does this in an odd way, by tacking
|
||
<i>targets2</i> onto a special tail section in the dependency list of
|
||
everything in <i>targets1</i>. It seems to be OK to create circular
|
||
dependencies this way; in fact, it appears to be the ``right thing to
|
||
do'' when a single build action produces both <i>targets1</i> and
|
||
<i>targets2</i>.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
When a rule is invoked, if there are <b><tt>actions</tt></b> declared
|
||
with the same name as the rule, the <tt>actions</tt> are added to the
|
||
updating actions for the target identified by the rule's first
|
||
argument. It is actually possible to invoke an undeclared rule if
|
||
corresponding actions are declared: the rule is treated as empty.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
<a name="binding">Targets</a> (other than <tt>NOTFILE</tt> targets) are
|
||
associated with paths in the file system through a process called <a
|
||
href=
|
||
"http://public.perforce.com/public/jam/src/Jam.html#binding">binding</a>.
|
||
Binding is a process of searching for a file with the same name as the
|
||
target (sans <a href="#grist">grist</a>), based on the settings of the
|
||
<a href="#target_specific">target-specific</a> <tt>SEARCH</tt> and
|
||
<tt>LOCATE</tt> variables.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
<a name="target_specific">In addition to</a> local and global
|
||
variables, jam allows you to set a variable <tt><b>on</b></tt> a
|
||
target. Target-specific variable values can usually not be read, and
|
||
take effect <i>only</i> in the following contexts:
|
||
|
||
<p>
|
||
|
||
<ul>
|
||
<li>In updating <tt>actions</tt>, variable values are first looked up
|
||
<tt><b>on</b></tt> the target named by the first argument (the target
|
||
being updated). Because Jam builds its entire dependency tree before
|
||
executing <tt>actions</tt>, Jam rules make target-specific variable
|
||
settings as a way of supplying parameters to the corresponding
|
||
<tt>actions</tt>.
|
||
|
||
<li>Binding is controlled <i>entirely</i> by the target-specific
|
||
setting of the <tt>SEARCH</tt> and <tt>LOCATE</tt> variables, as
|
||
described <a href=
|
||
"http://public.perforce.com/public/jam/src/Jam.html#search">here</a>.
|
||
|
||
<li>In the special rule used for <a href=
|
||
"http://public.perforce.com/public/jam/src/Jam.html#hdrscan">header
|
||
file scanning</a>, variable values are first looked up
|
||
<tt><b>on</b></tt> the target named by the rule's first argument (the
|
||
source file being scanned).
|
||
</ul>
|
||
|
||
<p>
|
||
|
||
<li>
|
||
The ``<b>bound value</b>'' of a variable is the path associated with
|
||
the target named by the variable. In build <tt>actions</tt>, the first
|
||
two arguments are automatically replaced with their bound values.
|
||
Target-specific variables can be selectively replaced by their bound
|
||
values using the <a href=
|
||
"http://public.perforce.com/public/jam/src/Jam.html#actionmods">bind</a>
|
||
action modifier.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
Note that the term ``binding'' as used in the Jam documentation
|
||
indicates a phase of processing that includes three sub-phases:
|
||
<i>binding</i> (yes!), update determination, and header file scanning.
|
||
The repetition of the term ``binding'' can lead to some confusion. In
|
||
particular, the <a href=
|
||
"http://public.perforce.com/public/jam/src/Jam.html#bindingmods">Modifying
|
||
Binding</a> section in the Jam documentation should probably be titled
|
||
``Modifying Update Determination''.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
<p>``<a href="#grist">Grist</a>'' is just a string prefix of the form
|
||
<tt><</tt><i>characters</i><tt>></tt>. It is used in Jam to
|
||
create unique target names based on simpler names. For example, the
|
||
file name ``<tt>test.exe</tt>'' may be used by targets in separate
|
||
subprojects, or for the debug and release variants of the ``same''
|
||
abstract target. Each distinct target bound to a file called
|
||
``<tt>test.exe</tt>'' has its own unique grist prefix. The Boost build
|
||
system also takes full advantage of Jam's ability to divide strings on
|
||
grist boundaries, sometimes concatenating multiple gristed elements at
|
||
the beginning of a string. Grist is used instead of identifying targets
|
||
with absolute paths for two reasons:
|
||
|
||
<ol summary="">
|
||
<li>The location of targets cannot always be derived solely from what
|
||
the user puts in a Jamfile, but sometimes depends also on the <a
|
||
href="#binding">binding</a> process. Some mechanism to distinctly
|
||
identify targets with the same name is still needed.
|
||
|
||
<li>Grist allows us to use a uniform abstract identifier for each
|
||
built target, regardless of target file location (as allowed by
|
||
setting <tt>ALL_LOCATE_TARGET</tt>.
|
||
</ol>
|
||
When grist is extracted from a name with <tt>$(</tt><i>var</i><tt>:G)</tt>,
|
||
the result includes the leading and trailing angle brackets. When grist
|
||
is added to a name with <tt>$(</tt><i>var</i><tt>:G=</tt><i>expr</i><tt>)</tt>,
|
||
existing grist is first stripped. Then, if <i>expr</i> is non-empty, leading
|
||
<tt><</tt>s and trailing <tt>></tt>s are added if necessary to form
|
||
an expression of the form <tt><</tt><i>expr2</i><tt>></tt>; <tt><</tt><i>expr2</i><tt>></tt>
|
||
is then prepended.
|
||
|
||
<p>
|
||
|
||
|
||
<li> <a name="variable_splitting">When Jam</a> is invoked it imports all environment
|
||
variable settings into corresponding Jam variables, followed by all command-line
|
||
(<tt>-s...</tt>) variable settings. Variables whose name ends in <tt>PATH</tt>,
|
||
<tt>Path</tt>, or <tt>path</tt> are split into string lists on OS-specific
|
||
path-list separator boundaries (e.g. "<tt>:</tt>" for UNIX and
|
||
"<tt>;</tt>" for Windows). All other variables are split on
|
||
space ("<tt> </tt>") boundaries. Boost Jam modifies that
|
||
behavior by allowing variables to be <a
|
||
href="#variable_quoting">quoted</a>.
|
||
|
||
<p>
|
||
|
||
<li>
|
||
A variable whose value is an empty list <i>or</i> which consists
|
||
entirely of empty strings has a negative logical value. Thus, for
|
||
example, code like the following allows a sensible non-empty default
|
||
which can easily be overridden by the user:
|
||
<blockquote><pre>
|
||
MESSAGE ?= starting jam... ;
|
||
if $(MESSAGE) { ECHO The message is: $(MESSAGE) ; }
|
||
</pre></blockquote>
|
||
If the user wants a specific message, he invokes jam with
|
||
<tt>"-sMESSAGE=</tt><i>message text</i><tt>"</tt>. If he
|
||
wants no message, he invokes jam with <tt>-sMESSAGE=</tt> and nothing at
|
||
all is printed.
|
||
|
||
<p>
|
||
|
||
</ul>
|
||
|
||
<p>Please also read <a href=
|
||
"http://public.perforce.com/public/jam/src/Jam.html">The Jam language
|
||
reference</a> for the additional details, and the <a href=
|
||
"http://public.perforce.com/public/jam/src/RELNOTES">Jam release notes</a>
|
||
for a brief description of recent, but <b>fundamental changes to the Jam
|
||
language</b> without which you will probably not understand any of the
|
||
build system code. In particular, note that the <tt>return</tt> statement
|
||
does not affect control flow.
|
||
|
||
<h3><a name="core_extensions">Core Jam Extensions</a></h3>
|
||
|
||
<p>A number of enhancements have been made to the core language of Classic
|
||
Jam. These changes were aimed primarily at making it easier to manage the
|
||
complexity of a large system such as Boost.Build.
|
||
|
||
<blockquote>
|
||
|
||
<h4><a name="variable_quoting"></a>Command-line and Environment Variable Quoting</h4>
|
||
|
||
<p>Classic Jam had an <a href="#variable_splitting">odd behavior</a> with
|
||
respect to command-line variable ( <tt>-s...</tt>) and environment
|
||
variable settings which made it impossible to define an arbitrary variable
|
||
with spaces in the value. Boost Jam remedies that by treating all such
|
||
settings as a single string if they are surrounded by double-quotes. Uses
|
||
of this feature can look interesting, since shells require quotes to keep
|
||
characters separated by whitespace from being treated as separate
|
||
arguments:
|
||
<blockquote><pre>
|
||
jam -sMSVCNT="\"\"C:\Program Files\Microsoft Visual C++\VC98\"\"" ...
|
||
</pre></blockquote>
|
||
|
||
The outer quote is for the shell. The middle quote is for Jam,
|
||
to tell it to take everything within those quotes literally, and
|
||
the inner quotes are for the shell again when paths are passed
|
||
as arguments to build actions. Under NT, it looks a lot more
|
||
sane to use environment variables before invoking jam when you
|
||
have to do this sort of quoting:
|
||
|
||
<blockquote><pre>
|
||
set MSVCNT=""C:\Program Files\Microsoft Visual C++\VC98\""
|
||
</pre></blockquote>
|
||
|
||
<h4><a name="jambase_replacement">Jambase Replacement</a></h4>
|
||
|
||
<p>New logic has been added to allow the built-in Jambase to be replaced
|
||
without recompiling Jam or adding command-line arguments. The user can
|
||
control the location of the build system by setting any of the <tt>JAMBASE</tt>,
|
||
<tt>BOOST_ROOT</tt>, or <tt>BOOST_BUILD_PATH</tt> environment variables (the settings of
|
||
these variables can also be overridden on the command-line using the
|
||
<tt>-s<i>VARIABLE</i>=</tt>... option).
|
||
|
||
<p>The process is controlled by variables (in decreasing
|
||
precedence):
|
||
<ul>
|
||
|
||
<li>If <tt>JAMBASE</tt> is set, it specifies the path to the Jambase
|
||
replacement. Non-rooted paths are computed relative to the directory of
|
||
Jam's invocation.
|
||
|
||
<li>Otherwise, if <tt>BOOST_BUILD_PATH</tt> or <tt>BOOST_ROOT</tt> is set,
|
||
the build system filename is <tt><b>boost-build.jam</b></tt>.
|
||
|
||
<li>If the build system filename does not contain a path specification,
|
||
the build system file is searched for on <tt>$(BOOST_BUILD_PATH)</tt>,
|
||
then at <tt>$(BOOST_ROOT)/tools/build</tt>.
|
||
|
||
<li>If <tt>BOOST_BUILD_PATH</tt> was not set, it will be set to
|
||
<tt>$(BOOST_ROOT)/tools/build</tt>.
|
||
|
||
<li>If neither <tt>JAMBASE</tt>, <tt>BOOST_ROOT</tt>, nor
|
||
<tt>BOOST_BUILD_PATH</tt> is set, we use the built-in Jambase (nearly
|
||
identical to the <a
|
||
href="http://freetype.sourceforge.net/jam/index.html">FTJam</a> Jambase)
|
||
and load the user's Jamfile. Perforce Jam has this behavior, and it is
|
||
used for building Jam itself. <b>Thus, when you rebuild Jam, these
|
||
variables should be unset</b>.
|
||
|
||
</ul>
|
||
|
||
<p>The rationale for this behavior is as follows:
|
||
<ul>
|
||
|
||
<li> The Jam executable should allow the Jambase to be overridden to
|
||
implement other build systems without the user having any knowledge
|
||
of Boost, thus the <tt>JAMBASE</tt> variable.
|
||
|
||
<li> <tt>BOOST_BUILD_PATH</tt> is designed to be used to find all <a
|
||
href="#module_support">modules</a> used by the build system, so that users
|
||
and system administrators may non-intrusively add modules to the system.
|
||
|
||
<li> Many Boost users already have <tt>BOOST_ROOT</tt> set. If a user
|
||
doesn't want to explicitly set up <tt>BOOST_BUILD_PATH</tt>,
|
||
<tt>BOOST_ROOT</tt> will supply reasonable behavior.
|
||
|
||
</ul>
|
||
|
||
|
||
<h4><a name="rule_indirection">Rule Indirection</a></h4>
|
||
|
||
<p>Boost Jam allows you to call a rule whose name is held in a variable or
|
||
computed as the result of an expression:
|
||
<blockquote><pre>
|
||
x = foo ;
|
||
rule foobar { ECHO foobar ; } # a trivial rule
|
||
$(x)bar ; # invokes foobar
|
||
|
||
</pre></blockquote>
|
||
|
||
Furthermore, if the first expression expands to more than one
|
||
list item, everything after the first item becomes part of the
|
||
first argument. This allows a crude form of argument binding:
|
||
|
||
<blockquote><pre>
|
||
# return the elements of sequence for which predicate returns non-nil
|
||
rule filter ( sequence * : predicate + )
|
||
{
|
||
local result ;
|
||
for local x in $(sequence)
|
||
{
|
||
if [ $(predicate) $(x) ] { result += $(x); }
|
||
}
|
||
return $(result);
|
||
}
|
||
|
||
# true iff x == y
|
||
rule equal ( x y )
|
||
{
|
||
if $(x) = $(y) { return true; }
|
||
}
|
||
|
||
# bind 3 to the first argument of equal
|
||
ECHO [ filter 1 2 3 4 5 4 3 : equal 3 ] ; # prints "3 3"
|
||
|
||
</pre></blockquote>
|
||
|
||
<h4><a name="argument_lists">Argument lists</a></h4>
|
||
|
||
<p>You can now describe the arguments accepted by a rule, and refer to
|
||
them by name within the rule. For example, the following prints ``I'm
|
||
sorry, Dave'' to the console:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
rule report ( pronoun index ? : state : names + )
|
||
{
|
||
local he.suffix she.suffix it.suffix = s ;
|
||
local I.suffix = m ;
|
||
local they.suffix you.suffix = re ;
|
||
|
||
ECHO $(pronoun)'$($(pronoun).suffix) $(state), $(names[$(index)]) ;
|
||
}
|
||
report I 2 : sorry : Joe Dave Pete ;
|
||
</pre>
|
||
</blockquote>
|
||
Each name in a list of formal arguments (separated by ``<tt>:</tt>'' in
|
||
the rule declaration) is bound to a single element of the corresponding
|
||
actual argument unless followed by one of these modifiers:
|
||
|
||
<table border="1" summary="Argument modifiers">
|
||
<tr>
|
||
<th>Symbol
|
||
|
||
<th>Semantics of preceding symbol
|
||
|
||
<tr>
|
||
<td><tt>?</tt>
|
||
|
||
<td>optional
|
||
|
||
<tr>
|
||
<td><tt>*</tt>
|
||
|
||
<td>Bind to zero or more unbound elements of the actual
|
||
argument. When ``<tt>*</tt>'' appears where an argument name
|
||
is expected, any number of additional arguments are
|
||
accepted. This feature can be used to implement
|
||
"varargs" rules.
|
||
|
||
<tr>
|
||
<td><tt>+</tt>
|
||
|
||
<td>Bind to one or more unbound elements of the actual argument.
|
||
</table>
|
||
|
||
<p>The actual and formal arguments are checked for inconsistencies, which
|
||
cause Jam to exit with an error code:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
### argument error
|
||
# rule report ( pronoun index ? : state : names + )
|
||
# called with: ( I 2 foo : sorry : Joe Dave Pete )
|
||
# extra argument foo
|
||
|
||
### argument error
|
||
# rule report ( pronoun index ? : state : names + )
|
||
# called with: ( I 2 : sorry )
|
||
# missing argument names
|
||
</pre>
|
||
</blockquote>
|
||
<p>If you omit the list of formal arguments, all checking is
|
||
bypassed as in ``classic'' Jam. Argument lists drastically improve the
|
||
reliability and readability of your rules, however, and are <b>strongly
|
||
recommended</b> for any new Jam code you write.
|
||
|
||
<h4><a name="module_support">Module Support</a></h4>
|
||
|
||
<p>Boost Jam introduces support for modules, which provide some
|
||
rudimentary namespace protection for rules and variables. A new
|
||
keyword, ``<tt>module</tt>'' was also introduced. The features
|
||
described in this section are <i>primitives</i>, meaning that
|
||
they are meant to provide the operations needed to write Jam
|
||
rules which provide a more elegant module interface.
|
||
|
||
<p>
|
||
|
||
<blockquote>
|
||
<h5><a name="module_support">Declaration</a></h5>
|
||
<a name="module_declaration"><tt>module<EFBFBD></tt>
|
||
<i>expression</i><tt><EFBFBD>{<7B></tt> ...<tt><EFBFBD>}<7D></tt></a>
|
||
|
||
<p>Code within the <tt>{<7B></tt> ...<tt><EFBFBD>}</tt> executes within the
|
||
module named by evaluating <i>expression</i>. Rule definitions can be
|
||
found in the module's own namespace, and in the namespace of the global
|
||
module as <i>module-name</i><tt>.</tt><i>rule-name</i>, so within a
|
||
module, other rules in that module may always be invoked without
|
||
qualification:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
<b>module my_module
|
||
{</b>
|
||
rule salute ( x ) { ECHO $(x), world ; }
|
||
rule greet ( ) { salute hello ; }
|
||
greet ;
|
||
<b>}
|
||
my_module.salute</b> goodbye ;
|
||
</pre>
|
||
</blockquote>
|
||
When an invoked rule is not found in the current module's namespace, it
|
||
is looked up in the namespace of the global module, so qualified calls
|
||
work across modules:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
module your_module
|
||
{
|
||
rule bedtime ( ) { <b>my_module.salute</b> goodnight ; }
|
||
}
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<p>
|
||
|
||
<h5><a name="module_locals">Local Variables</a></h5>
|
||
<tt>module<EFBFBD>local<EFBFBD></tt> <i>expression</i><tt><EFBFBD>;</tt><br>
|
||
<i>- or -</i><br>
|
||
<tt>module<EFBFBD>local<EFBFBD></tt> <i>expression</i><tt><EFBFBD>=<3D></tt>
|
||
<i>expression2</i><tt><EFBFBD>;</tt>
|
||
|
||
<p>The variables named by <i>expression</i> are given a distinct value
|
||
in the module, and can be manipulated by code executing in the module
|
||
without affecting variable bindings seen by other modules. If the
|
||
assignment form is used, <i>expression2</i> is assigned to the
|
||
variables when the declaration is executed. For example:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
module M {
|
||
<b>module local</b> x = a b c ;
|
||
|
||
rule f ( )
|
||
{
|
||
{
|
||
local x = 1 2 3 ; # temp override for M's x
|
||
N.g ; # call into module N, below
|
||
}
|
||
ECHO $(x) ; # prints "a b c"
|
||
}
|
||
}
|
||
|
||
module N {
|
||
rule g ( )
|
||
{
|
||
x = foo bar baz ; # sets global x
|
||
M.h ; # call back into M, below
|
||
}
|
||
}
|
||
|
||
module M {
|
||
rule h ( )
|
||
{
|
||
ECHO $(x) ; # prints "1 2 3"
|
||
}
|
||
}
|
||
|
||
M.f ;
|
||
ECHO $(x) ; # prints "foo bar baz"
|
||
</pre>
|
||
</blockquote>
|
||
The only way to access another module's local variables is through a
|
||
rule defined in that module:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
module M {
|
||
rule get ( names * )
|
||
{
|
||
return $($(names)) ;
|
||
}
|
||
}
|
||
ECHO [ <b>M.get</b> x ] ; # prints "a b c"
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<h5><a name="local_rules">Local Rules</a></h5>
|
||
|
||
<blockquote>
|
||
<tt>local rule</tt> <i>rulename...</i>
|
||
</blockquote>
|
||
|
||
<p>The rule is declared locally to the current module. It is
|
||
not entered in the global module with qualification, and its
|
||
name will not appear in the result of
|
||
<blockquote>
|
||
<tt>[ RULENAMES</tt> <i>module-name</i><tt> ]</tt>.
|
||
</blockquote>
|
||
|
||
<h5><a name="RULENAMES_rule">The <tt>RULENAMES</tt> Rule</a></h5>
|
||
|
||
<blockquote>
|
||
<pre>
|
||
rule RULENAMES ( module ? )
|
||
</pre>
|
||
</blockquote>
|
||
Returns a list of the names of all non-local rules in the given module.
|
||
If <tt>module</tt> is omitted, the names of all non-local rules in the
|
||
global module are returned.
|
||
<h5><a name="IMPORT_rule">The <tt>IMPORT</tt> Rule</a></h5>
|
||
|
||
<tt>IMPORT</tt> allows rule name aliasing across modules:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
rule IMPORT ( source_module ? : source_rules *
|
||
: target_module ? : target_rules * )
|
||
</pre>
|
||
</blockquote>
|
||
The <tt>IMPORT</tt> rule copies rules from the <tt>source_module</tt> into the
|
||
<tt>target_module</tt> as <tt>local</tt> rules. If either <tt>source_module</tt> or
|
||
<tt>target_module</tt> is not supplied, it refers to the global
|
||
module. <tt>source_rules</tt> specifies which rules from the <tt>source_module</tt> to
|
||
import; <tt>TARGET_RULES</tt> specifies the names to give those rules in
|
||
<tt>target_module</tt>. If <tt>source_rules</tt> contains a name which doesn't
|
||
correspond to a rule in <tt>source_module</tt>, or if it contains a different
|
||
number of items than <tt>target_rules</tt>, an error is issued. For example,
|
||
|
||
<blockquote>
|
||
<pre>
|
||
# import m1.rule1 into m2 as local rule m1-rule1.
|
||
IMPORT m1 : rule1 : m2 : m1-rule1 ;
|
||
|
||
# import all non-local rules from m1 into m2
|
||
IMPORT m1 : [ RULENAMES m1 ] : m2 : [ RULENAMES m1 ] ;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<h5><a name="EXPORT_rule">The <tt>EXPORT</tt> Rule</a></h5>
|
||
|
||
<tt>EXPORT</tt> allows rule name aliasing across modules:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
rule EXPORT ( module ? : rules * )
|
||
</pre>
|
||
</blockquote>
|
||
The <tt>EXPORT</tt> rule marks <tt>rules</tt> from the <tt>source_module</tt> as non-local
|
||
(and thus exportable). If an element of <tt>rules</tt> does not name a
|
||
rule in <tt>module</tt>, an error is issued. For example,
|
||
<blockquote>
|
||
<pre>
|
||
module X {
|
||
local rule r { ECHO X.r ; }
|
||
}
|
||
IMPORT X : r : : r ; # error - r is local in X
|
||
EXPORT X : r ;
|
||
IMPORT X : r : : r ; # OK.
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<h5><a name="CALLER_MODULE_rule">The <tt>CALLER_MODULE</tt> Rule</a></h5>
|
||
|
||
<blockquote>
|
||
<pre>
|
||
rule CALLER_MODULE ( levels ? )
|
||
</pre>
|
||
</blockquote>
|
||
<tt>CALLER_MODULE</tt> returns the name of the module scope
|
||
enclosing the call to its caller (if levels is supplied, it is
|
||
interpreted as an integer number of additional levels of call stack to
|
||
traverse to locate the module). If the scope belongs to the global
|
||
module, or if no such module exists, returns the empty list. For
|
||
example, the following prints "{Y} {X}":
|
||
|
||
<blockquote>
|
||
<pre>
|
||
module X {
|
||
rule get-caller { return [ CALLER_MODULE ] ; }
|
||
rule get-caller's-caller { return [ CALLER_MODULE 1 ] ; }
|
||
|
||
rule call-Y { return Y.call-X2 ; }
|
||
|
||
}
|
||
module Y {
|
||
rule call-X { return X.get-caller ; }
|
||
rule call-X2 { return X.get-caller's-caller ; }
|
||
}
|
||
|
||
callers = [ X.get-caller ] [ Y.call-X ] [ X.call-Y ] ;
|
||
ECHO {$(callers)} ;
|
||
|
||
</pre>
|
||
</blockquote>
|
||
|
||
</blockquote>
|
||
|
||
<h4><a name="local_foreach">Local For Loop Variables</a></h4>
|
||
|
||
<p>Boost Jam allows you to declare a local <tt>for</tt> loop control
|
||
variable right in the loop:
|
||
<blockquote><pre>
|
||
x = 1 2 3 ;
|
||
y = 4 5 6 ;
|
||
for <b>local</b> y in $(x)
|
||
{
|
||
ECHO $(y) ; # prints "1", "2", or "3"
|
||
}
|
||
ECHO $(y) ; # prints "4 5 6"
|
||
</pre></blockquote>
|
||
|
||
<h4><a name="while_loops">While Loops</a></h4>
|
||
|
||
In classic Jam, some constructs are only possible using recursion:
|
||
<blockquote><pre>
|
||
# returns the part of $(list) following the first occurrence of $(symbol)
|
||
rule after-symbol ( symbol : list * )
|
||
{
|
||
if ! $(list) || ( $(symbol) = $(list[1]) )
|
||
{
|
||
return $(list[2-]) ;
|
||
}
|
||
else
|
||
{
|
||
return [ after-symbol $(symbol) : $(list[2-]) ] ;
|
||
}
|
||
}
|
||
</pre></blockquote>
|
||
The addition of <tt>while</tt> loops allows a simpler formulation for this and
|
||
many other rules:
|
||
<blockquote><pre>
|
||
rule after-symbol ( symbol : list * )
|
||
{
|
||
while $(list) && $(list[1]) != $(symbol)
|
||
{
|
||
list = $(list[2-]) ;
|
||
}
|
||
return $(list) ;
|
||
}
|
||
</pre></blockquote>
|
||
|
||
<h4><a name="negative_indexing">Negative Indexing</a></h4>
|
||
|
||
Classic Jam supplies 1-based list indexing, and slicing on a closed
|
||
(inclusive) range:
|
||
<blockquote><pre>
|
||
x = 1 2 3 4 5 ;
|
||
ECHO $(x[3]) ; # prints "3"
|
||
ECHO $(x[2-4]) ; # prints "2 3 4"
|
||
ECHO $(x[2-]) ; # prints "2 3 4 5"
|
||
</pre></blockquote>
|
||
|
||
Boost Jam adds Python-style negative indexing to access locations relative
|
||
to the <i>end</i> of the list.
|
||
|
||
<blockquote><pre>
|
||
ECHO $(x[-1]) $(x[-3]) ; # prints "5 3"
|
||
ECHO $(x[-3--1]) ; # prints "3 4 5"
|
||
ECHO $(x[-3-4]) ; # prints "3 4"
|
||
ECHO $(x[2--2]) ; # prints "2 3 4"
|
||
</pre></blockquote>
|
||
|
||
Consistency with the 1-based, inclusive
|
||
indexing of Classic Jam and the use of ``<tt>-</tt>'' as the
|
||
range separator make this feature a bit clumsier than it would otherwise
|
||
need to be, but it does work.
|
||
|
||
<h4><a name="BINDRULE">Target Binding Detection</a></h4>
|
||
|
||
<p>Whenever a target is <a href="#binding">bound</a> to a location in the
|
||
filesystem, Boost Jam will look for a variable called <tt>BINDRULE</tt> (first
|
||
``<tt>on</tt>'' the target being bound, then in the global module). If
|
||
non-empty, <tt>$(BINDRULE[1])</tt> names a rule which is called with the
|
||
name of the target and the path it is being bound to. The signature of the
|
||
rule named by <tt>$(BINDRULE[1])</tt> should match the following:
|
||
|
||
<blockquote><pre>
|
||
rule bind-rule ( target : path )
|
||
</pre></blockquote>
|
||
|
||
This facility is useful for correct header file scanning, since many
|
||
compilers will search for <tt>#include</tt>d files first in the directory
|
||
containing the file doing the <tt>#include</tt>
|
||
directive. <tt>$(BINDRULE)</tt> can be used to make a record of that
|
||
directory.
|
||
|
||
<h4><a name="FAIL_EXPECTED">Return Code Inversion</a></h4>
|
||
|
||
<p>For handling targets whose build actions are expected to fail
|
||
(e.g. when testing that assertions or compile-time type checkin work
|
||
properly), Boost Jam supplies a <tt>FAIL_EXPECTED</tt> rule in the same
|
||
style as <tt>NOCARE</tt>, et. al. During target updating, the return code
|
||
of the build actions for arguments to <tt>FAIL_EXPECTED</tt> is inverted:
|
||
if it fails, building of dependent targets continues as though it
|
||
succeeded. If it succeeds, dependent targets are skipped.
|
||
|
||
<h4><a name="NOCARE">Ignoring Return Codes</a></h4>
|
||
|
||
|
||
<p>Perforce Jam supplied a <tt>NOCARE</tt> rule which is typically used for
|
||
header files to indicate that if they are not found, the dependent targets
|
||
should be built anyway. Boost Jam extends <tt>NOCARE</tt> to apply to
|
||
targets with build actions: if their build actions exit with a nonzero
|
||
return code, dependent targets will still be built.
|
||
<h4><a name="SUBST_rule">The <tt>SUBST</tt> Rule</a></h4>
|
||
|
||
<p>The behavior of the <tt>SUBST</tt> rule for regular-expression matching
|
||
and replacement (originally added in <a href=
|
||
"http://freetype.sourceforge.net/jam/index.html">FTJam</a>) has been
|
||
modified:
|
||
|
||
<ul>
|
||
<li>
|
||
One or more replacement patterns may be supplied. The new signature
|
||
for <tt>SUBST</tt> is:
|
||
|
||
<blockquote>
|
||
<pre>
|
||
SUBST ( source pattern replacements + )
|
||
</pre>
|
||
</blockquote>
|
||
The return value is the concatenated results of applying each element
|
||
of <tt>replacements</tt> in turn. For example, the following will
|
||
print ``<tt>[x] (y) {z}</tt>'':
|
||
|
||
<blockquote>
|
||
<pre>
|
||
ECHO [ SUBST xyz (.)(.)(.) [$1] ($2) {$3} ] ;
|
||
</pre>
|
||
</blockquote>
|
||
|
||
<li>
|
||
If there is no match, <tt>SUBST</tt> now returns an empty list. In
|
||
FTJam, the original <tt>source</tt> string was returned, making it
|
||
awkward to check whether a pattern was matched.
|
||
|
||
<p>
|
||
|
||
<li>Compiled regular expressions are now internally cached, making it
|
||
much faster to use <tt>SUBST</tt> multiple times with the same string.
|
||
</ul>
|
||
|
||
<h4><a name="#JAM_VERSION">The <tt>JAM_VERSION</tt> global variable</a></h4>
|
||
|
||
<p>A predefined global variable with two elements indicates the version
|
||
number of Boost Jam. Boost Jam versions start at <tt>"03" "00"</tt>. Earlier
|
||
versions of Jam do not automatically define <tt>JAM_VERSION</tt>.
|
||
|
||
|
||
<h4><a name="debugging_support">Debugging Support</a></h4>
|
||
|
||
<h5><a name="BACKTRACE_rule">The BACKTRACE rule</a></h5>
|
||
|
||
<blockquote><pre>
|
||
rule BACKTRACE ( )
|
||
</pre></blockquote>
|
||
|
||
Returns a list of quadruples: <i>filename line module
|
||
rulename</i>..., describing each shallower level of the call
|
||
stack. This rule can be used to generate useful diagnostic
|
||
messages from Jam rules.
|
||
|
||
<p>The <tt>-d</tt> command-line option admits new arguments:
|
||
|
||
<ul>
|
||
<li> <tt>-d+10</tt> - enables <a name="profiling"><b>profiling</b></a> of rule
|
||
invocations. When Jam exits, it dumps all rules invoked, their gross
|
||
and net times in platform-dependent units, and the number of times the
|
||
rule was invoked.
|
||
|
||
<li> <tt>-d+11</tt> - enables <a name="parse_debugging"><b>parser
|
||
debugging</b></a>, if Jam has been compiled with the "--debug"
|
||
option to the parser generator named by $(YACC).
|
||
|
||
<li> <tt>-d+12</tt> - enables <a
|
||
name="dependency_graph"><b>dependency graph output
|
||
</b></a>. This feature was ``stolen'' from a version of Jam
|
||
modified by <a href="mailto:cmcpheeters@aw.sgi.com">Craig
|
||
McPheeters</a>.
|
||
|
||
</ul>
|
||
|
||
</blockquote>
|
||
|
||
<h3><a name="target_names">Target Names</a></h3>
|
||
|
||
<p>In addition to <a href="#user_targets">user targets</a>, which
|
||
correspond directly to the names the user writes in her subproject Jamfile,
|
||
several additional targets are generated, regardless of the directory from
|
||
which Jam was invoked:
|
||
|
||
<ul>
|
||
<li>A <b>main target</b> has all the same dependencies as a user target
|
||
(i.e. building it updates all requested subvariants). Its name is the
|
||
same except for the addition of <tt>$(SOURCE_GRIST)</tt>, which
|
||
identifies the subproject. The identification looks like the names of the
|
||
path components from the project root to the subproject, separated by
|
||
exclamation points. Thus, if the project is rooted at <tt>foo</tt>, in
|
||
the subproject at <tt>foo/bar/baz</tt> the target <tt>my_target</tt> is
|
||
identified by <tt><bar!baz>my_target</tt>.
|
||
|
||
|
||
<li>A <b>subvariant target</b> has additional grist identifying its main target
|
||
and subvariant. This grist is joined to <tt>$(SOURCE_GRIST)</tt> with
|
||
the platform's directory separator. Thus, on UNIX, a subvariant target
|
||
of <tt>my_target</tt> above might be identified as
|
||
<tt><bar!baz/my_target/optimization-space/runtime-link-static>my_source.o</tt>.
|
||
Note that the part of the grist following the first slash, known as the
|
||
<b>subvariant id</b>, also corresponds to a fragment of the subvariant
|
||
directory path where the corresponding target is generated. Most built
|
||
targets will be identified this way.
|
||
</ul>
|
||
|
||
<h3><a name="internal_globals">Global Variables</a></h3>
|
||
|
||
<p>This section describes some of the global variables used by the build
|
||
system. Please note that some parts of the system (particularly those in
|
||
<tt>allyourbase.jam</tt>) are heavily based on the Jambase file supplied
|
||
with Jam, and as such do not follow the conventions described below.
|
||
|
||
<p>Global variables used in the build system fall into three categories:
|
||
|
||
<ul>
|
||
<li> Global variables intended to
|
||
be set by the user on the command-line or in the environment use
|
||
<tt>ALL_UPPER_CASE</tt> names.
|
||
|
||
<li> Internal global variables begin with a lower-case "g" and
|
||
continue in upper-case: <tt>gSOME_GLOBAL</tt>
|
||
|
||
<li> Global variables of the form:
|
||
<tt>gBASE_NAME(</tt><i>arguments</i><tt>)</tt>, where <i>arguments</i> is a
|
||
comma-separated argument list, are used internally to achieve a kind of
|
||
indirection by concatenating variable values:
|
||
|
||
<blockquote><pre>
|
||
ECHO $(gFUBAR($(x),$(y))) ;
|
||
</pre>
|
||
</blockquote>
|
||
</ul>
|
||
|
||
<p>Please note that the build system commonly takes advantage of <a
|
||
href="http://public.perforce.com/public/jam/src/Jam.html#bindingmods">Jam's
|
||
Dynamic Scoping feature</a> (see the <tt>local</tt> command in the
|
||
"Flow of Control" section below the link target) to temporarily
|
||
"change" a global variable by declaring a <tt>local</tt> of the
|
||
same name.
|
||
|
||
<h3>Variables Associated with SubProject Identity</h3>
|
||
|
||
<ul>
|
||
<li><tt>SUBDIR_TOKENS</tt> - a list of the path elements relative to the
|
||
project root of the current subproject.
|
||
|
||
<li><tt>SUBDIR</tt> - the path from the invocation directory to the
|
||
current subproject directory.
|
||
</ul>
|
||
|
||
<h3>Grist Variables</h3>
|
||
|
||
<ul>
|
||
<li><tt>TARGET_GRIST</tt> takes the form
|
||
<tt><i>subproject!id</i>/target/toolset/variant/<i>subvariant-path</i></tt>.
|
||
</ul>
|
||
|
||
<h2><a name="design_criteria">Design Criteria</a></h2>
|
||
|
||
<h3><a name="assumptions">Assumptions</a></h3>
|
||
|
||
<p>The requirements are driven by several basic assumptions:
|
||
|
||
<ul>
|
||
<li>There is no single Boost developer or test facility with access to or
|
||
knowledge of all the platforms and compilers Boost libraries are used
|
||
with.
|
||
|
||
<li>Boost libraries are used across such a wide range of platforms and
|
||
compilers that almost no other assumptions can be made.
|
||
</ul>
|
||
|
||
<h3><a name="requirements">Requirements</a></h3>
|
||
|
||
<p>This build system was designed to satisfy the following requirements:
|
||
|
||
<ul>
|
||
<li>A developer adding a new library or test program must only have to
|
||
add simple entries naming the source files to a text file, and not have
|
||
to know anything about platform specific files. The developer should not
|
||
have to supply header dependency information.
|
||
|
||
<li>There should be a very high likelihood of builds succeeding on all
|
||
platforms if a build succeeds on any platform. In other words, a
|
||
developer must not be required to have access to many platforms or
|
||
compilers to ensure correct builds
|
||
|
||
<li>A user or developer adding support for a new platform or compiler
|
||
should only have to add to a single file describing how to do the build
|
||
for that platform or compiler, and shouldn't have to identify the files
|
||
that will need to be built.
|
||
|
||
<li>The build should rely only on tools native to the platform and
|
||
compiler, or supplied via the boost download.
|
||
|
||
<li>The details of how the build is done for a particular platform or
|
||
compiler should be appropriate for that platform.
|
||
|
||
<li>It should be possible to build multiple variants (e.g. debug/release)
|
||
of a single target.
|
||
|
||
<li>It should be possible to build multiple variants of multiple targets
|
||
with multiple compilers from a single build command.
|
||
|
||
<li>The build tools must be able to handle Boost growth issues such as
|
||
identified in Directory Structure proposals and discussion.
|
||
|
||
<li>Support for dynamic and static linking should be included.
|
||
|
||
<li>It should be relatively straightforward to add support for a new
|
||
compiler. In most cases, no modification of files used to describe
|
||
existing targets should be required.
|
||
|
||
<li>Support for compiler- and variant-specific configuration for each
|
||
target
|
||
|
||
<li>It should be possible to build targets into a directory unrelated to
|
||
the source directories (they may be read-only)
|
||
</ul>
|
||
|
||
<h2><a name="footnotes">Footnotes</a></h2>
|
||
<a name="1">[1]</a> Boost Jam is actually descended directly from <a
|
||
href="http://freetype.sourceforge.net/jam/index.html">FTJam</a>, which was
|
||
itself a variant of <a href=
|
||
"http://www.perforce.com/jam/jam.html">Jam/MR</a>. It is hoped that crucial
|
||
features we rely on will eventually be incorporated back into the Jam/MR release.
|
||
|
||
<p><a name="2">[2]</a> Note: right now, a dependency feature of a main
|
||
target makes <b>all</b> resulting built targets dependent, including
|
||
intermediate targets. That means that if an executable is dependent on an
|
||
external library, and that library changes, all the sources comprising the
|
||
executable will be recompiled as well. This behavior should probably be
|
||
fixed.
|
||
<hr>
|
||
|
||
<p>© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||
sell and distribute this document is granted provided this copyright notice
|
||
appears in all copies. This document is provided "as is" without express or
|
||
implied warranty, and with no claim as to its suitability for any purpose.
|
||
|
||
<p>Revised
|
||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
|
||
-->11 November, 2001
|
||
<!--webbot bot="Timestamp" endspan i-checksum="21080"
|
||
-->
|
||
</body>
|
||
|