Boost logo

Boost-Build :

From: David Abrahams (dave_at_[hidden])
Date: 2005-09-20 16:35:08


> Chapter 24. User documentation
>
>
> This section will provide the information necessary to create
> your own projects using Boost.Build.

Haven't we already been doing that? This section doesn't really make
sense as is. The section called "tutorial" should really be broken
into two parts: "Hello World" for getting started, and the rest, which
should be incorporated into this section

> The information provided here is relatively high-level, and
> Chapter 26, Detailed reference as well as the on-line help system
> must be used to obtain low-level documentation (see ???).
^^^^^^^^^
strike this

> Boost.Build actually consists of two parts - Boost.Jam, a build
^
(bjam)
> engine with its own interpreted language, and Boost.Build
> itself, implemented in Boost.Jam's language.

Rewrite as

Boost.Build actually consists of two parts. First, there is
Boost.Jam (bjam), a low-level build engine written in C, which
handles basic jobs such as dependency checking and invoking build
commands, and the high-level build system, which interprets your
target descriptions and decides what dependencies and commands
should be used to build them. A little interpreter for a
specialized language is built into bjam. The rest of the build
system, including your Jamfiles, is implemented in that language.

then move it much earlier, somewhere into what is currently the
tutorial. This is basic information that's necessary for coming to
grips with BB, and unless users get it early, the whole thing will
look very mysterious.

> The chain of events when you type bjam on the command line is:
>
> 1. Boost.Jam tries to find Boost.Build and loads the top-level
> module. The exact process is described in the section
> called “Initialization”
>
> 2. The top-level module loads user-defined configuration
> files, user-config.jam and site-config.jam, which define
> available toolsets.

Explain the purpose of site-config.jam.

> 3. The Jamfile in the current directory is read. That in turn
> might cause reading of further Jamfiles. As a result, a
> tree of projects is created, with targets inside projects.
>
> 4. Finally, using the build request specified on the command
> line, Boost.Build decides which targets should be built,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
determines a superset of the targets to
> and how. That information is passed back to Boost.Jam,
> which takes care of actually running commands.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
determines which of the targets are missing or out-of-date
and issues the commands to build them.
>
> So, to be able to successfully use Boost.Build, you need to
> know only three things:
>
> ● How to configure Boost.Build
>
> ● How to write Jamfiles
>
> ● How the build process works
>
> ● Some Basics about the Boost.Jam language.

Ahem. That's four. And shouldn't these be in the same order as the
presentation in the document?

> See the Boost.Jam
> and Classic Jam documentation.

Strike that. The basics need to be given in this document, and IIRC
they are.

Ack! What happened to the section called "Boost.Jam language" that
used to follow this one?? I have lots of remarks on that section, but
it was basically valid and, IMO, crucial. Oh, bizarre; it appears to
be checked in to CVS and has been for quite some time. I'm going to
stick the XML in here and strip the tags:

> Boost.Jam language
>
> This section will describe the basics of the Boost.Jam language—just
> enough for writing Jamfiles. For more information, please see the
> Boost.Jam and Classic Jam documentation.
>
> Boost.Jam has an interpreted, procedural language.
^^^
"is", maybe?

> On the lowest level, a Boost.Jam program consists of variables and
^^
"At"

> rule rules (the Jam term for function). They are grouped in
^^^^ ^^^^^^^^
strike that "functions"

> modules—there's 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.

Except class instances, right? I know that everything is a list of
strings on some level, but on another a class instance has distinct
type. Unless you explain this, or just drop mention of classes,
readers will wonder about this.

> 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 with the
> $(variable) syntax. For example:
>
> a = $(b) $(c) ;
>
>
>
> Rules are defined by specifying the rule name, the parameter names,
> and the allowed size of the list value for each parameter.
>
> rule example
> (
> parameter1 :
> parameter2 ? :
> parameter3 + :
> parameter4 *
> )
> {
> // 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
^^
"or"
> be arbitrary long, but the third argument may not be empty.
^^^^^^^^^
"arbitrarily"

Start a new subsection here:

> The overview of Boost.Jam language statements is given below:
^^^
"An"
>
> helper 1 : 2 : 3 ;
> x = [ helper 1 : 2 : 3 ] ;
>
> This code calls the named rule with the specified arguments.

"Both lines call the rule named "helper" with three arguments, each
of which is a single element list consisting of "1", "2", and "3",
respectively.

> 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.

"To capture the result of the call, you need to enclose it in
brackets as shown on the second line."
>
> if cond { statements } [ else statement ]

First of all cond, statements and statement need to be made
<replaceable>...</>. Secondly, you need to typographically
distinguish the literal {}s from the []s which denote optionalness.

> Regular if-statement. The condition is composed of:
>
> Literals (true if at least one string is not empty)
> Comparisons: a operator b where operator is one of =,
> !=, <, >, <=, >=.

> The comparison is done pairwise between each string in the
> left and the right arguments.

"The two lists of strings—and their elements—are
compared lexicographically."

>
> Logical operations: ! a, a && b, a || b

You need more spacing around these. The commas group everything too
closely.

> Grouping: ( cond )
>
>
> for var in list { statements }
^
[local]

var, list, statements should be <replaceable>...</>

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

Ditto

> while cond { statements }
>
> Repeatedly execute statements while cond remains true upon entry.
^^^^^^^^^^
strike this
>
> return values ;
>
> This statement should be used only inside a
> rule and assigns values to the return value of the
> rule.
>
> The return statement does not exit the rule. For example:
>
> rule test ( )
> {
> if 1 = 1 {
> return "resonable" ;
^^^^^^^^^
"reasonable"
> }
> return "strange" ;
> }
>
> will return strange, not
> resonable.
^^^^^^^^^
"reasonable"

>
> import module ;
> import module : rule ;
^^^^
"rules..."

> The first form imports the specified bjam module. All rules from
> that module are made available using the qualified name:
> module.rule. The second form imports the specified rules only, and
> they can be called using unqualified names.
>
> Configuration
>
> The Boost.Build configuration is specified in the file
> user-config.jam. You can edit the one that comes with
> Boost.Build, or create a copy in your home directory and edit
> that. (See the reference for the exact search paths.) The
> primary function of that file is to declare which compilers and
> other tools are available. The simplest syntax to configure a
> tool is:
>
> using tool-name ;
>
> The using rule is given a name of tool, and will make that tool
^^
the
> available to Boost.Build.

Have we even been introduced to the notion of tools? Very early in
the documentation (tutorial or before) we should describe the fact
that BBv2 is extensible through a set of pluggable toolsets and
platform-independent build features. This in effect turns an NxM
build problem (N libraries, M platforms/compilers) into a N+M problem,
much as iterators do in the standard library (N algorithms, M data
structures).

> For example, using gcc ; will make
> the gcc compiler available.
^
"suite"

> Since nothing but a tool name is specified, Boost.Build will
> pick some default settings. For example, it will use the gcc
> executable found in the PATH, or look in some known
> installation locations. In most cases, this strategy works
> automatically. In case you have several versions of a compiler,
^^^^^^^
"If"
> it's installed in some unusual location, or you need to tweak
^^^^
"your compiler is"

> its configuration, you'll need to pass additional parameters to
> the using rule. The parameters to using can be different for
> each tool. You can obtain specific documentation for any tool's
> configuration parameters by invoking
>
> bjam --help tool-name.init
>
> That said, for all the compiler toolsets Boost.Build supports
> out-of-the-box, the list of parameters to using is the same:
> toolset-name, version, invocation-command, and options.
>
> The version parameter identifies the toolset version, in case
> you have several installed. It can have any form you like, but
^
"versions"

> it's recommended that you use a numeric identifier like 7.1.
^
"or 3.4.2. If you expect Boost.Build to configure automatically, use
a standard numeric form supported by the toolset."

>
> The invocation-command parameter is the command that must be
> executed to run the compiler.
^^^^^^^^
"primary executable of the toolset (usually a compiler)."

> This parameter can usually be omitted if the compiler executable
^^^^^^^^
strike
>
> ● has its “usual name” and is in the PATH, or
>
> ● was installed in a standard “installation directory”, or

Remove all quotation marks from these bullets.

> ● can be found through a global mechanism like the Windows
> registry.
>
> For example:
>
> using msvc : 7.1 ;
> using gcc ;
>
> If the compiler can be found in the PATH but only by a
> nonstandard name, you can just supply that name:
>
> using gcc : : g++-3.2 ;
>
> Otherwise, it might be necessary to supply the complete path to
> the compiler executable:
>
> using msvc : : Z:/Programs/Microsoft Visual Studio/vc98/bin/cl ;
>
> Some Boost.Build toolsets will use that path to take additional
> actions required before invoking the compiler, such as calling
> vendor-supplied scripts to set up its required environment
> variables.
>
> To configure several versions of a toolset, simply invoke the
> using rule multiple times:
>
> using gcc : 3.3 ;
> using gcc : 3.4 : g++-3.4 ;
> using gcc : 3.2 : g++-3.2 ;
>
> Note that in the first call to using, the compiler found in the
> PATH will be used, and there's no need to explicitly specify
> the command.
>
> As shown above, both the version and invocation-command
> parameters are optional, but there's an important restriction:
> if you configure the same toolset more than once, you must pass
> the version parameter every time. For example, the following is
> not allowed:
>
> using gcc ;
> using gcc : 3.4 : g++-3.4 ;
>
> because the first using call does not specify a version.
>
> The options parameter is used to fine-tune the configuration.
> All of Boost.Build's standard compiler toolsets accept
> properties of the four builtin features cflags, cxxflags,
> compileflags and linkflags as options specifying flags that
> will be always passed to the corresponding tools. Values of the
> cflags feature are passed directly to the C compiler, values of
> the cxxflags feature are passed directly to the C++ compiler,
> and values of the compileflags feature are passed to both. For
> example, to configure a gcc toolset so that it always generates
> 64-bit code you could write:
>
> using gcc : 3.4 : : <compileflags>-m64 <linkflags>-m64 ;

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com
 

Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk