Boost.Build v2 user manual


This is a preliminary version intended to document everything implemeneted but not yet ready for any practical use.



Reference documentation
Features and properties
Initialization
Command line
Projects
Targets
Build process

Reference

Features and properties

Definition

A feature is a normalized (toolset-independent) aspect of a build configuration, such as whether inlining is enabled.

A feature value is a specific available setting for a feature.

A property is a (feature,value) pair, expressed as <feature>value.

A subfeature is a feature which only exists in the presence of its parent, and whose identity can be derived (in the context of its parent) from the name of its value.

A value-string is a string of the form value-subvalue1-subvalue2...-subvalueN, where value is a feature value and subvalue1...subvalueN are values of related subfeatures. For example, by using value-string properties <toolset>gcc <toolset-version>3.0.1, can be expressed more conscicely, as <toolset>gcc-3.0.1.

A set of properties is called, naturally, property set. For example, <toolset>gcc <runtime-link>static. Sometimes it's better to represent a property set without spaces. In that case property path is used, which consists of all properties, joined with slashes. To continue with example, property path representation would be <toolset>gcc/<runtime-link>static .

Each feature can have any of the following attributes:

TODO: document active features..

When the build system tries to generate a target (such as library dependency) matching a given build request, it may find that an exact match isn't possible — for example, the target may impose additonal build requirements. We need to determine whether a buildable version of that target can actually be used.

In general, there are many possible situations: a libary which is dependency of a main target and should be linked into it, target which is directly requested on the command line, or build executable which is used in the build process itself. At this moment we use a simple approach.

Two property sets are called link-compatible when targets with those property sets can be used interchangably. In turn, two property sets are link compatible when there's no link-incompatible feature which has different values in those property sets. Whenever requested and actual properties are link-compatible, it's OK. Otherwise, it's an error.

Definition of property refinement

When a target with certain properties is requested, and that target requires some set of properties, it is needed to find the set of properties to use for building. This process is called property refinement and is performed by these rules

  1. If original properties and required properties are not link-compatible, refinement fails.
  2. Each property in the required set is added to the original property set
  3. If the original property set includes property with a different value of non free feature, that property is removed.

Initialization

Immediately upon startup, the bjam executable attempts to find the location of build system files. It does so by looking for a file called boost-build.jam. That file is first looked in the invocation directory and its parents up to the filesystem root, and then in the directories from variable BOOST_BUILD_PATH. When found, the file is loaded and should specify the build system location by calling the boost-build rule:

    rule boost-build ( location ? )
   
The directory specified by location and directories in BOOST_BUILD_PATH are searched for a file called bootstrap.jam which is loaded and completes startup.

This arrangement allows to make build system work without any environmental variables. For example, build system files can be placed in a directory boost-build at your project root, and a file boost-build.jam at the project root can contain:

    boost-build boost-build ;
   
In this case, running bjam in the project root will automatically find the build system.

Command line

The comamnd line may contain:

Command line arguments

Command line arguments specify targets and build request using the following rules. For example, the command line
    target1 debug gcc/runtime-link=dynamic,static
   
would cause target called target1 to be rebuild in debug mode, except that for gcc, both dynamically and statically linked binaries would be created.

TODO: should allow

    target1 debug gcc,borland/runtime-link=static
   
to work.

Command line options

All of the Boost.Build options start with the "--" prefix. They are described in the following table.

Command line options
Option Description
--debug Enables internal checks.
--dump-projects Cause the project structure to be output.
--help Access to the online help system. This prints general information on how to use the help system with additional --help* options.

Projects

Boost.Build considers every software it build as organized into projects, which corresponds to a single Jamfile. The project are organized in a hierarchical structure, so for each project we can talk about parent project, which is always unique and a number of subprojects. (TODO: project root).

Project attributes

For each project, there are several attributes.

Project id is a short way to denote a project, as opposed to the Jamfile's pathname. It is a hierarchical path, unrelated to filesystem, such as "boost/thread". There are two ways to refer to a project using project-id:

Source location specifies the directory where sources for the project are located.

Project requirements are requirements that apply to all the targets in the projects as well as all subprojects.

Default build is the build request that should be used when no build request is specified explicitly.

The default values for those attributes are given in the table below. In order to affect them, Jamfile may call the project rule. The rule has this syntax:

    project id : <attributes> ;
   
Here, attributes is a sequence of (attribute-name, attribute-value) pairs. The list of attribute names along with its handling is shown in the table below. For example, it it possible to write:
    project tennis 
        : requirements <threading>multi 
        : default-build release
        ;
   
Attribute Name for the 'project' rule Default value Handling by the 'project' rule
Project id none none Assigned from the first parameter of the 'project' rule. It is assumed to denote absolute project id.
Source location source-location The location of jamfile for the project Sets to the passed value
Requirements requirements The parent's requirements The parent's requirements are refined with the passed requirement and the result is used as the project requirements.
Default build default-build TODO Sets to the passed value

Project relationship

There are three kinds of project relationships.

First is parent-child. This relationship is established implicitly: parent directories of a project are searched, and the first found Jamfile is assumed to define the parent project. The parent-child relationship affects only attribute values for the child project.

Second is build relationship. Some project may request to recursively build other projects. Those project need not be child projects. The build-project rule is used for that:

    build-project src ;   

The third kind is the 'use' relationship. In means that one project uses targets from another. It is possible to just refer to target in other projects using target id. However, if target id uses project id, it is required that the project id is known. The use-project rule is employed to guarantee that.

    use-project ( id : location )
   
It loads the project at the specified location, which makes its project id available in the project which invokes the rule. It is required that the id parameter passed to the use-project rule be equal to the id that the loaded project declared. At this moment, the id paremeter should be absolute project id.

Targets

Main targets and main target alternatives

Main target is a named entity which can be build, for example a named executable file. To declare a main target, user invokes some of the main target rules, passing it things like list of source and requirement.

It is possible to have different list of sources for different toolsets, therefore it is possible to invoke main target rules several times for a single main target. For example:

    exe a : a_gcc.cpp : <toolset> ;
    exe a : a.cpp ;
Each call to the 'exe' rule defines a new main target alternative for the main target a.exe. In this case, the first alternative will be used for the gcc toolset, while the second alternative will be used in other cases. TODO: document the exact selection method under "Build process" below.

Target identifiers and references

Target identifier is used to denote a target. It is described by the following grammar:

    target-id -> project-reference local-target-name
    project-reference -> [jamfile-location] [ "@" [project-id] ]
    jamfile-location -> pathname 
    project-id -> pathname
    local-target-name -> identifier
For example, valid target ids might be:
    a
    lib/b
    @/boost/thread
    /home/ghost/build/lr_library@parser/lalr1
To map the target id into target, the project where that target is contained is first found:
  1. If project-reference is empty, then the current project is used — i.e. the project there the target id occurs.
  2. If the project id is absolute, the project with that id is used.
  3. If the project id is relative, it is treated relatively to project-id of the project at jamfile-location. If that project does not declare project id, it is an error.
After that, the target given by local-target-name in the found project is used.

Target reference is used to specify a source target, and may additionally specify desired properties for that target. It has this syntax:

    target-reference -> target-id [ "/" requested-properties ]
    requested-properties -> property-path
For example,
    exe compiler : compiler.cpp libs/cmdline/<optimization>space ;
would cause the version of cmdline library, optimized for space, to be linked in even if the compile executable is build with optimization for speed.
Ambiguity resolution

Target reference may have the same form as a pathname, for example lib/a. In order to determine if this is target reference or pathname, it is checked if there's a jamfile in the specified path. If there is one, it is loaded and if the specified target is declared by that project it is used. Otherwise, we just treat the target reference as a file name.

Target paths

To distinguish targets build with different properties, they are put in different directories. Rules for determining target paths are given below:

  1. All targets are placed under directory corresponding to the project where they are defined.
  2. Each non free, non incidental property cause an additional element to be added to the target path. That element has the form <feature-name>-<feature-value> for ordinary features and <feature-value> for implicit ones. [Note about composite features].
  3. If the set of free, non incidental properties is different from the set of free, non incidental properties for the project in which the main target that uses the target is defined, a part of the form main_target-<name> is added to the target path. Note:It would be nice to completely track free features also, but this appears to be complex and not extremely needed.

For example, we might have these paths:

    debug/optimization-off
    debug/main-target-a
   

Build process

The build works in this way. On startup, the project in the current directory is read. In turn, it may request building of other projects, which will be loaded recursively. Parent projects are also loaded to inherit some of their properties. As the result, a tree of projects is constructed. After that, the build request is constructed from the command line. Then, the steps are:

  1. All of the projects to be build are passed the build request. If the build request does not satisfy the project's requirements, a warning is issued and the build of the project is skipped. Projects mentioned in build-project rule will still be build.
  2. An attempts to make all the main targets in the project is performed. For each main target:
    1. All main target alternatives which requirements are satisfied by the build request are enumerated.
    2. If there are several such alternatives, the one which longer requirements list is selected.
  3. For each selected alternative
    1. Each target reference in the source list are recursively constructed.
    2. The dependency graph for the target is constructed by running so called matching process, using generated source targets and ordinary sources.

The dependency graph constructed for each target is build of so called "virtual targets", which do not yet correspond to jam's targets. It is therefore converted to jam's dependency graph which is then build.


Last modified: Aug 12, 2002

© Copyright Vladimir Prus 2002. 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.