diff --git a/v2/doc/Jamfile.v2 b/v2/doc/Jamfile.v2
index 16c9efe48..43adbdacf 100644
--- a/v2/doc/Jamfile.v2
+++ b/v2/doc/Jamfile.v2
@@ -1,3 +1,3 @@
project tools/build/v2/doc ;
-boostbook userman : userman.xml ;
+boostbook userman : src/userman.xml ;
diff --git a/v2/doc/html/images/blank.png b/v2/doc/html/images/blank.png
new file mode 100644
index 000000000..764bf4f0c
Binary files /dev/null and b/v2/doc/html/images/blank.png differ
diff --git a/v2/doc/html/images/caution.png b/v2/doc/html/images/caution.png
new file mode 100644
index 000000000..5b7809ca4
Binary files /dev/null and b/v2/doc/html/images/caution.png differ
diff --git a/v2/doc/html/images/draft.png b/v2/doc/html/images/draft.png
new file mode 100644
index 000000000..0084708c9
Binary files /dev/null and b/v2/doc/html/images/draft.png differ
diff --git a/v2/doc/html/images/home.png b/v2/doc/html/images/home.png
new file mode 100644
index 000000000..cbb711de7
Binary files /dev/null and b/v2/doc/html/images/home.png differ
diff --git a/v2/doc/html/images/important.png b/v2/doc/html/images/important.png
new file mode 100644
index 000000000..12c90f607
Binary files /dev/null and b/v2/doc/html/images/important.png differ
diff --git a/v2/doc/html/images/next.png b/v2/doc/html/images/next.png
new file mode 100644
index 000000000..45835bf89
Binary files /dev/null and b/v2/doc/html/images/next.png differ
diff --git a/v2/doc/html/images/note.png b/v2/doc/html/images/note.png
new file mode 100644
index 000000000..d0c3c645a
Binary files /dev/null and b/v2/doc/html/images/note.png differ
diff --git a/v2/doc/html/images/prev.png b/v2/doc/html/images/prev.png
new file mode 100644
index 000000000..cf24654f8
Binary files /dev/null and b/v2/doc/html/images/prev.png differ
diff --git a/v2/doc/html/images/tip.png b/v2/doc/html/images/tip.png
new file mode 100644
index 000000000..5c4aab3bb
Binary files /dev/null and b/v2/doc/html/images/tip.png differ
diff --git a/v2/doc/html/images/toc-blank.png b/v2/doc/html/images/toc-blank.png
new file mode 100644
index 000000000..6ffad17a0
Binary files /dev/null and b/v2/doc/html/images/toc-blank.png differ
diff --git a/v2/doc/html/images/toc-minus.png b/v2/doc/html/images/toc-minus.png
new file mode 100644
index 000000000..abbb020c8
Binary files /dev/null and b/v2/doc/html/images/toc-minus.png differ
diff --git a/v2/doc/html/images/toc-plus.png b/v2/doc/html/images/toc-plus.png
new file mode 100644
index 000000000..941312ce0
Binary files /dev/null and b/v2/doc/html/images/toc-plus.png differ
diff --git a/v2/doc/html/images/up.png b/v2/doc/html/images/up.png
new file mode 100644
index 000000000..07634de26
Binary files /dev/null and b/v2/doc/html/images/up.png differ
diff --git a/v2/doc/html/images/warning.png b/v2/doc/html/images/warning.png
new file mode 100644
index 000000000..1c33db8f3
Binary files /dev/null and b/v2/doc/html/images/warning.png differ
diff --git a/v2/doc/html/reference.css b/v2/doc/html/reference.css
new file mode 100644
index 000000000..33ef65625
--- /dev/null
+++ b/v2/doc/html/reference.css
@@ -0,0 +1,76 @@
+th
+{
+ font-weight: bold;
+ text-align: center;
+}
+
+.title
+{
+ font-weight: bold;
+ font-size: 2pc;
+ font-family: Times New Roman;
+ margin-bottom: 1pc;
+ text-align: center;
+}
+
+.toc
+{
+ margin-left: 5%;
+ margin-right: 5%;
+ margin-bottom: 0pc;
+ width: 50%;
+}
+
+.programlisting
+{
+ margin-left: 3pc;
+ width: 50%;
+}
+
+.computeroutput
+{
+ font-family: Lucida Console;
+ font-size: 80%;
+}
+
+.table
+{
+ text-align: center;
+ margin-bottom: 1pc;
+}
+
+@media screen
+{
+ a{ color: blue; }
+
+ th, .title
+ {
+ background-color: lightskyblue;
+ }
+
+ .section-title
+ {
+ background-color: #EEE;
+ }
+
+ .programlisting
+ {
+ background-color: #EED;
+ border: 0.1em ridge cyan;
+ padding: 1pc;
+ }
+
+ .toc
+ {
+ border: 0.2em ridge lightcoral;
+ padding: 0.5pc;
+ background-color: #DDD;
+ }
+}
+
+@media print
+{
+ a{ color: black; }
+}
+
+
diff --git a/v2/doc/src/advanced.xml b/v2/doc/src/advanced.xml
new file mode 100644
index 000000000..d47216681
--- /dev/null
+++ b/v2/doc/src/advanced.xml
@@ -0,0 +1,831 @@
+
+
+
+
+ Advanced
+
+ This section will document
+ mostly high-level view of Boost.Build, mentioning appropriate
+ modules and rules. The on-line help system must be used to obtain
+ low-level documentation (see the help option).
+
+
+ Overview
+
+ The most fundemental entity in Boost.Build is main
+ target. This is object that user want to construct from
+ sources and keep up to date with regard to those sources. Typical
+ examples of main targets are executable files and libraries.
+
+ Main targets are grouped in projects. Their main
+ purpose is organization: related targets placed in one project,
+ can then be built together, or share some definitions.
+
+ Main targets and projects are created as the result of reading
+ one or several Jamfiles. Each Jamfile is a file written in
+ Boost.Jam interpreted language, and typically contains calls to
+ functions provided by Boost.Build, which create main targets of
+ needed type, declare project attributes and access other
+ projects. The full list of functions provided by Boost.Build is
+ described below.
+ Of course, user can create his own functions, or it can directly
+ access Boost.Build internals from Jamfile, if builtin facilities are
+ not sufficient.
+
+ Each main target, or project can be built in a number of ways,
+ say with optimization or without. We'll call such entities
+ "metatargets". To make Boost.Build produce any real targets, user
+ issues build request,
+ which specifies metatargets to be built, and properties to be
+ used.
+
+ The properties are just (name,value) pairs that
+ describe various aspects of constructed objects, for example:
+
+<optimization>full <inlining>off
+
+
+ Given the built request, Boost.Build figures out the targets
+ needed for requested metatargets with requested properties, how
+ they can be created, and whether exising files can be reused. It
+ finally issues command to create needed files, automatically
+ converting properties into appropricate command line options.
+
+
+
+
+ Your first project and roadmap
+
+ Creating your first project requires three steps:
+
+
+ Create an empty file called "Jamfile"
+
+
+
+ Create an empty file called "project-root.jam"
+
+
+
+
+ Either set your BOOST_BUILD_PATH environment
+ variant to Boost.Build root, or create a "boost-build.jam" file
+ with the following content:
+
+
+boost-build /path/to/boost.build ;
+
+
+
+
+
+
+ After that, you can run the "bjam" command in the directory
+ where you've created the files. Surely, it won't do anything, but
+ it will run without error, at least. Your next steps might
+ be:
+
+
+
+
+ Adding new main targets to the "Jamfile" file. The basic
+ syntax for declaring a main target is described below, and all builtin functions for
+ declaring main targets are listed.
+
+
+
+
+
+ Creating subprojects. Create a directory, put new Jamfile
+ there, and move some main targets to that Jamfile, or declare
+ new ones. The projects
+ reference will help with this part.
+
+
+
+
+
+ Customizing Boost.Build for your needs. You might have
+ additional tools you want to run, or just want different
+ extension for some file. The extender manual is waiting for
+ you.
+
+
+
+
+
+
+
+ Main targets
+
+
+ Main target is a user-defined named
+ entity which can be build, for example a named executable file.
+ Declaring a main target is usually done using one of main target functions.
+ The user can also declare custom main target
+ function.
+
+ Most main targets rules in Boost.Build use similiar
+ syntax:
+
+
+function-name main-target-name
+ : sources
+ : requirements
+ : default-build
+ : usage-requirements
+ ;
+
+
+
+
+
+ "main-target-name" is the name used to request the target
+ on command line and to use it from other main targets. Main
+ target name may contain alphanumeric characters and symbols '-'
+ and '_';
+
+
+
+
+
+ "sources" is the list of source files and other main
+ targets that must be combined. If source file is specified
+ using relative path, it's considered to be relative to the
+ source directory of the project where the path is used. See the
+ project rule
+ for information how to change source directory.
+
+
+
+
+
+ "requirements" is the list of properties that must always
+ be present when this main target is built.
+
+
+
+
+
+ "default-build" is the list of properties that will be used
+ unless some other value of the same feature is already
+ specified.
+
+
+
+
+
+ "usage-requirements" is the list of properties that will be
+ propagated to all main targets that use this one, i.e. to all
+ dependedents.
+
+
+
+
+ Some main target rules have shorter list of parameters, and
+ you should consult their documentation for details.
+
+ Building of the same main target can differ greatly from
+ platform to platform. For example, you might have different list
+ of sources for different compilers. Therefore it is possible to
+ invoke main target rules several times for a single main target.
+ For example:
+
+
+exe a : a_gcc.cpp : <toolset>gcc ;
+exe a : a.cpp ;
+
+
+
+ Each call to the 'exe' rule defines a new main target
+ alternative for the main target a.
+ In this case, the first alternative will be used for the
+ gcc toolset, while the second alternative will
+ be used in other cases. See below for
+ details.
+
+
+ Sometime a main target is really needed only by some other
+ main target. E.g. a rule that declared test-suite uses a main
+ target that represent test, but those main targets are rarely
+ needed by themself.
+
+ It possible to declare target inline, i.e. the "sources"
+ parameter may include call to other main rules. For example:
+
+
+exe hello : hello.cpp
+ [ obj helpers : helpers.cpp : <optimization>off ] ;
+
+
+
+Will cause "helpers.cpp" to be always compiled without
+optimization. It's possible to request main targets declared
+inline, but since they are considered local, they are renamed to
+"parent-main-target_name..main-target-name". In the example above,
+to build only helpers, one should run "bjam hello..helpers".
+
+
+
+
+
+ Projects
+
+ Boost.Build considers every software it build as organized
+ into projects — modules which declare targets.
+ Projects are organized in a hierarchical structure, so each
+ project may have a single parent project and a number of
+ subprojects.
+
+ Most often, projects are created as result of loading
+ Jamfile — files which are specially meant to
+ describe projects. Boost.Build will implicitly load Jamfile in
+ the invocation directory, and all Jamfiles referred by the first
+ one, creating the hierarchy of projects.
+
+ The exact name of file that describes project is configurable.
+ By default, it's Jamfile, but can be changed by setting
+ global variables JAMFILE, for example in
+ boost-build.jam file. The value of the variable is a
+ list of regex patterns that are used when searching for Jamfile
+ in a directory.
+
+ Every Boost.Build modules can decide to act as project and be
+ able to declare targets. For example, the
+ site-config.jam module can declare libraries
+ available on a given host, as described here.
+
+ There are three things that can be put in Jamfile:
+ declarations of main targets, calls to a number of predefined
+ rules, and arbitrary user code. The predefined rules are listed
+ below:
+
+
+
+
+
+
+ Rule
+
+ Semantic
+
+
+
+
+
+ project
+
+
+ Define project attributes.
+
+
+
+ use-project
+
+ Make another project known.
+
+
+
+ build-project
+
+ Build another project when this one is built.
+
+
+
+ explicit
+
+ States that the target should be built only by explicit
+ request.
+
+
+
+ glob
+
+ Takes a list of wildcards, and returns the list of files
+ which match any of the wildcards.
+
+
+
+
+
+ Each project is also associated with project root.
+ That's a root for a tree of projects, which specifies some global
+ properties.
+
+
+ Project root
+
+
+ Project root for a projects is the nearest parent directory
+ which contains a file called
+ project-root.jam. That file defines
+ certain properties which apply to all projects under project
+ root. It can:
+
+
+
+
+ configure toolsets, via call to toolset.using
+
+
+
+
+
+ refer to other projects, via the use-project
+ rule
+
+
+
+
+
+ declare constants, via the constant and
+ path-constant rules.
+
+
+
+
+
+
+ To facilitate declaration of simple projects, Jamfile and
+ project-root can be merged together. To achieve this effect, the
+ project root file should call the project rule. The
+ semantic is precisely the same as if the call was made in
+ Jamfile, except that project-root.jam will start serve as
+ Jamfile. The Jamfile in the directory of project-root.jam will be
+ ignored, and project-root.jam will be able to declare main
+ targets as usual.
+
+
+
+
+ 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". Target references make use of project ids to
+ specify a target.
+
+ 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 also 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
+
+ none
+
+ Sets to the passed value
+
+
+
+ Build directory
+
+ build-dir
+
+ If parent has a build dir set, the value of it, joined
+ with the relative path from parent to the current project.
+ Otherwise, empty
+
+ Sets to the passed value, interpreted as relative to the
+ project's location.
+
+
+
+
+
+
+
+ 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.
+
+
+
+
+
+ Target identifiers and references
+
+ Target identifier is used to denote a
+ target. The syntax is:
+
+
+target-id -> (project-id | target-name | file-name )
+ | (project-id | directory-name) "//" target-name
+project-id -> path
+target-name -> path
+file-name -> path
+directory-name -> path
+
+
+
+This grammar allows some elements to be recognized as either
+
+
+
+
+ project id (at this point, all project ids start with slash).
+
+
+
+
+
+ name of target declared in current Jamfile (note that target
+ names may include slash).
+
+
+
+
+
+ a regular file, denoted by absolute name or name relative to
+ project's sources location.
+
+
+
+
+ To determine the real meaning a check is made if project-id
+ by the specified name exists, and then if main target of that
+ name exists. For example, valid target ids might be:
+
+
+a -- target in current project
+lib/b.cpp -- regular file
+/boost/thread -- project "/boost/thread"
+/home/ghost/build/lr_library//parser -- target in specific project
+
+
+
+
+ Rationale:Target is separated from project by special
+ separator (not just slash), because:
+
+
+
+
+ It emphasises that projects and targets are different things.
+
+
+
+
+
+ It allows to have main target names with slashes.
+
+
+
+
+
+
+
+ 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
+compiler executable is build with optimization for
+speed.
+
+
+
+ Builtin facilities
+
+
+ Main targets
+
+
+ exe
+
+
+
+ Creates a regular executable file. Sources must be either
+ object files or libraries, and sources of different types
+ will be converted to accepted types automatically.
+
+
+
+
+ lib
+
+
+ Creates a library file. Depending on the value of
+ <link> feature the library will be either static or
+ shared. Like with "exe", sources will be converted either to
+ objects or libraries.
+
+ The handling of libraries in sources depends on whether
+ linking is static or shared. For shared linking, libraries
+ will be linked in. For static linking the library sources
+ will not be linked in, since it's not possible, and will be
+ passed on. Other main target which depend on this one will
+ see those libraries and link to it. Therefore, putting
+ library in sources of other library works in all cases.
+
+
+ alias
+
+
+
+ Builds all the source targets and returns them unmodified.
+ Please run "bjam --help alias" for more details.
+
+
+
+ stage
+
+
+
+ Copies a number of targets to a single directory. The
+ primary purpose is installing binaries. Please run "bjam --help
+ stage" for more details.
+
+
+
+ unit-test (from module "testing")
+
+
+
+ Creates an executable file and runs it. Build won't succeed
+ unless the executable runs successfully. The rule is usefull
+ for creating test program which should be rerun whenever any
+ dependency changes.
+
+
+
+
+
+
+
+ Features
+
+
+ variant
+
+
+
+ The feature which combines several low-level features in
+ order to make building most common variants simple.
+
+
+ Allowed values:debug, release,
+ profile
+
+ The value debug expands to
+
+
+<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on
+
+
+ The value release expands to
+
+
+<optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off
+
+
+ The value profile expands to the same as
+ release, plus:
+
+
+<profiling>on <debug-symbols>on
+
+
+ Rationale: Runtime debugging is on in debug build
+ so suit expectations of people used various IDEs. It's
+ assumed other folks don't have any specific expectation in
+ this point.
+
+
+ link
+
+
+
+ Feature which controls how libraries are built.
+
+
+ Allowed values:shared,
+ static
+
+
+ library
+
+
+
+ For exe and lib main targets, the <library>X feature
+ is equvivalent to putting X in the list of sources. The feature
+ is sometimes more convenient: you can put <library>X in
+ the requirements for a project and it will be linked to all
+ executables.
+
+
+
+
+ use
+
+
+
+ Causes the target referenced by the value of this feature
+ to be constructed and adds it's usage requirements to build
+ properties. The constructed targets are not used in any other
+ way. The primary use case is when you use some library and want
+ it's usage requirements (such as include paths) to be applied,
+ but don't want to link to the library.
+
+
+
+
+ dll-path
+
+
+
+ Specify a path where dynamic libraries should be found at
+ where executable or shared library is run. This feature
+ directly affects binaries with the gcc compiler, allowing them
+ to pick specific libraries, and ignoring all environment
+ settings. On other toolsets, the binary still requires proper
+ environment settings to be run. However, Boost.Build tools
+ which run executables will notice dll-path settings and create
+ this environment automatically.
+
+
+
+ hardcode-dll-paths
+
+
+
+ Controls automatic generation of dll-path properties.
+
+
+ Allowed values:off, on When this
+ property is on, usage requirements for each library will
+ include additional dll-path propertry, with the path the the
+ generated library file. This allows to run executables
+ without placing all the dependent libraries to a single
+ location.
+
+
+
+
+
+
+
diff --git a/v2/doc/src/architecture.xml b/v2/doc/src/architecture.xml
new file mode 100644
index 000000000..79bde6fed
--- /dev/null
+++ b/v2/doc/src/architecture.xml
@@ -0,0 +1,434 @@
+
+
+
+
+ Boost.Build v2 architecture
+
+
+ This document is work-in progress. Don't expect much from it
+ yet.
+
+
+
+ Targets
+
+ There are two user-visible kinds of targets in Boost.Build.
+ First are "abstract" — they correspond to things declared
+ by user, for example, projects and executable files. The primary
+ thing about abstract target is that it's possible to request them
+ to be build with a particular values of some properties. Each
+ combination of properties may possible yield different set of
+ real file, so abstract target do not have a direct correspondence
+ with files.
+
+ File targets, on the contary, are associated with concrete
+ files. Dependency graphs for abstract targets with specific
+ properties are constructed from file targets. User has no was to
+ create file targets, however it can specify rules that detect
+ file type for sources, and also rules for transforming between
+ file targets of different types. That information is used in
+ constructing dependency graph, as desribed in the "next section".
+ [ link? ] Note:File targets are not
+ the same as targets in Jam sense; the latter are created from
+ file targets at the latest possible moment. Note:"File
+ target" is a proposed name for what we call virtual targets. It
+ it more understandable by users, but has one problem: virtual
+ targets can potentially be "phony", and not correspond to any
+ file.
+
+
+ Dependency scanning
+
+ Dependency scanning is the process of finding implicit
+ dependencies, like "#include" statements in C++. The requirements
+ for right dependency scanning mechanism are:
+
+
+
+
+ Support for different scanning algorithms. C++ and XML have
+ quite different syntax for includes and rules for looking up
+ included files.
+
+
+
+
+
+ Ability to scan the same file several times. For example,
+ single C++ file can be compiled with different include
+ paths.
+
+
+
+
+
+ Proper detection of dependencies on generated files.
+
+
+
+
+
+ Proper detection of dependencies from generated file.
+
+
+
+
+
+ Support for different scanning algorithms
+
+ Different scanning algorithm are encapsulated by objects
+ called "scanners". Please see the documentation for "scanner"
+ module for more details.
+
+
+
+
+ Ability to scan the same file several times
+
+ As said above, it's possible to compile a C++ file twice, with
+ different include paths. Therefore, include dependencies for
+ those compilations can be different. The problem is that bjam
+ does not allow several scans of the same target.
+
+ The solution in Boost.Build is straigtforward. When a virtual
+ target is converted to bjam target (via
+ virtual-target.actualize method), we specify the scanner
+ object to be used. The actualize method will create different
+ bjam targets for different scanners.
+
+ All targets with specific scanner are made dependent on target
+ without scanner, which target is always created. This is done in
+ case the target is updated. The updating action will be
+ associated with target without scanner, but if sources for that
+ action are touched, all targets — with scanner and without
+ should be considered outdated.
+
+ For example, assume that "a.cpp" is compiled by two compilers
+ with different include path. It's also copied into some install
+ location. In turn, it's produced from "a.verbatim". The
+ dependency graph will look like:
+
+
+a.o (<toolset>gcc) <--(compile)-- a.cpp (scanner1) ----+
+a.o (<toolset>msvc) <--(compile)-- a.cpp (scanner2) ----|
+a.cpp (installed copy) <--(copy) ----------------------- a.cpp (no scanner)
+ ^
+ |
+ a.verbose --------------------------------+
+
+
+
+
+ Proper detection of dependencies on generated files.
+
+ This requirement breaks down to the following ones.
+
+
+
+
+ If when compiling "a.cpp" there's include of "a.h", the
+ "dir" directory is in include path, and a target called "a.h"
+ will be generated to "dir", then bjam should discover the
+ include, and create "a.h" before compiling "a.cpp".
+
+
+
+
+
+ Since almost always Boost.Build generates targets to a
+ "bin" directory, it should be supported as well. I.e. in the
+ scanario above, Jamfile in "dir" might create a main target,
+ which generates "a.h". The file will be generated to "dir/bin"
+ directory, but we still have to recornize the dependency.
+
+
+
+
+ The first requirement means that when determining what "a.h"
+ means, when found in "a.cpp", we have to iterate over all
+ directories in include paths, checking for each one:
+
+
+
+
+ If there's file "a.h" in that directory, or
+
+
+
+
+
+ If there's a target called "a.h", which will be generated
+ to that directory.
+
+
+
+
+ Classic Jam has built-in facilities for point (1) above, but
+ that's not enough. It's hard to implement the right semantic
+ without builtin support. For example, we could try to check if
+ there's targer called "a.h" somewhere in dependency graph, and
+ add a dependency to it. The problem is that without search in
+ include path, the semantic may be incorrect. For example, one can
+ have an action which generated some "dummy" header, for system
+ which don't have the native one. Naturally, we don't want to
+ depend on that generated header on platforms where native one is
+ included.
+
+ There are two design choices for builtin support. Suppose we
+ have files a.cpp and b.cpp, and each one includes header.h,
+ generated by some action. Dependency graph created by classic jam
+ would look like:
+
+
+a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
+
+
+ <d2>header.h --------> header.y
+ [generated in d2]
+
+b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4]
+
+
+
+In this case, Jam thinks all header.h target are not
+realated. The right dependency graph might be:
+
+
+a.cpp ----
+ \
+ \
+ >----> <d2>header.h --------> header.y
+ / [generated in d2]
+ /
+b.cpp ----
+
+
+or
+
+
+a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
+ |
+ (includes)
+ V
+ <d2>header.h --------> header.y
+ [generated in d2]
+ ^
+ (includes)
+ |
+b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4]
+
+
+
+
+The first alternative was used for some time. The problem
+however is: what include paths should be used when scanning
+header.h? The second alternative was suggested by Matt Armstrong.
+It has similiar effect: add targets which depend on
+<scanner1>header.h will also depend on <d2>header.h.
+But now we have two different target with two different scanners,
+and those targets can be scanned independently. The problem of
+first alternative is avoided, so the second alternative is
+implemented now.
+
+
+ The second sub-requirements is that targets generated to "bin"
+ directory are handled as well. Boost.Build implements
+ semi-automatic approach. When compiling C++ files the process
+ is:
+
+
+
+
+ The main target to which compiled file belongs is found.
+
+
+
+
+
+ All other main targets that the found one depends on are
+ found. Those include main target which are used as sources, or
+ present as values of "dependency" features.
+
+
+
+
+
+ All directories where files belonging to those main target
+ will be generated are added to the include path.
+
+
+
+
+ After this is done, dependencies are found by the approach
+ explained previously.
+
+ Note that if a target uses generated headers from other main
+ target, that main target should be explicitly specified as
+ dependency property. It would be better to lift this requirement,
+ but it seems not very problematic in practice.
+
+ For target types other than C++, adding of include paths must
+ be implemented anew.
+
+
+
+ Proper detection of dependencies from generated files
+
+ Suppose file "a.cpp" includes "a.h" and both are generated by
+ some action. Note that classic jam has two stages. In first stage
+ dependency graph graph is build and actions which should be run
+ are determined. In second stage the actions are executed.
+ Initially, neither file exists, so the include is not found. As
+ the result, jam might attempt to compile a.cpp before creating
+ a.h, and compilation will fail.
+
+ The solution in Boost.Jam is to perform additional dependency
+ scans after targets are updated. This break separation between
+ build stages in jam — which some people consider a good
+ thing — but I'm not aware of any better solution.
+
+ In order to understand the rest of this section, you better
+ read some details about jam dependency scanning, available
+
+ at this link.
+
+ Whenever a target is updated, Boost.Jam rescans it for
+ includes. Consider this graph, created before any actions are
+ run.
+
+
+A -------> C ----> C.pro
+ /
+B --/ C-includes ---> D
+
+
+
+Both A and B have dependency on C and C-includes (the latter
+dependency is not shown). Say during building we've tried to create
+A, then tried to create C and successfully created C.
+
+
+ In that case, the set of includes in C might well have
+ changed. We do not bother to detect precisely which includes were
+ added or removed. Instead we create another internal node
+ C-includes-2. Then we determine what actions should be run to
+ update the target. In fact this mean that we perform logic of
+ first stage while already executing stage.
+
+ After actions for C-includes-2 are determined, we add
+ C-includes-2 to the list of A's dependents, and stage 2 proceeds
+ as usual. Unfortunately, we can't do the same with target B,
+ since when it's not visited, C target does not know B depends on
+ it. So, we add a flag to C which tells and it was rescanned. When
+ visiting B target, the flag is notices and C-includes-2 will be
+ added to the list of B's dependencies.
+
+ Note also that internal nodes are sometimes updated too.
+ Consider this dependency graph:
+
+
+a.o ---> a.cpp
+ a.cpp-includes --> a.h (scanned)
+ a.h-includes ------> a.h (generated)
+ |
+ |
+ a.pro <-------------------------------------------+
+
+
+ Here, out handling of generated headers come into play. Say
+ that a.h exists but is out of date with respect to "a.pro", then
+ "a.h (generated)" and "a.h-includes" will be marking for
+ updating, but "a.h (scanned)" won't be marked. We have to rescan
+ "a.h" file after it's created, but since "a.h (generated)" has no
+ scanner associated with it, it's only possible to rescan "a.h"
+ after "a.h-includes" target was updated.
+
+ Tbe above consideration lead to decision that we'll rescan a
+ target whenever it's updated, no matter if this target is
+ internal or not.
+
+
+
+ The remainder of this document is not indended to be read at
+ all. This will be rearranged in future.
+
+
+
+
+ File targets
+
+
+ As described above, file targets corresponds
+ to files that Boost.Build manages. User's may be concerned about
+ file targets in three ways: when declaring file target types,
+ when declaring transformations between types, and when
+ determining where file target will be placed. File targets can
+ also be connected with actions, that determine how the target is
+ created. Both file targets and actions are implemented in the
+ virtual-target module.
+
+
+
+ Types
+
+ A file target can be given a file, which determines
+ what transformations can be applied to the file. The
+ type.register rule declares new types. File type can
+ also be assigned a scanner, which is used to find implicit
+ dependencies. See "dependency scanning" [ link? ] below.
+
+
+
+
+ Target paths
+
+ To distinguish targets build with different properties, they
+ are put in different directories. Rules for determining target
+ paths are given below:
+
+
+
+
+ All targets are placed under directory corresponding to the
+ project where they are defined.
+
+
+
+
+
+ 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].
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
diff --git a/v2/doc/src/catalog.xml b/v2/doc/src/catalog.xml
new file mode 100644
index 000000000..26e16145d
--- /dev/null
+++ b/v2/doc/src/catalog.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/v2/doc/src/extending.xml b/v2/doc/src/extending.xml
new file mode 100644
index 000000000..eff223486
--- /dev/null
+++ b/v2/doc/src/extending.xml
@@ -0,0 +1,128 @@
+
+
+
+
+ Extender Manual
+
+
+ Introduction
+
+ This document explains how to extend Boost.Build to accomodate
+ your local requirements. Let's start with quite simple, but
+ realistic example.
+
+ Say you're writing an application which generates C++ code. If
+ you ever did this, you know that it's not nice. Embedding large
+ portions of C++ code in string literals is very awkward. A much
+ better solution is:
+
+
+
+
+ Write the template of the code to be generated, leaving
+ placeholders at the points which will change
+
+
+
+
+
+ Access the template in your application and replace
+ placeholders with appropriate text.
+
+
+
+
+ Write the result.
+
+
+
+ It's quite easy to archive. You write special verbatim files,
+ which are just C++, except that the very first line of the file
+ gives a name of variable that should be generated. A simple tool
+ is created which takes verbatim file and creates a cpp file with
+ a single char* variable, which name is taken from the first line
+ of verbatim file, and which value is properly quoted content of
+ the verbatim file.
+
+ Let's see what Boost.Build can do.
+
+ First off, Boost.Build has no idea about "verbatim files". So,
+ you must register a new type. The following code does it:
+
+
+import type ;
+type.register VERBATIM : verbatim ;
+
+
+ The first parameter to 'type.register' gives the name of
+ declared type. By convention, it's uppercase. The second
+ parameter is suffix for this type. So, if Boost.Build sees
+ "code.verbatim" in the list of sources, it knows that it's of
+ type VERBATIM.
+
+ Lastly, you need a tool to convert verbatim files to C++. Say
+ you've sketched such a tool in Python. Then, you have to inform
+ Boost.Build about the tool. The Boost.Build concept which
+ represents a tool is generator.
+
+ First, you say that generator 'inline-file' is able to convert
+ VERBATIM type into C++:
+
+
+import generators ;
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+
+
+ Second, you must specify the commands to be run to actually
+ perform convertion:
+
+
+actions inline-file
+{
+ "./inline-file.py" $(<) $(>)
+}
+
+
+
+ Now, we're ready to tie it all together. Put all the code
+ above in file "verbatim.jam", add "import verbatim ;" to
+ "project-root.jam", and it's possible to write the following in
+ Jamfile:
+
+
+exe codegen : codegen.cpp class_template.verbatim usage.verbatim ;
+
+
+
+The verbatim files will be automatically converted into C++
+and linked it.
+
+
+ The complete code is available in example/customization
+ directory.
+
+
+
+ Target types
+
+
+
+
+ Tools
+
+
+
+
+ Main target rules
+
+
+
+
+ Scanners
+
+
+
diff --git a/v2/doc/src/faq.xml b/v2/doc/src/faq.xml
new file mode 100644
index 000000000..5d7c5a1ca
--- /dev/null
+++ b/v2/doc/src/faq.xml
@@ -0,0 +1,82 @@
+
+
+
+
+ Frequently Asked Questions
+
+
+
+ I'm getting "Duplicate name of actual target" error. What
+ does it mean?
+
+
+
+ The most likely case is that you're trying to
+ compile the same file twice, with almost the same,
+ but differing properties. For example:
+
+
+exe a : a.cpp : <include>/usr/local/include ;
+exe b : a.cpp ;
+
+
+
+
+
+ The above snippet requires two different compilations
+ of 'a.cpp', which differ only in 'include' property.
+ Since the 'include' property is free, Boost.Build
+ can't generate two ojects files into different directories.
+ On the other hand, it's dangerous to compile the file only
+ once -- maybe you really want to compile with different
+ includes.
+
+
+
+ To solve this issue, you need to decide if file should
+ be compiled once or twice.
+
+
+
+ Two compile file only once, make sure that properties
+ are the same:
+
+
+exe a : a.cpp : <include>/usr/local/include ;
+exe b : a.cpp : <include>/usr/local/include ;
+
+
+
+ If changing the properties is not desirable, for example
+ if 'a' and 'b' target have other sources which need
+ specific properties, separate 'a.cpp' into it's own target:
+
+
+obj a_obj : a.cpp : <include>/usr/local/include ;
+exe a : a_obj ;
+
+
+
+ To compile file twice, you can make the object file local
+ to the main target:
+
+
+ exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ;
+ exe b : [ obj a_obj : a.cpp ] ;
+
+
+
+
+
+ A good question is why Boost.Build can't use some of the above
+ approaches automatically. The problem is that such magic would
+ require additional implementation complexities and would only
+ help in half of the cases, while in other half we'd be silently
+ doing the wrong thing. It's simpler and safe to ask user to
+ clarify his intention in such cases.
+
+
+
+
+
diff --git a/v2/doc/src/howto.xml b/v2/doc/src/howto.xml
new file mode 100644
index 000000000..dcb44670f
--- /dev/null
+++ b/v2/doc/src/howto.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ How to use this document
+
+
+ If you've just found out about Boost.Build V2 and want to know
+ if it will work for you, start with . You can continue with the . When you're ready to try Boost.Build
+ in practice, go to .
+
+
+
+ If you are about to use Boost.Build on your project, or already
+ using it and have a problem, look at .
+
+
+
+ If you're trying to build a project which uses Boost.Build,
+ look at and then read about
+ .
+
+
+
+ Finally, if nothing applies to you, write to our mailing list,
+ telling what information you'd like to know.
+
+
+
diff --git a/v2/doc/src/install.xml b/v2/doc/src/install.xml
new file mode 100644
index 000000000..d164a5907
--- /dev/null
+++ b/v2/doc/src/install.xml
@@ -0,0 +1,111 @@
+
+
+
+
+ Installation
+
+
+ Assuming you're installing Boost.Build from released source
+ distribution, the following steps are needed. All paths are
+ given relatively to Boost.Build root directory, which is the
+ directory with the document you are reading.
+
+
+
+
+
+ Go to "jam_src" directory and build Boost.Jam. Two convenient
+ scripts are provided, "build.sh" (for Unix systems) and
+ "build.bat" (for Windows). Run the appropriate one and
+ Boost.Jam will be built to directory
+ bin.{platform_name}.. The Boost.Jam documentation has
+ more details in case you need them.
+
+
+
+
+
+ Place the Boost.Jam binary, called "bjam" or "bjam.exe",
+ somewhere in your PATH. Go to the root
+ directory of Boost.Build and run "bjam --version". You should
+ get
+
+ Boost.Build V2 (Milestone N)
+
+ (where N is the version you've downloaded).
+
+
+
+
+
+ Configure toolsets to use. Open the
+ user-config.jam file and follow
+ instructions there to specify what compiles/libraries you
+ have and where they are located.
+
+
+
+
+
+ You should now be able to go to
+ example/hello, and run
+ bjam there. A simple application will be
+ built. You can also play with other projects in
+ example.
+
+
+
+
+
+
+ If you use Boost distribution, or Boost CVS, the Boost.Build
+ root is located at $boost_root/tools/build/v2
+ and the installation steps are the same. However, don't skip
+ the bjam rebuilding step, even if you have a previous version.
+ CVS version of Boost.Build requires CVS version of Boost.Jam.
+
+
+
+ When starting a new project which uses Boost.Build, you need
+ to make sure that build system can be found. There are two
+ ways.
+
+
+
+
+
+ Set enviromnetal variable BOOST_BUILD_PATH
+ to the absolute path to Boost.Build installation directory.
+
+
+
+
+
+ Create, at the top of your project, a file called
+ boost-build.jam, with a single line:
+
+
+boost-build /path/to/boost.build ;
+
+
+
+
+
+
+ If you're trying to use Boost.Build V2 on Boost itself, please
+ note that when building Boost, V1 is used by default. You'd have
+ to add command line option to all "bjam"
+ invocations.
+
+
diff --git a/v2/doc/src/recipes.xml b/v2/doc/src/recipes.xml
new file mode 100644
index 000000000..33aa1df6a
--- /dev/null
+++ b/v2/doc/src/recipes.xml
@@ -0,0 +1,35 @@
+
+
+
+
+ Boost Build System V2 recipes
+
+
+ Targets in site-config.jam
+
+ It is desirable to declare standard libraries available on a
+ given system. Putting target declaration in Jamfile is not really
+ good, since locations of the libraries can vary. The solution is
+ to put the following to site-config.jam.
+
+
+import project ;
+project.initialize $(__name__) ;
+project site-config ;
+lib zlib : : <name>z ;
+
+
+ The second line allows this module to act as project. The
+ third line gives id to this project — it really has no location
+ and cannot be used otherwise. The fourth line just declares a
+ target. Now, one can write
+
+
+exe hello : hello.cpp /site-config//zlib ;
+
+
+ in any Jamfile.
+
+
+
diff --git a/v2/doc/src/reference.xml b/v2/doc/src/reference.xml
new file mode 100644
index 000000000..400cdbac5
--- /dev/null
+++ b/v2/doc/src/reference.xml
@@ -0,0 +1,1037 @@
+
+
+
+
+ Detailed reference
+
+
+ Features and properties
+
+
+ Definitions
+
+ A feature is a normalized (toolset-independent)
+ aspect of a build configuration, such as whether inlining is
+ enabled. Feature names may not contain the '>'
+ character.
+
+
+
+ Each feature in a build configuration has one or more
+ associated values. Feature values for non-free features
+ may not contain the '<', ':', or
+ '=' characters. Feature values for free features may not
+ contain the '<' character.
+
+ 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 feature, and whose identity can be derived
+ (in the context of its parent) from its value. A subfeature's
+ parent can never be another subfeature. Thus, features and their
+ subfeatures form a two-level hierarchy.
+
+ A value-string for a feature F is a string of
+ the form
+ value-subvalue1-subvalue2...-subvalueN, where
+ value is a legal value for F and
+ subvalue1...subvalueN are legal values of some
+ of F's subfeatures. For example, the properties
+ <toolset>gcc <toolset-version>3.0.1 can be
+ expressed more conscisely using a value-string, as
+ <toolset>gcc-3.0.1.
+
+ A property set is a set of properties (i.e. a
+ collection without dublicates), for instance:
+ <toolset>gcc <runtime-link>static.
+
+ A property path is a property set whose elements have
+ been joined into a single string separated by slashes. A property
+ path representation of the previous example would be
+ <toolset>gcc/<runtime-link>static.
+
+ A build specification is a property set which fully
+ describes the set of features used to build a target.
+
+
+
+ Property Validity
+
+
+ For free
+ features, all values are valid. For all other features,
+ the valid values are explicitly specified, and the build
+ system will report an error for the use of an invalid
+ feature-value. Subproperty validity may be restricted so
+ that certain values are valid only in the presence of
+ certain other subproperties. For example, it is possible
+ to specify that the <gcc-target>mingw
+ property is only valid in the presence of
+ <gcc-version>2.95.2.
+
+
+
+
+ Feature Attributes
+
+ Each feature has a collection of zero or more of the following
+ attributes. Feature attributes are low-level descriptions of how
+ the build system should interpret a feature's values when they
+ appear in a build request. We also refer to the attributes of
+ properties, so that a incidental property, for example, is
+ one whose feature is has the incidental attribute.
+
+
+
+ incidental
+
+ Incidental features are assumed not to affect build
+ products at all. As a consequence, the build system may use
+ the same file for targets whose build specification differs
+ only in incidental features. A feature which controls a
+ compiler's warning level is one example of a likely
+ incidental feature.
+
+ Non-incidental features are assumed to affect build
+ products, so the files for targets whose build specification
+ differs in non-incidental features are placed in different
+ directories as described in "target paths" below. [ where? ]
+
+
+
+
+
+
+ propagated
+
+
+ Features of this kind are
+ propagated to dependencies. That is, if a main target is built using a
+ propagated
+ property, the build systems attempts to use the same property
+ when building any of its dependencies as part of that main
+ target. For instance, when an optimized exectuable is
+ requested, one usually wants it to be linked with optimized
+ libraries. Thus, the <optimization> feature is
+ propagated.
+
+
+
+
+
+ free
+
+
+ Most features have a finite set of allowed values, and can
+ only take on a single value from that set in a given build
+ specification. Free features, on the other hand, can have
+ several values at a time and each value can be an arbitrary
+ string. For example, it is possible to have several
+ preprocessor symbols defined simultaneously:
+
+
+<define>NDEBUG=1 <define>HAS_CONFIG_H=1
+
+
+
+
+
+ optional
+
+ An optional feature is a feature which is not required to
+ appear in a build specification. Every non-optional non-free
+ feature has a default value which is used when a value for
+ the feature is not otherwise specified, either in a target's
+ requirements or in the user's build request. [A feature's
+ default value is given by the first value listed in the
+ feature's declaration. -- move this elsewhere - dwa]
+
+
+
+ symmetric
+
+ A symmetric feature's default value is not automatically
+ included in build variants. Normally
+ a feature only generates a subvariant directory when its
+ value differs from the value specified by the build variant,
+ leading to an assymmetric subvariant directory structure for
+ certain values of the feature. A symmetric feature, when
+ relevant to the toolset, always generates a corresponding
+ subvariant directory.
+
+
+
+ path
+
+ The value of a path feature specifies a path. The path is
+ treated as relative to the directory of Jamfile where path
+ feature is used and is translated appropriately by the build
+ system when the build is invoked from a different
+ directory
+
+
+
+ implicit
+
+ Values of implicit features alone identify the feature.
+ For example, a user is not required to write
+ "<toolset>gcc", but can simply write "gcc". Implicit
+ feature names also don't appear in variant paths, although
+ the values do. Thus: bin/gcc/... as opposed to
+ bin/toolset-gcc/.... There should typically be only a few
+ such features, to avoid possible name clashes.
+
+
+
+ composite
+
+ Composite features actually correspond to groups of
+ properties. For example, a build variant is a composite
+ feature. When generating targets from a set of build
+ properties, composite features are recursively expanded and
+ added to the build property set, so rules can find
+ them if neccessary. Non-composite non-free features override
+ components of composite features in a build property set.
+
+
+
+ link-incompatible
+
+ See below.
+
+
+
+ dependency
+
+ The value of dependency feature if a target reference.
+ When used for building of a main target, the value of
+ dependency feature is treated as additional dependency.
+
+ For example, dependency features allow to state that
+ library A depends on library B. As the result, whenever an
+ application will link to A, it will also link to B.
+ Specifying B as dependency of A is different from adding B to
+ the sources of A.
+
+
+
+ Features which are neither free nor incidental are called
+ base features.
+
+ TODO: document active features..
+
+
+
+ Feature Declaration
+
+ The low-level feature declaration interface is the
+ feature rule from the
+ feature module:
+
+
+rule feature ( name : allowed-values * : attributes * )
+
+
+ A feature's allowed-values may be extended wit The build
+system will provide high-level rules which define features in terms
+of valid and useful combinations of attributes.
+
+
+
+
+
+
+ Build Variants
+
+
+A build variant, or (simply variant) is a special kind of composite
+ feature which automatically incorporates the default values of
+ features that . Typically you'll want at least two separate
+ variants: one for debugging, and one for your release code. [
+ Volodya says: "Yea, we'd need to mention that it's a composite
+ feature and describe how they are declared, in pacticular that
+ default values of non-optional features are incorporated into
+ build variant automagically. Also, do we wan't some variant
+ inheritance/extension/templates. I don't remember how it works in
+ V1, so can't document this for V2.". Will clean up soon -DWA ]
+
+
+
+ Link compatible and incompatible properties
+
+ 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.
+
+ The build request can originate in many ways: it may come
+ directly from the user's command-line, from a dependency of a
+ main target upon a library, or from a dependency of a target upon
+ an executable used to build that target, for example. For each
+ way, there are different rules whether we can use a given
+ subvariant or not. The current rules are described below.
+
+ 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.
+
+ When building of a main target is requested from a command
+ line or some project, link-compatibility is not considered. When
+ building is requested by other main target, via sources or
+ dependency properties, the requested and actual property sets
+ must be link-compatible, otherwise a warning is produced.
+
+ Rationale:Link-compatibility is not considered when
+ main target is requested by a project, because it causes problems
+ in practice. For example, some parts of a project might be
+ single-threaded, while others — multi-threaded. They are
+ not link-compatible, but they are not linked, either. So, there's
+ no need to issue error or warning. The errors used to be
+ generated, and only caused problems.
+
+
+
+ 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
+
+
+
+
+ If original properties and required properties are not
+ link-compatible, refinement fails.
+
+
+
+
+
+ Each property in the required set is added to the original
+ property set
+
+
+
+
+
+ If the original property set includes property with a different
+ value of non free feature, that property is removed.
+
+
+
+
+
+
+ Conditional properties
+
+ Sometime it's desirable to apply certain requirements only for
+ specific combination of other properties. For example, one of
+ compilers that you use issues a poinless warning that you want to
+ suppress by passing a command line option to it. You would not
+ want to pass that option to other compilers. Condititional
+ properties allow to do that. Their systax is:
+
+
+property ( "," property ) * ":" property
+
+
+
+For example, the problem above would be solved by:
+
+
+exe hello : hello.cpp : <toolset>yfc:<cxxflags>-disable-pointless-warning ;
+
+
+
+
+
+
+
+ Initialization
+
+ bjam's first job upon startup is to load the Jam code which
+ implements the build system. To do this, it searches for a file
+ called "boost-build.jam", first in the invocation directory, then
+ in its parent and so forth up to the filesystem root, and finally
+ in the directories specified by the environment variable
+ BOOST_BUILD_PATH. When found, the file is interpreted, and should
+ specify the build system location by calling the boost-build
+ rule:
+
+
+rule boost-build ( location ? )
+
+
+
+If location is a relative path, it is treated as relative to
+the directory of boost-build.jam. The directory specified by
+location and directories in BOOST_BUILD_PATH are then searched for
+a file called bootstrap.jam which is interpreted and is expected to
+bootstrap the build system. This arrangement allows the build
+system to work without any command-line or environment variable
+settings. For example, if the build system files were located in a
+directory "build-system/" at your project root, you might place a
+boost-build.jam at the project root containing:
+
+
+boost-build build-system ;
+
+
+In this case, running bjam anywhere in the project tree will
+automatically find the build system.
+
+ The default "bootstrap.jam", after loading some standard
+ definitions, loads two files, which can be provided/customised by
+ user: "site-config.jam" and "user-config.jam".
+
+ Locations where those files a search are summarized below:
+
+
+
+
+Boost.Build comes with default versions of those files,
+ which can serve as templates for customized versions.
+
+
+
+
+ Command line
+
+ The command line may contain:
+
+
+ Jam options,
+
+ Boost.Build options,
+
+ Command line arguments
+
+
+
+ Command line arguments
+
+
+ Command line arguments specify targets and build
+ request using the following rules.
+
+
+
+
+
+ An argument which does not contain slashes or the "="
+ symbol is either a value of an implicit feature, or target to
+ be built. It is taken to be value of a feature if appropriate
+ feature exists. Otherwise, it is considered a target id. Special target name "clean"
+ has the same effect as "--clean" option.
+
+
+
+
+
+ An argument with either slashes or the "=" symbol specifies
+ a number of build
+ request
+ elements. In the simplest form, it's just a set of properties,
+ separated by slashes, which become a single build request
+ element, for example:
+
+
+borland/<runtime-link>static
+
+
+More complex form is used to save typing. For example,
+instead of
+
+
+borland/runtime-link=static borland/runtime-link=dynamic
+
+
+one can use
+
+
+borland/runtime-link=static,dynamic
+
+
+Exactly, the conversion from argument to build request
+elements is performed by (1) splitting the argument at each slash,
+(2) converting each split part into a set of properties and (3)
+taking all possible combination of the property sets. Each split
+part should have the either the form
+
+
+feature-name=feature-value1[","feature-valueN]*
+
+
+or, in case of implict feature
+
+
+feature-value1[","feature-valueN;]*
+
+
+and will be converted into property set
+
+
+<feature-name>feature-value1 .... <feature-name>feature-valueN
+
+
+
+
+
+
+
+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.
+
+
+
+
+ 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
+
+
+
+
+
+ --version
+
+ Prints information on Boost.Build and Boost.Jam
+ versions.
+
+
+
+ --help
+
+ Access to the online help system. This prints general
+ information on how to use the help system with additional
+ --help* options.
+
+
+
+ --clean
+
+ Removes everything instead of building. Unlike
+ clean target in make, it is possible to clean only
+ some targets.
+
+
+
+ --debug
+
+ Enables internal checks.
+
+
+
+ --dump-projects
+
+ Cause the project structure to be output.
+
+
+
+ --no-error-backtrace
+
+ Don't print backtrace on errors. Primary usefull for
+ testing.
+
+
+
+ --ignore-config
+
+ Do not load site-config.jam and
+ user-config.jam
+
+
+
+
+
+
+
+
+
+ Build request
+
+
+
+
+
+ Build process
+
+ Construction of each main target begins with finding
+ properties for this main target. They are found by
+ processing both build request, and target requirements,
+ which give properties needed for the target to build. For
+ example, a given main target might require certian defines, or
+ will not work unless compiled in multithreaded mode. The process
+ of finding properties for main target is described in property refinement.
+
+ After that, dependencies (i.e. other main targets) are build
+ recursively. Build request for dependencies is not always equal
+ to those of dependent — certain properties are dropped and
+ user can explicitly specify desired properties for dependencies.
+ See
+ propagated features and for details.
+
+ When dependencies are constructed, the dependency graph for
+ this main target and for this property set is created, which
+ describes which files need to be created, on which other files
+ they depend and what actions are needed to construct those files.
+ There's more that one method, and user can define new ones, but
+ usually, this involves generators and target
+ types.
+
+ Target type is just a way to classify targets. For example,
+ there are builtin types EXE, OBJ and
+ CPP. Generators are objects
+ that know how to convert between different target type. When a
+ target of a given type must be created, all generators for that
+ type, which can handle needed properties, are found. Each is
+ passed the list of sources, and either fails, or returns a
+ dependency graph. If a generator cannot produce desired type from
+ given sources, it may try to recursively construct types that it
+ can handle from the types is was passed. This allows to try all
+ possible transformations. When all generators are tried, a
+ dependency graph is selected.
+
+ Finally, the dependency graph is passed to underlying
+ Boost.Jam program, which runs all actions needed to bring all
+ main targets up-to date. At this step, implicit dependencies are
+ also scanned and accounted for, as described "here." [ link? ]
+
+ Given a list of targets ids and a build request, building goes
+ this way. First, for each id we obtain the abstract targets
+ corresponding to it. This also loads all necessary projects. If
+ no target id is given, project in the current directory is used.
+ Build request is expanded, and for each resulting property set,
+ the generate method of all targets is called, which
+ yields a list of virtual targets. After that all virtual targets
+ are actualized, and target "all" is set to depend on all created
+ actual targets. Lastly, depending on whether --clean
+ option was given, either target "all" or target "clean" is
+ updated. Generation of virtual target from abstract one is
+ performed as follows:
+
+
+
+ For project targets, all of main targets are generated
+ with the same properties. Then all projects referred via
+ "build-project" are generated as well. If it's not possible
+ to refine requested properties with project requirements, the
+ project is skipped.
+
+
+ It is possible to disable building of certain target using the
+ explicit rule, available in all project
+ modules. The syntax is
+
+
+rule explicit ( target-name )
+
+
+ If this rule is invoked on a target, it will be built only
+when it's explicitly requested on the command line.
+
+
+
+
+
+ For main target, with several alternatives, one of them is
+ selected as described below.
+ If there's only one
+ alternative, it's used unconditionally.
+
+
+
+
+ All main target alternatives which requirements are
+ satisfied by the build request are enumerated.
+
+
+
+
+
+ If there are several such alternatives, the one which
+ longer requirements list is selected.
+
+
+
+
+
+
+
+
+ For the selected alternative
+
+
+
+
+ Each target reference in the source list are
+ recursively constructed.
+
+
+
+
+
+ Properties are refined with alternative's requirements,
+ and active features in the resulting set are executed.
+
+
+
+
+
+ Conditional properties are evaluated.
+
+
+
+
+
+ The dependency graph for the target is constructed in a
+ way which depends on the kind of main target, typically
+ using generators.
+
+
+
+
+
+
+
+
+ If, when building sources, the properties on recursively
+ created targets are not link-compatibile with build properties,
+ a warning is issued.
+
+
+
+
+
+
+
+ Alternative selection
+
+ When there are several alternatives, one of them must be
+ selected. The process is as follows:
+
+
+
+
+ For each alternative condition is defined
+ as the set of base properies in requirements. [Note: it might be
+ better to explicitly specify the condition explicitly, as in
+ conditional requirements].
+
+
+
+
+
+ An alternative is viable only if all properties in condition
+ are present in build request.
+
+
+
+
+
+ If there's one viable alternative, it's choosen. Otherwise,
+ an attempt is made to find one best alternative. An alternative
+ a is better than another alternative b, iff set of properties
+ in b's condition is stict subset of the set of properities of
+ 'a's condition. If there's one viable alternative, which is
+ better than all other, it's selected. Otherwise, an error is
+ reported.
+
+
+
+
+
+
+
+ Generated headers
+
+ Usually, Boost.Build handles implicit dependendies completely
+ automatically. For example, for C++ files, all #include
+ statements are found and handled. The only aspect where user help
+ might be needed is implicit dependency on generated files.
+
+ By default, Boost.Build handles such dependencies within one
+ main target. For example, assume that main target "app" has two
+ sources, "app.cpp" and "parser.y". The latter source is converted
+ into "parser.c" and "parser.h". Then, if "app.cpp" includes
+ "parser.h", Boost.Build will detect this dependency. Moreover,
+ since "parser.h" will be generated into a build directory, the
+ path to that directory will automatically added to include
+ path.
+
+ Making this mechanism work across main target boundaries is
+ possible, but imposes certain overhead. For that reason, if
+ there's implicit dependency on files from other main targets, the
+ <implicit-dependency> [ link ] feature must
+ be used, for example:
+
+
+lib parser : parser.y ;
+exe app : app.cpp : <implicit-dependency>parser ;
+
+
+
+The above example tells the build system that when scanning
+all sources of "app" for implicit-dependencies, it should consider
+targets from "parser" as potential dependencies.
+
+
+
+
+ Generators
+
+ To construct a main target with given properties from sources,
+ it is required to create a dependency graph for that main target,
+ which will also include actions to be run. The algorithm for
+ creating the dependency graph is described here.
+
+ The fundamental concept is generator. If encapsulates
+ the notion of build tool and is capable to converting a set of
+ input targets into a set of output targets, with some properties.
+ Generator matches a build tool as closely as possible: it works
+ only when the tool can work with requested properties (for
+ example, msvc compiler can't work when requested toolset is gcc),
+ and should produce exactly the same targets as the tool (for
+ example, if Borland's linker produces additional files with debug
+ information, generator should also).
+
+ Given a set of generators, the fundamental operation is to
+ construct a target of a given type, with given properties, from a
+ set of targets. That operation is performed by rule
+ generators.construct and the used algorithm is described
+ below.
+
+
+ Selecting and ranking viable generators
+
+ Each generator, in addition to target types that it can
+ produce, have attribute that affects its applicability in
+ particular sitiation. Those attributes are:
+
+
+
+
+ Required properties, which are properties absolutely
+ necessary for the generator to work. For example, generator
+ encapsulating the gcc compiler would have <toolset>gcc as
+ required property.
+
+
+
+
+
+ Optional properties, which increase the generators
+ suitability for a particual build.
+
+
+
+
+
+ Generator's required and optional properties may not include
+ either free or incidental properties. (Allowing this would
+ greatly complicate caching targets).
+
+
+ When trying to construct a target, the first step is to select
+ all possible generators for the requested target type, which
+ required properties are a subset of requested properties.
+ Generators which were already selected up the call stack are
+ excluded. In addition, if any composing generators were selected
+ up the call stack, all other composing generators are ignored
+ (TODO: define composing generators). The found generators
+ assigned a rank, which is the number of optional properties
+ present in requested properties. Finally, generators with highest
+ rank are selected for futher processing.
+
+
+
+ Running generators
+
+ When generators are selected, each is run to produce a list of
+ created targets. This list might include targets which are not of
+ requested types, because generators create the same targets as
+ some tool, and tool's behaviour is fixed. (Note: should specify
+ that in some cases we actually want extra targets). If generator
+ fails, it returns an empty list. Generator is free to call
+ 'construct' again, to convert sources to the types it can handle.
+ It also can pass modified properties to 'constuct'. However, a
+ generator is not allowed to modify any propagated properties,
+ otherwise when actually consuming properties we might discover
+ that the set of propagated properties is different from what was
+ used for building sources.
+
+ For all targets which are not of requested types, we try to
+ convert them to requested type, using a second call to
+ construct. This is done in order to support
+ transformation sequences where single source file expands to
+ several later. See this
+ message for details.
+
+
+
+
+ Selecting dependency graph
+
+
+ After all generators are run,
+ it is necessary to decide which of successfull invocation will be
+ taken as final result. At the moment, this is not done. Instead,
+ it is checked whether all successfull generator invocation
+ returned the same target list. Error is issued otherwise.
+
+
+
+
+
+ Property adjustment
+
+ Because target location is determined by the build system, it
+ is sometimes necessary to adjust properties, in order to not
+ break actions. For example, if there's an action which generates
+ a header, say "a_parser.h", and a source file "a.cpp" which
+ includes that file, we must make everything work as if a_parser.h
+ is generated in the same directory where it would be generated
+ without any subvariants.
+
+ Correct property adjustment can be done only after all targets
+ are created, so the approach taken is:
+
+
+
+
+ When dependency graph is constructed, each action can be
+ assigned a rule for property adjustment.
+
+
+
+
+
+ When virtual target is actualized, that rule is run and
+ return the final set of properties. At this stage it can use
+ information of all created virtual targets.
+
+
+
+
+ In case of quoted includes, no adjustment can give 100%
+ correct results. If target dirs are not changed by build system,
+ quoted includes are searched in "." and then in include path,
+ while angle includes are searched only in include path. When
+ target dirs are changed, we'd want to make quoted includes to be
+ search in "." then in additional dirs and then in the include
+ path and make angle includes be searched in include path,
+ probably with additional paths added at some position. Unless,
+ include path already has "." as the first element, this is not
+ possible. So, either generated headers should not be included
+ with quotes, or first element of include path should be ".",
+ which essentially erases the difference between quoted and angle
+ includes. Note: there only way to get "." as include path
+ into compiler command line is via verbatim compiler option. In
+ all other case, Boost.Build will convert "." into directory where
+ it occurs.
+
+
+
+
+ Transformations cache
+
+
+ Under certain conditions, an
+ attempt is made to cache results of transformation search. First,
+ the sources are replaced with targets with special name and the
+ found target list is stored. Later, when properties, requested
+ type, and source type are the same, the store target list is
+ retrieved and cloned, with appropriate change in names.
+
+
+
+
+
+
+
diff --git a/v2/doc/src/tutorial.xml b/v2/doc/src/tutorial.xml
new file mode 100644
index 000000000..167ee4214
--- /dev/null
+++ b/v2/doc/src/tutorial.xml
@@ -0,0 +1,516 @@
+
+
+
+
+ Tutorial
+
+
+ Hello, world
+
+ The simplest project that Boost.Build can construct is
+ stored in example/hello directory. The targets are declared in
+ a file called Jamfile, which contains the
+ following:
+
+
+exe hello : hello.cpp ;
+
+
+ Even with this simple setup, you can do some interesting
+ things. First of all, running "bjam" would build binary "hello"
+ from hello.cpp, in debug version. After that, you can run
+
+
+bjam release
+
+
+ which would create release version of the 'hello' binary.
+ Note that debug and release version would be created in different
+ directories, so if you want to switch from debug to release
+ version and back, no recompilation is needed. Let's extend the
+ example by adding another line to Jamfile:
+
+
+exe hello2 : hello.cpp ;
+
+
+ You can now rebuild both debug and release versions:
+
+
+bjam debug release
+
+
+ You'll see that two versions of "hello2" binary are linked.
+ Of course, hello.cpp won't be recompiled. Now you decide to remove
+ all build products. You do that with the following command
+
+
+bjam --clean debug release
+
+
+ It's also possible to create or clean only specific targets.
+ Both following commands are legal and create or clean only files
+ that belonging the the named binary:
+
+
+bjam hello2
+bjam --clean hello2
+
+
+
+
+
+ Properties
+
+ Boost.Build attempts to allow building different variants of
+ projects, e.g. for debugging and release, or in single and
+ multithreaded mode. In order to stay portable, it uses the
+ concept of features, which is abstract aspect of
+ build configuration. Property is just a (feature,
+ value) pair. For example, there's a feature "debug-symbols", which can
+ have a value of "on" or "off". When users asks to build project is a
+ particual value, Boost.Build will automatically find the
+ appropriate flags to the used compiler.
+
+ The "release" and "debug" in bjam invocation that we've seen
+ are just are short form of specifying values of feature
+ "variant". There is a lot of builtin features, and it's possible
+ to write something like:
+
+
+bjam release inlining=off debug-symbols=on
+
+
+
+ The first command line element specified the value of feature
+ "variant". The feature is very common and is therefore special
+ — it's possible to specify only value. Another feature,
+ "inlining" is not special, and you should use
+
+
+feature-name=feature-value
+
+
+ syntax for it. Complete description of features can be found
+ here. The set of
+ properties specified in the command line constitute
+ build request — the desired properties
+ for requested targets, or for the project in the current
+ directory. The actual set of properties used for building is
+ often different. For example, when compiling a program you need
+ some include paths. It's not reasonable to ask the user to specify
+ those paths with each bjam invocation, so must be specified in
+ Jamfile and added to the build request. For another example,
+ certain application can only be linked in multithreaded mode. To
+ support such situations, every target is allowed to specify
+ requirements -- properties that are required
+ to its building. Consider this example:
+
+
+exe hello
+ : hello.cpp
+ : <include>/home/ghost/Work/boost <threading>multi
+
+
+ In this case, when hello is build, the two specified properties will
+ always be present. This leads to a question: what if user explictly
+ requested single-threading. The answer is that requirement can
+ affect build properties only to a certain degree: the requested and
+ actual properties must be link-compatible. See below. If they are not link
+ compatible, the bulding of the target is skipped. Previously, we've
+ added "hello2" target. Seems like we have to specify the same
+ requirements for it, which results in duplication. But there's a
+ better way. Each project (i.e. each Jamfile), can specify a set of
+ attributes, including requirements:
+
+
+project
+ : requirements <include>/home/ghost/Work/boost <threading>multi
+ ;
+
+exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
+
+
+ The effect would be as if we specified this requirement for
+ both "hello" and "hello2".
+
+
+
+
+ Project hierarchy
+
+ So far we only considered examples with one project (i.e. with
+ one Jamfile). Typically, you'd have a lot of projects organized
+ into a tree. At the top of the tree there's project
+ root. This is a directory which contains, besides Jamfile, a
+ file called "project-root.jam". Each other Jamfile has a single
+ parent, which is the Jamfile in the nearest parent directory. For
+ example, in the following directory layout:
+
+
+[top]
+ |
+ |-- Jamfile
+ |-- project-root.jam
+ |
+ |-- src
+ | |
+ | |-- Jamfile
+ | \-- app.cpp
+ |
+ \-- lib
+ |
+ |-- lib1
+ | |
+ | |-- Jamfile
+ |-- lib1.cpp
+
+
+
+project root is at top. Both src/Jamfile and lib/lib1/Jamfile
+have [top]/Jamfile as parent project. Projects inherit all
+attributes (such as requirements) from their parents. When the same
+attributes are specified in the project, they are combined with
+inherited ones. For example, if [top]/Jamfile has
+
+
+<include>/home/ghost/local
+
+
+in requirements, then all other projects will have that in
+their requirements too. Of course, any project can add additional
+includes. More details can be found in the section on projects. Projects are not automatically
+built when
+their parents are built. You should specify this explicitly. In our
+example, [top]/Jamfile might contain:
+
+
+build-project src ;
+
+
+ It will cause project in src to be built whenever project in
+[top] is built. However, targets in lib/lib1 will be built only if
+required. For example, there may be 10 targets, and two of them are
+used by targets in src/Jamfile. Then, only those two targets will
+be built.
+
+
+
+
+ Using libraries
+
+ Let's continue the above example and see how src/Jamfile
+ can use libraries from
+ lib/lib1. (TODO: need to make this section consistent with
+ "examples-v2/libraries". Assume lib/lib1/Jamfile contains:
+
+
+lib lib1 : lib1.cpp ;
+
+
+ Then, to use this library in src/Jamfile, we can write:
+
+
+exe app : app.cpp ../lib/lib1//lib1 ;
+
+
+While "app.cpp" is a regular source file, "../lib/lib1//lib1"
+is a reference to another target, here, library "lib1" declared in
+Jamfile at "../lib/lib1". When linking the "app" binary, the needed
+version of the library will be built and linked in. But what is
+meant by "needed"? For example, we can request to build "app" with
+properties
+
+
+<optimization>full <cxxflags>-w-8080
+
+
+Which properties must be used for "lib1"? The answer is that
+some properties are propagated — Boost.Build attemps
+to use dependencies with the same value of propagated features. The
+<optimization> feature is propagated, so both "app" and
+"lib1" will be compiled with full optimization. But
+<cxxflags> feature is not propagated: its value will be added
+as-is to compiler flags for "a.cpp", but won't affect "lib1". There
+is still a couple of problems. First, the library probably has some
+headers which must be used when compiling "app.cpp". We could use
+requirements on "app" to add those includes, but then this work
+will be repeated for all programs which use "lib1". A better
+solution is to modify lib/lib1/Jamfilie in this way:
+
+
+project
+ : usage-requirements <include>.
+ ;
+
+lib lib1 : lib1.cpp ;
+
+
+Usage requirements are requirements which are applied to
+dependents. In this case, <include> will be applied to all
+targets which use "lib1" — i.e. targets which have "lib1"
+either in sources or in dependency properties. You'd need to
+specify usage requirements only once, and programs which use "lib1"
+don't have to care about include paths any longer. Or course, the
+path will be interpreted relatively to "lib/lib1" and will be
+adjusted according to the bjams invocation
+directory. For
+example, if building from project root, the final compiler's
+command line will contain .
+
+
+ The second problem is that we hardcode the path to library's
+ Jamfile. Imagine it's hardcoded in 20 different places and we
+ change the directory layout. The solution is to use project ids
+ — symbolic names, not tied to directory layout. First, we
+ assign a project id to Jamfile in lib/lib1:
+
+
+project lib1
+ : usage-requirements <include>.
+ ;
+
+
+
+Second, we use the project id to refer to the library in
+src/Jamfile:
+
+
+exe app : app.cpp /lib1//lib1 ;
+
+
+The "/lib1//lib1" syntax is used to refer to target "lib1" in
+project with global id "/lib1" (the slash is used to specify global
+id). This way, users of "lib1" do not depend on its location, only
+on id, which is supposedly stable. The only thing left, it to make
+sure that src/Jamfile knows the project id that it uses. We add to
+[top]/Jamfile the following line:
+
+
+use-project /lib1 : lib/lib1 ;
+
+
+Now, all projects can refer to "lib1" using the symbolic
+name. If the library is moved somewhere, only a single line in the
+top-level Jamfile should be changed.
+
+
+
+
+ Library dependencies
+
+ The previous example was simple. Often, there are long chains
+ of dependencies between libraries. The main application is a thin
+ wrapper on top of library with core logic, which uses library of
+ utility functions, which uses boost filesystem library.
+ Expressing these dependencies is straightforward:
+
+
+lib utils : utils.cpp /boost/filesystem//fs ;
+lib core : core.cpp utils ;
+exe app : app.cpp core ;
+
+
+ So, what's the reason to even mention this case? First,
+ because it's a bit more complex that it seems. When using shared
+ linking, libraries are build just as written, and everything will
+ work. However, what happens with static linking? It's not
+ possible to include another library in static library.
+ Boost.Build solves this problem by returning back library targets
+ which appear as sources for static libraries. In this case, if
+ everything is built statically, the "app" target will link not
+ only "core" library, but also "utils" and
+ "/boost/filesystem//fs".
+
+ So, the net result is that the above code will work for both
+ static linking and for shared linking.
+
+ Sometimes, you want all applications in some project to link
+ to a certain library. Putting the library in sources of all
+ targets is possible, but verbose. You can do better by using
+ <library> property. For example, if "/boost/filesystem//fs"
+ should be linked to all applications in your project, you can add
+ <library>/boost/filesystem//fs to requirements of the
+ project, like this:
+
+
+project
+ : requirements <library>/boost/filesystem//fs
+ ;
+
+
+
+
+ Static and shared libaries
+
+ While the
+ previous section explained how to create and use libraries, it
+ omitted one important detail. Libraries can be either
+ static, which means they are included in executable
+ files which use them, or shared (a.k.a.
+ dynamic), which are only referred to from executables,
+ and must be available at run time. Boost.Build can work with both
+ types. By default, all libraries are shared. This is much more
+ efficient in build time and space. But the need to install all
+ libraries to some location is not always convenient, especially
+ for debug builds. Also, if the installed shared library changes,
+ all application which use it might start to behave differently.
+
+
+ Static libraries do not suffer from these problems, but
+ considerably increase the size of application. Before describing
+ static libraries, it's reasonable to give another, quite simple
+ approach. If your project is built with
+ <hardcode-dll-paths>true property, then the application
+ will include the full paths for all shared libraries, eliminating
+ the above problems. Unfortunately, you no longer can move shared
+ library to a different location, which makes this option suitable
+ only for debug builds. Further, only gcc compiler supports this
+ option.
+
+ Building a library statically is easy. You'd need to change
+ the value of <link> feature from it's deafault value
+ shared, to static. So, to build everything as
+ static libraries, you'd say
+
+
+bjam link=static
+
+
+
+on the command line. The linking mode can be fine-tuned on
+per-target basis.
+
+
+
+
+ Suppose your library can be only build statically. This is
+ easily achieved using requirements:
+
+
+lib l : l.cpp : <link>static ;
+
+
+
+
+
+
+
+ What if library can be both static and shared, but when
+ using it in specific executable, you want it static?
+ Target
+ references are here to help:
+
+
+exe important : main.cpp helpers/<link>static ;
+
+
+
+
+
+
+
+ What if the library is defined in some other project, which
+ you cannot change. But still, you want static linking to that
+ library in all cases. You can use target references everywhere:
+
+
+exe e1 : e1.cpp /other_project//lib1/<link>static ;
+exe e10 : e10.cpp /other_project//lib1/<link>static ;
+
+
+but that's far from being convenient. Another way is to
+introduce a level of indirection: create a local target, which will
+refer to static version of lib1. Here's the
+solution:
+
+
+alias lib1 : /other_project//lib1/<link>static ;
+exe e1 : e1.cpp lib1 ;
+exe e10 : e10.cpp lib1 ;
+
+
+(Note, that the "alias" target type is not yet implemented,
+but it's quite simple to do. I bet it's waiting for you to do it
+;-))
+
+
+
+
+
+
+
+ Prebuilt targets
+
+
+ We've just learned how to use libraries which are created by
+ Boost.Build. But some libraries are not. At the same time, those
+ libraries can have different versions (release and debug, for
+ example), that we
+ should select depending on build properties. Prebuilt targets
+ provide a mechanism for that. Jamfile in lib/lib2 can contain:
+
+
+lib lib2
+ :
+ : <file>lib2_release.a <variant>release
+ ;
+
+lib lib2
+ :
+ : <file>lib2_debug.a <variant>debug
+ ;
+
+
+This defines two alternatives for target "lib2", and for each
+one names a prebuilt file. Naturally, there are no sources.
+Instead, the <file> feature is used to specify the file name.
+Which alternative is selected depends on properties of dependents.
+If "app" binary should use "lib2", we can write:
+
+
+exe app : app.cpp /lib/lib1//lib2 ../lib/lib2//lib2 ;
+
+
+If we build release version of "app", then it will be linked
+with "lib2_release.a", and debug version will use "lib2_debug.a".
+Another important kind of prebuilt targets are system libraries
+— more specifically, libraries which are automatically found
+by the compiler. E.g. gcc uses "-l" switch for that. Such libraries
+should be declared almost like regular ones:
+
+
+lib zlib : : <name>z ;
+
+
+We again don't specify any sources, but give a name which
+should be passed to the compiler. In this example, and for gcc
+compiler, the "-lz" option will be added. Paths where library
+should be searched can also be specified:
+
+
+lib zlib : : <name>z <search>/opt/lib ;
+
+
+And, of course, two variants can be used:
+
+
+lib zlib : : <name>z <variant>release ;
+lib zlib : : <name>z_d <variant>debug ;
+
+
+Of course, you'll probably never in your life need debug
+version of zlib, but for other libraries this is quite reasonable.
+
+
+ More advanced use of prebuilt target is descibed in recipes.
+
+
+
+
+
diff --git a/v2/doc/src/userman.xml b/v2/doc/src/userman.xml
new file mode 100644
index 000000000..9d69bcff6
--- /dev/null
+++ b/v2/doc/src/userman.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+ Boost.Build v2 User Manual
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/v2/doc/userman.xml b/v2/doc/userman.xml
deleted file mode 100644
index 328ecb351..000000000
--- a/v2/doc/userman.xml
+++ /dev/null
@@ -1,3189 +0,0 @@
-
-
-
-
- Boost.Build v2 User Manual
-
-
- How to use this document
-
-
- If you've just found out about Boost.Build V2 and want to know
- if it will work for you, start with . You can continue with the . When you're ready to try Boost.Build
- in practice, go to .
-
-
-
- If you are about to use Boost.Build on your project, or already
- using it and have a problem, look at .
-
-
-
- If you're trying to build a project which uses Boost.Build,
- look at and then read about
- .
-
-
-
- Finally, if nothing applies to you, write to our mailing list,
- telling what information you'd like to know.
-
-
-
-
-
- Installation
-
-
- Assuming you're installing Boost.Build from released source
- distribution, the following steps are needed. All paths are
- given relatively to Boost.Build root directory, which is the
- directory with the document you are reading.
-
-
-
-
-
- Go to "jam_src" directory and build Boost.Jam. Two convenient
- scripts are provided, "build.sh" (for Unix systems) and
- "build.bat" (for Windows). Run the appropriate one and
- Boost.Jam will be built to directory
- bin.{platform_name}.. The Boost.Jam documentation has
- more details in case you need them.
-
-
-
-
-
- Place the Boost.Jam binary, called "bjam" or "bjam.exe",
- somewhere in your PATH. Go to the root
- directory of Boost.Build and run "bjam --version". You should
- get
-
- Boost.Build V2 (Milestone N)
-
- (where N is the version you've downloaded).
-
-
-
-
-
- Configure toolsets to use. Open the
- user-config.jam file and follow
- instructions there to specify what compiles/libraries you
- have and where they are located.
-
-
-
-
-
- You should now be able to go to
- example/hello, and run
- bjam there. A simple application will be
- built. You can also play with other projects in
- example.
-
-
-
-
-
-
- If you use Boost distribution, or Boost CVS, the Boost.Build
- root is located at $boost_root/tools/build/v2
- and the installation steps are the same. However, don't skip
- the bjam rebuilding step, even if you have a previous version.
- CVS version of Boost.Build requires CVS version of Boost.Jam.
-
-
-
- When starting a new project which uses Boost.Build, you need
- to make sure that build system can be found. There are two
- ways.
-
-
-
-
-
- Set enviromnetal variable BOOST_BUILD_PATH
- to the absolute path to Boost.Build installation directory.
-
-
-
-
-
- Create, at the top of your project, a file called
- boost-build.jam, with a single line:
-
-
-boost-build /path/to/boost.build ;
-
-
-
-
-
-
- If you're trying to use Boost.Build V2 on Boost itself, please
- note that when building Boost, V1 is used by default. You'd have
- to add command line option to all "bjam"
- invocations.
-
-
-
-
- Tutorial
-
-
- Hello, world
-
- The simplest project that Boost.Build can construct is
- stored in example/hello directory. The targets are declared in
- a file called Jamfile, which contains the
- following:
-
-
-exe hello : hello.cpp ;
-
-
- Even with this simple setup, you can do some interesting
- things. First of all, running "bjam" would build binary "hello"
- from hello.cpp, in debug version. After that, you can run
-
-
-bjam release
-
-
- which would create release version of the 'hello' binary.
- Note that debug and release version would be created in different
- directories, so if you want to switch from debug to release
- version and back, no recompilation is needed. Let's extend the
- example by adding another line to Jamfile:
-
-
-exe hello2 : hello.cpp ;
-
-
- You can now rebuild both debug and release versions:
-
-
-bjam debug release
-
-
- You'll see that two versions of "hello2" binary are linked.
- Of course, hello.cpp won't be recompiled. Now you decide to remove
- all build products. You do that with the following command
-
-
-bjam --clean debug release
-
-
- It's also possible to create or clean only specific targets.
- Both following commands are legal and create or clean only files
- that belonging the the named binary:
-
-
-bjam hello2
-bjam --clean hello2
-
-
-
-
-
- Properties
-
- Boost.Build attempts to allow building different variants of
- projects, e.g. for debugging and release, or in single and
- multithreaded mode. In order to stay portable, it uses the
- concept of features, which is abstract aspect of
- build configuration. Property is just a (feature,
- value) pair. For example, there's a feature "debug-symbols", which can
- have a value of "on" or "off". When users asks to build project is a
- particual value, Boost.Build will automatically find the
- appropriate flags to the used compiler.
-
- The "release" and "debug" in bjam invocation that we've seen
- are just are short form of specifying values of feature
- "variant". There is a lot of builtin features, and it's possible
- to write something like:
-
-
-bjam release inlining=off debug-symbols=on
-
-
-
- The first command line element specified the value of feature
- "variant". The feature is very common and is therefore special
- — it's possible to specify only value. Another feature,
- "inlining" is not special, and you should use
-
-
-feature-name=feature-value
-
-
- syntax for it. Complete description of features can be found
- here. The set of
- properties specified in the command line constitute
- build request — the desired properties
- for requested targets, or for the project in the current
- directory. The actual set of properties used for building is
- often different. For example, when compiling a program you need
- some include paths. It's not reasonable to ask the user to specify
- those paths with each bjam invocation, so must be specified in
- Jamfile and added to the build request. For another example,
- certain application can only be linked in multithreaded mode. To
- support such situations, every target is allowed to specify
- requirements -- properties that are required
- to its building. Consider this example:
-
-
-exe hello
- : hello.cpp
- : <include>/home/ghost/Work/boost <threading>multi
-
-
- In this case, when hello is build, the two specified properties will
- always be present. This leads to a question: what if user explictly
- requested single-threading. The answer is that requirement can
- affect build properties only to a certain degree: the requested and
- actual properties must be link-compatible. See below. If they are not link
- compatible, the bulding of the target is skipped. Previously, we've
- added "hello2" target. Seems like we have to specify the same
- requirements for it, which results in duplication. But there's a
- better way. Each project (i.e. each Jamfile), can specify a set of
- attributes, including requirements:
-
-
-project
- : requirements <include>/home/ghost/Work/boost <threading>multi
- ;
-
-exe hello : hello.cpp ;
-exe hello2 : hello.cpp ;
-
-
- The effect would be as if we specified this requirement for
- both "hello" and "hello2".
-
-
-
-
- Project hierarchy
-
- So far we only considered examples with one project (i.e. with
- one Jamfile). Typically, you'd have a lot of projects organized
- into a tree. At the top of the tree there's project
- root. This is a directory which contains, besides Jamfile, a
- file called "project-root.jam". Each other Jamfile has a single
- parent, which is the Jamfile in the nearest parent directory. For
- example, in the following directory layout:
-
-
-[top]
- |
- |-- Jamfile
- |-- project-root.jam
- |
- |-- src
- | |
- | |-- Jamfile
- | \-- app.cpp
- |
- \-- lib
- |
- |-- lib1
- | |
- | |-- Jamfile
- |-- lib1.cpp
-
-
-
-project root is at top. Both src/Jamfile and lib/lib1/Jamfile
-have [top]/Jamfile as parent project. Projects inherit all
-attributes (such as requirements) from their parents. When the same
-attributes are specified in the project, they are combined with
-inherited ones. For example, if [top]/Jamfile has
-
-
-<include>/home/ghost/local
-
-
-in requirements, then all other projects will have that in
-their requirements too. Of course, any project can add additional
-includes. More details can be found in the section on projects. Projects are not automatically
-built when
-their parents are built. You should specify this explicitly. In our
-example, [top]/Jamfile might contain:
-
-
-build-project src ;
-
-
- It will cause project in src to be built whenever project in
-[top] is built. However, targets in lib/lib1 will be built only if
-required. For example, there may be 10 targets, and two of them are
-used by targets in src/Jamfile. Then, only those two targets will
-be built.
-
-
-
-
- Using libraries
-
- Let's continue the above example and see how src/Jamfile
- can use libraries from
- lib/lib1. (TODO: need to make this section consistent with
- "examples-v2/libraries". Assume lib/lib1/Jamfile contains:
-
-
-lib lib1 : lib1.cpp ;
-
-
- Then, to use this library in src/Jamfile, we can write:
-
-
-exe app : app.cpp ../lib/lib1//lib1 ;
-
-
-While "app.cpp" is a regular source file, "../lib/lib1//lib1"
-is a reference to another target, here, library "lib1" declared in
-Jamfile at "../lib/lib1". When linking the "app" binary, the needed
-version of the library will be built and linked in. But what is
-meant by "needed"? For example, we can request to build "app" with
-properties
-
-
-<optimization>full <cxxflags>-w-8080
-
-
-Which properties must be used for "lib1"? The answer is that
-some properties are propagated — Boost.Build attemps
-to use dependencies with the same value of propagated features. The
-<optimization> feature is propagated, so both "app" and
-"lib1" will be compiled with full optimization. But
-<cxxflags> feature is not propagated: its value will be added
-as-is to compiler flags for "a.cpp", but won't affect "lib1". There
-is still a couple of problems. First, the library probably has some
-headers which must be used when compiling "app.cpp". We could use
-requirements on "app" to add those includes, but then this work
-will be repeated for all programs which use "lib1". A better
-solution is to modify lib/lib1/Jamfilie in this way:
-
-
-project
- : usage-requirements <include>.
- ;
-
-lib lib1 : lib1.cpp ;
-
-
-Usage requirements are requirements which are applied to
-dependents. In this case, <include> will be applied to all
-targets which use "lib1" — i.e. targets which have "lib1"
-either in sources or in dependency properties. You'd need to
-specify usage requirements only once, and programs which use "lib1"
-don't have to care about include paths any longer. Or course, the
-path will be interpreted relatively to "lib/lib1" and will be
-adjusted according to the bjams invocation
-directory. For
-example, if building from project root, the final compiler's
-command line will contain .
-
-
- The second problem is that we hardcode the path to library's
- Jamfile. Imagine it's hardcoded in 20 different places and we
- change the directory layout. The solution is to use project ids
- — symbolic names, not tied to directory layout. First, we
- assign a project id to Jamfile in lib/lib1:
-
-
-project lib1
- : usage-requirements <include>.
- ;
-
-
-
-Second, we use the project id to refer to the library in
-src/Jamfile:
-
-
-exe app : app.cpp /lib1//lib1 ;
-
-
-The "/lib1//lib1" syntax is used to refer to target "lib1" in
-project with global id "/lib1" (the slash is used to specify global
-id). This way, users of "lib1" do not depend on its location, only
-on id, which is supposedly stable. The only thing left, it to make
-sure that src/Jamfile knows the project id that it uses. We add to
-[top]/Jamfile the following line:
-
-
-use-project /lib1 : lib/lib1 ;
-
-
-Now, all projects can refer to "lib1" using the symbolic
-name. If the library is moved somewhere, only a single line in the
-top-level Jamfile should be changed.
-
-
-
-
- Library dependencies
-
- The previous example was simple. Often, there are long chains
- of dependencies between libraries. The main application is a thin
- wrapper on top of library with core logic, which uses library of
- utility functions, which uses boost filesystem library.
- Expressing these dependencies is straightforward:
-
-
-lib utils : utils.cpp /boost/filesystem//fs ;
-lib core : core.cpp utils ;
-exe app : app.cpp core ;
-
-
- So, what's the reason to even mention this case? First,
- because it's a bit more complex that it seems. When using shared
- linking, libraries are build just as written, and everything will
- work. However, what happens with static linking? It's not
- possible to include another library in static library.
- Boost.Build solves this problem by returning back library targets
- which appear as sources for static libraries. In this case, if
- everything is built statically, the "app" target will link not
- only "core" library, but also "utils" and
- "/boost/filesystem//fs".
-
- So, the net result is that the above code will work for both
- static linking and for shared linking.
-
- Sometimes, you want all applications in some project to link
- to a certain library. Putting the library in sources of all
- targets is possible, but verbose. You can do better by using
- <library> property. For example, if "/boost/filesystem//fs"
- should be linked to all applications in your project, you can add
- <library>/boost/filesystem//fs to requirements of the
- project, like this:
-
-
-project
- : requirements <library>/boost/filesystem//fs
- ;
-
-
-
-
- Static and shared libaries
-
- While the
- previous section explained how to create and use libraries, it
- omitted one important detail. Libraries can be either
- static, which means they are included in executable
- files which use them, or shared (a.k.a.
- dynamic), which are only referred to from executables,
- and must be available at run time. Boost.Build can work with both
- types. By default, all libraries are shared. This is much more
- efficient in build time and space. But the need to install all
- libraries to some location is not always convenient, especially
- for debug builds. Also, if the installed shared library changes,
- all application which use it might start to behave differently.
-
-
- Static libraries do not suffer from these problems, but
- considerably increase the size of application. Before describing
- static libraries, it's reasonable to give another, quite simple
- approach. If your project is built with
- <hardcode-dll-paths>true property, then the application
- will include the full paths for all shared libraries, eliminating
- the above problems. Unfortunately, you no longer can move shared
- library to a different location, which makes this option suitable
- only for debug builds. Further, only gcc compiler supports this
- option.
-
- Building a library statically is easy. You'd need to change
- the value of <link> feature from it's deafault value
- shared, to static. So, to build everything as
- static libraries, you'd say
-
-
-bjam link=static
-
-
-
-on the command line. The linking mode can be fine-tuned on
-per-target basis.
-
-
-
-
- Suppose your library can be only build statically. This is
- easily achieved using requirements:
-
-
-lib l : l.cpp : <link>static ;
-
-
-
-
-
-
-
- What if library can be both static and shared, but when
- using it in specific executable, you want it static?
- Target
- references are here to help:
-
-
-exe important : main.cpp helpers/<link>static ;
-
-
-
-
-
-
-
- What if the library is defined in some other project, which
- you cannot change. But still, you want static linking to that
- library in all cases. You can use target references everywhere:
-
-
-exe e1 : e1.cpp /other_project//lib1/<link>static ;
-exe e10 : e10.cpp /other_project//lib1/<link>static ;
-
-
-but that's far from being convenient. Another way is to
-introduce a level of indirection: create a local target, which will
-refer to static version of lib1. Here's the
-solution:
-
-
-alias lib1 : /other_project//lib1/<link>static ;
-exe e1 : e1.cpp lib1 ;
-exe e10 : e10.cpp lib1 ;
-
-
-(Note, that the "alias" target type is not yet implemented,
-but it's quite simple to do. I bet it's waiting for you to do it
-;-))
-
-
-
-
-
-
-
- Prebuilt targets
-
-
- We've just learned how to use libraries which are created by
- Boost.Build. But some libraries are not. At the same time, those
- libraries can have different versions (release and debug, for
- example), that we
- should select depending on build properties. Prebuilt targets
- provide a mechanism for that. Jamfile in lib/lib2 can contain:
-
-
-lib lib2
- :
- : <file>lib2_release.a <variant>release
- ;
-
-lib lib2
- :
- : <file>lib2_debug.a <variant>debug
- ;
-
-
-This defines two alternatives for target "lib2", and for each
-one names a prebuilt file. Naturally, there are no sources.
-Instead, the <file> feature is used to specify the file name.
-Which alternative is selected depends on properties of dependents.
-If "app" binary should use "lib2", we can write:
-
-
-exe app : app.cpp /lib/lib1//lib2 ../lib/lib2//lib2 ;
-
-
-If we build release version of "app", then it will be linked
-with "lib2_release.a", and debug version will use "lib2_debug.a".
-Another important kind of prebuilt targets are system libraries
-— more specifically, libraries which are automatically found
-by the compiler. E.g. gcc uses "-l" switch for that. Such libraries
-should be declared almost like regular ones:
-
-
-lib zlib : : <name>z ;
-
-
-We again don't specify any sources, but give a name which
-should be passed to the compiler. In this example, and for gcc
-compiler, the "-lz" option will be added. Paths where library
-should be searched can also be specified:
-
-
-lib zlib : : <name>z <search>/opt/lib ;
-
-
-And, of course, two variants can be used:
-
-
-lib zlib : : <name>z <variant>release ;
-lib zlib : : <name>z_d <variant>debug ;
-
-
-Of course, you'll probably never in your life need debug
-version of zlib, but for other libraries this is quite reasonable.
-
-
- More advanced use of prebuilt target is descibed in recipes.
-
-
-
-
-
-
- Advanced
-
- This section will document
- mostly high-level view of Boost.Build, mentioning appropriate
- modules and rules. The on-line help system must be used to obtain
- low-level documentation (see the help option).
-
-
- Overview
-
- The most fundemental entity in Boost.Build is main
- target. This is object that user want to construct from
- sources and keep up to date with regard to those sources. Typical
- examples of main targets are executable files and libraries.
-
- Main targets are grouped in projects. Their main
- purpose is organization: related targets placed in one project,
- can then be built together, or share some definitions.
-
- Main targets and projects are created as the result of reading
- one or several Jamfiles. Each Jamfile is a file written in
- Boost.Jam interpreted language, and typically contains calls to
- functions provided by Boost.Build, which create main targets of
- needed type, declare project attributes and access other
- projects. The full list of functions provided by Boost.Build is
- described below.
- Of course, user can create his own functions, or it can directly
- access Boost.Build internals from Jamfile, if builtin facilities are
- not sufficient.
-
- Each main target, or project can be built in a number of ways,
- say with optimization or without. We'll call such entities
- "metatargets". To make Boost.Build produce any real targets, user
- issues build request,
- which specifies metatargets to be built, and properties to be
- used.
-
- The properties are just (name,value) pairs that
- describe various aspects of constructed objects, for example:
-
-<optimization>full <inlining>off
-
-
- Given the built request, Boost.Build figures out the targets
- needed for requested metatargets with requested properties, how
- they can be created, and whether exising files can be reused. It
- finally issues command to create needed files, automatically
- converting properties into appropricate command line options.
-
-
-
-
- Your first project and roadmap
-
- Creating your first project requires three steps:
-
-
- Create an empty file called "Jamfile"
-
-
-
- Create an empty file called "project-root.jam"
-
-
-
-
- Either set your BOOST_BUILD_PATH environment
- variant to Boost.Build root, or create a "boost-build.jam" file
- with the following content:
-
-
-boost-build /path/to/boost.build ;
-
-
-
-
-
-
- After that, you can run the "bjam" command in the directory
- where you've created the files. Surely, it won't do anything, but
- it will run without error, at least. Your next steps might
- be:
-
-
-
-
- Adding new main targets to the "Jamfile" file. The basic
- syntax for declaring a main target is described below, and all builtin functions for
- declaring main targets are listed.
-
-
-
-
-
- Creating subprojects. Create a directory, put new Jamfile
- there, and move some main targets to that Jamfile, or declare
- new ones. The projects
- reference will help with this part.
-
-
-
-
-
- Customizing Boost.Build for your needs. You might have
- additional tools you want to run, or just want different
- extension for some file. The extender manual is waiting for
- you.
-
-
-
-
-
-
-
- Main targets
-
-
- Main target is a user-defined named
- entity which can be build, for example a named executable file.
- Declaring a main target is usually done using one of main target functions.
- The user can also declare custom main target
- function.
-
- Most main targets rules in Boost.Build use similiar
- syntax:
-
-
-function-name main-target-name
- : sources
- : requirements
- : default-build
- : usage-requirements
- ;
-
-
-
-
-
- "main-target-name" is the name used to request the target
- on command line and to use it from other main targets. Main
- target name may contain alphanumeric characters and symbols '-'
- and '_';
-
-
-
-
-
- "sources" is the list of source files and other main
- targets that must be combined. If source file is specified
- using relative path, it's considered to be relative to the
- source directory of the project where the path is used. See the
- project rule
- for information how to change source directory.
-
-
-
-
-
- "requirements" is the list of properties that must always
- be present when this main target is built.
-
-
-
-
-
- "default-build" is the list of properties that will be used
- unless some other value of the same feature is already
- specified.
-
-
-
-
-
- "usage-requirements" is the list of properties that will be
- propagated to all main targets that use this one, i.e. to all
- dependedents.
-
-
-
-
- Some main target rules have shorter list of parameters, and
- you should consult their documentation for details.
-
- Building of the same main target can differ greatly from
- platform to platform. For example, you might have different list
- of sources for different compilers. Therefore it is possible to
- invoke main target rules several times for a single main target.
- For example:
-
-
-exe a : a_gcc.cpp : <toolset>gcc ;
-exe a : a.cpp ;
-
-
-
- Each call to the 'exe' rule defines a new main target
- alternative for the main target a.
- In this case, the first alternative will be used for the
- gcc toolset, while the second alternative will
- be used in other cases. See below for
- details.
-
-
- Sometime a main target is really needed only by some other
- main target. E.g. a rule that declared test-suite uses a main
- target that represent test, but those main targets are rarely
- needed by themself.
-
- It possible to declare target inline, i.e. the "sources"
- parameter may include call to other main rules. For example:
-
-
-exe hello : hello.cpp
- [ obj helpers : helpers.cpp : <optimization>off ] ;
-
-
-
-Will cause "helpers.cpp" to be always compiled without
-optimization. It's possible to request main targets declared
-inline, but since they are considered local, they are renamed to
-"parent-main-target_name..main-target-name". In the example above,
-to build only helpers, one should run "bjam hello..helpers".
-
-
-
-
-
- Projects
-
- Boost.Build considers every software it build as organized
- into projects — modules which declare targets.
- Projects are organized in a hierarchical structure, so each
- project may have a single parent project and a number of
- subprojects.
-
- Most often, projects are created as result of loading
- Jamfile — files which are specially meant to
- describe projects. Boost.Build will implicitly load Jamfile in
- the invocation directory, and all Jamfiles referred by the first
- one, creating the hierarchy of projects.
-
- The exact name of file that describes project is configurable.
- By default, it's Jamfile, but can be changed by setting
- global variables JAMFILE, for example in
- boost-build.jam file. The value of the variable is a
- list of regex patterns that are used when searching for Jamfile
- in a directory.
-
- Every Boost.Build modules can decide to act as project and be
- able to declare targets. For example, the
- site-config.jam module can declare libraries
- available on a given host, as described here.
-
- There are three things that can be put in Jamfile:
- declarations of main targets, calls to a number of predefined
- rules, and arbitrary user code. The predefined rules are listed
- below:
-
-
-
-
-
-
- Rule
-
- Semantic
-
-
-
-
-
- project
-
-
- Define project attributes.
-
-
-
- use-project
-
- Make another project known.
-
-
-
- build-project
-
- Build another project when this one is built.
-
-
-
- explicit
-
- States that the target should be built only by explicit
- request.
-
-
-
- glob
-
- Takes a list of wildcards, and returns the list of files
- which match any of the wildcards.
-
-
-
-
-
- Each project is also associated with project root.
- That's a root for a tree of projects, which specifies some global
- properties.
-
-
- Project root
-
-
- Project root for a projects is the nearest parent directory
- which contains a file called
- project-root.jam. That file defines
- certain properties which apply to all projects under project
- root. It can:
-
-
-
-
- configure toolsets, via call to toolset.using
-
-
-
-
-
- refer to other projects, via the use-project
- rule
-
-
-
-
-
- declare constants, via the constant and
- path-constant rules.
-
-
-
-
-
-
- To facilitate declaration of simple projects, Jamfile and
- project-root can be merged together. To achieve this effect, the
- project root file should call the project rule. The
- semantic is precisely the same as if the call was made in
- Jamfile, except that project-root.jam will start serve as
- Jamfile. The Jamfile in the directory of project-root.jam will be
- ignored, and project-root.jam will be able to declare main
- targets as usual.
-
-
-
-
- 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". Target references make use of project ids to
- specify a target.
-
- 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 also 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
-
- none
-
- Sets to the passed value
-
-
-
- Build directory
-
- build-dir
-
- If parent has a build dir set, the value of it, joined
- with the relative path from parent to the current project.
- Otherwise, empty
-
- Sets to the passed value, interpreted as relative to the
- project's location.
-
-
-
-
-
-
-
- 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.
-
-
-
-
-
- Target identifiers and references
-
- Target identifier is used to denote a
- target. The syntax is:
-
-
-target-id -> (project-id | target-name | file-name )
- | (project-id | directory-name) "//" target-name
-project-id -> path
-target-name -> path
-file-name -> path
-directory-name -> path
-
-
-
-This grammar allows some elements to be recognized as either
-
-
-
-
- project id (at this point, all project ids start with slash).
-
-
-
-
-
- name of target declared in current Jamfile (note that target
- names may include slash).
-
-
-
-
-
- a regular file, denoted by absolute name or name relative to
- project's sources location.
-
-
-
-
- To determine the real meaning a check is made if project-id
- by the specified name exists, and then if main target of that
- name exists. For example, valid target ids might be:
-
-
-a -- target in current project
-lib/b.cpp -- regular file
-/boost/thread -- project "/boost/thread"
-/home/ghost/build/lr_library//parser -- target in specific project
-
-
-
-
- Rationale:Target is separated from project by special
- separator (not just slash), because:
-
-
-
-
- It emphasises that projects and targets are different things.
-
-
-
-
-
- It allows to have main target names with slashes.
-
-
-
-
-
-
-
- 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
-compiler executable is build with optimization for
-speed.
-
-
-
- Builtin facilities
-
-
- Main targets
-
-
- exe
-
-
-
- Creates a regular executable file. Sources must be either
- object files or libraries, and sources of different types
- will be converted to accepted types automatically.
-
-
-
-
- lib
-
-
- Creates a library file. Depending on the value of
- <link> feature the library will be either static or
- shared. Like with "exe", sources will be converted either to
- objects or libraries.
-
- The handling of libraries in sources depends on whether
- linking is static or shared. For shared linking, libraries
- will be linked in. For static linking the library sources
- will not be linked in, since it's not possible, and will be
- passed on. Other main target which depend on this one will
- see those libraries and link to it. Therefore, putting
- library in sources of other library works in all cases.
-
-
- alias
-
-
-
- Builds all the source targets and returns them unmodified.
- Please run "bjam --help alias" for more details.
-
-
-
- stage
-
-
-
- Copies a number of targets to a single directory. The
- primary purpose is installing binaries. Please run "bjam --help
- stage" for more details.
-
-
-
- unit-test (from module "testing")
-
-
-
- Creates an executable file and runs it. Build won't succeed
- unless the executable runs successfully. The rule is usefull
- for creating test program which should be rerun whenever any
- dependency changes.
-
-
-
-
-
-
-
- Features
-
-
- variant
-
-
-
- The feature which combines several low-level features in
- order to make building most common variants simple.
-
-
- Allowed values:debug, release,
- profile
-
- The value debug expands to
-
-
-<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on
-
-
- The value release expands to
-
-
-<optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off
-
-
- The value profile expands to the same as
- release, plus:
-
-
-<profiling>on <debug-symbols>on
-
-
- Rationale: Runtime debugging is on in debug build
- so suit expectations of people used various IDEs. It's
- assumed other folks don't have any specific expectation in
- this point.
-
-
- link
-
-
-
- Feature which controls how libraries are built.
-
-
- Allowed values:shared,
- static
-
-
- library
-
-
-
- For exe and lib main targets, the <library>X feature
- is equvivalent to putting X in the list of sources. The feature
- is sometimes more convenient: you can put <library>X in
- the requirements for a project and it will be linked to all
- executables.
-
-
-
-
- use
-
-
-
- Causes the target referenced by the value of this feature
- to be constructed and adds it's usage requirements to build
- properties. The constructed targets are not used in any other
- way. The primary use case is when you use some library and want
- it's usage requirements (such as include paths) to be applied,
- but don't want to link to the library.
-
-
-
-
- dll-path
-
-
-
- Specify a path where dynamic libraries should be found at
- where executable or shared library is run. This feature
- directly affects binaries with the gcc compiler, allowing them
- to pick specific libraries, and ignoring all environment
- settings. On other toolsets, the binary still requires proper
- environment settings to be run. However, Boost.Build tools
- which run executables will notice dll-path settings and create
- this environment automatically.
-
-
-
- hardcode-dll-paths
-
-
-
- Controls automatic generation of dll-path properties.
-
-
- Allowed values:off, on When this
- property is on, usage requirements for each library will
- include additional dll-path propertry, with the path the the
- generated library file. This allows to run executables
- without placing all the dependent libraries to a single
- location.
-
-
-
-
-
-
-
-
- Detailed reference
-
-
- Features and properties
-
-
- Definitions
-
- A feature is a normalized (toolset-independent)
- aspect of a build configuration, such as whether inlining is
- enabled. Feature names may not contain the '>'
- character.
-
-
-
- Each feature in a build configuration has one or more
- associated values. Feature values for non-free features
- may not contain the '<', ':', or
- '=' characters. Feature values for free features may not
- contain the '<' character.
-
- 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 feature, and whose identity can be derived
- (in the context of its parent) from its value. A subfeature's
- parent can never be another subfeature. Thus, features and their
- subfeatures form a two-level hierarchy.
-
- A value-string for a feature F is a string of
- the form
- value-subvalue1-subvalue2...-subvalueN, where
- value is a legal value for F and
- subvalue1...subvalueN are legal values of some
- of F's subfeatures. For example, the properties
- <toolset>gcc <toolset-version>3.0.1 can be
- expressed more conscisely using a value-string, as
- <toolset>gcc-3.0.1.
-
- A property set is a set of properties (i.e. a
- collection without dublicates), for instance:
- <toolset>gcc <runtime-link>static.
-
- A property path is a property set whose elements have
- been joined into a single string separated by slashes. A property
- path representation of the previous example would be
- <toolset>gcc/<runtime-link>static.
-
- A build specification is a property set which fully
- describes the set of features used to build a target.
-
-
-
- Property Validity
-
-
- For free
- features, all values are valid. For all other features,
- the valid values are explicitly specified, and the build
- system will report an error for the use of an invalid
- feature-value. Subproperty validity may be restricted so
- that certain values are valid only in the presence of
- certain other subproperties. For example, it is possible
- to specify that the <gcc-target>mingw
- property is only valid in the presence of
- <gcc-version>2.95.2.
-
-
-
-
- Feature Attributes
-
- Each feature has a collection of zero or more of the following
- attributes. Feature attributes are low-level descriptions of how
- the build system should interpret a feature's values when they
- appear in a build request. We also refer to the attributes of
- properties, so that a incidental property, for example, is
- one whose feature is has the incidental attribute.
-
-
-
- incidental
-
- Incidental features are assumed not to affect build
- products at all. As a consequence, the build system may use
- the same file for targets whose build specification differs
- only in incidental features. A feature which controls a
- compiler's warning level is one example of a likely
- incidental feature.
-
- Non-incidental features are assumed to affect build
- products, so the files for targets whose build specification
- differs in non-incidental features are placed in different
- directories as described in "target paths" below. [ where? ]
-
-
-
-
-
-
- propagated
-
-
- Features of this kind are
- propagated to dependencies. That is, if a main target is built using a
- propagated
- property, the build systems attempts to use the same property
- when building any of its dependencies as part of that main
- target. For instance, when an optimized exectuable is
- requested, one usually wants it to be linked with optimized
- libraries. Thus, the <optimization> feature is
- propagated.
-
-
-
-
-
- free
-
-
- Most features have a finite set of allowed values, and can
- only take on a single value from that set in a given build
- specification. Free features, on the other hand, can have
- several values at a time and each value can be an arbitrary
- string. For example, it is possible to have several
- preprocessor symbols defined simultaneously:
-
-
-<define>NDEBUG=1 <define>HAS_CONFIG_H=1
-
-
-
-
-
- optional
-
- An optional feature is a feature which is not required to
- appear in a build specification. Every non-optional non-free
- feature has a default value which is used when a value for
- the feature is not otherwise specified, either in a target's
- requirements or in the user's build request. [A feature's
- default value is given by the first value listed in the
- feature's declaration. -- move this elsewhere - dwa]
-
-
-
- symmetric
-
- A symmetric feature's default value is not automatically
- included in build variants. Normally
- a feature only generates a subvariant directory when its
- value differs from the value specified by the build variant,
- leading to an assymmetric subvariant directory structure for
- certain values of the feature. A symmetric feature, when
- relevant to the toolset, always generates a corresponding
- subvariant directory.
-
-
-
- path
-
- The value of a path feature specifies a path. The path is
- treated as relative to the directory of Jamfile where path
- feature is used and is translated appropriately by the build
- system when the build is invoked from a different
- directory
-
-
-
- implicit
-
- Values of implicit features alone identify the feature.
- For example, a user is not required to write
- "<toolset>gcc", but can simply write "gcc". Implicit
- feature names also don't appear in variant paths, although
- the values do. Thus: bin/gcc/... as opposed to
- bin/toolset-gcc/.... There should typically be only a few
- such features, to avoid possible name clashes.
-
-
-
- composite
-
- Composite features actually correspond to groups of
- properties. For example, a build variant is a composite
- feature. When generating targets from a set of build
- properties, composite features are recursively expanded and
- added to the build property set, so rules can find
- them if neccessary. Non-composite non-free features override
- components of composite features in a build property set.
-
-
-
- link-incompatible
-
- See below.
-
-
-
- dependency
-
- The value of dependency feature if a target reference.
- When used for building of a main target, the value of
- dependency feature is treated as additional dependency.
-
- For example, dependency features allow to state that
- library A depends on library B. As the result, whenever an
- application will link to A, it will also link to B.
- Specifying B as dependency of A is different from adding B to
- the sources of A.
-
-
-
- Features which are neither free nor incidental are called
- base features.
-
- TODO: document active features..
-
-
-
- Feature Declaration
-
- The low-level feature declaration interface is the
- feature rule from the
- feature module:
-
-
-rule feature ( name : allowed-values * : attributes * )
-
-
- A feature's allowed-values may be extended wit The build
-system will provide high-level rules which define features in terms
-of valid and useful combinations of attributes.
-
-
-
-
-
-
- Build Variants
-
-
-A build variant, or (simply variant) is a special kind of composite
- feature which automatically incorporates the default values of
- features that . Typically you'll want at least two separate
- variants: one for debugging, and one for your release code. [
- Volodya says: "Yea, we'd need to mention that it's a composite
- feature and describe how they are declared, in pacticular that
- default values of non-optional features are incorporated into
- build variant automagically. Also, do we wan't some variant
- inheritance/extension/templates. I don't remember how it works in
- V1, so can't document this for V2.". Will clean up soon -DWA ]
-
-
-
- Link compatible and incompatible properties
-
- 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.
-
- The build request can originate in many ways: it may come
- directly from the user's command-line, from a dependency of a
- main target upon a library, or from a dependency of a target upon
- an executable used to build that target, for example. For each
- way, there are different rules whether we can use a given
- subvariant or not. The current rules are described below.
-
- 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.
-
- When building of a main target is requested from a command
- line or some project, link-compatibility is not considered. When
- building is requested by other main target, via sources or
- dependency properties, the requested and actual property sets
- must be link-compatible, otherwise a warning is produced.
-
- Rationale:Link-compatibility is not considered when
- main target is requested by a project, because it causes problems
- in practice. For example, some parts of a project might be
- single-threaded, while others — multi-threaded. They are
- not link-compatible, but they are not linked, either. So, there's
- no need to issue error or warning. The errors used to be
- generated, and only caused problems.
-
-
-
- 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
-
-
-
-
- If original properties and required properties are not
- link-compatible, refinement fails.
-
-
-
-
-
- Each property in the required set is added to the original
- property set
-
-
-
-
-
- If the original property set includes property with a different
- value of non free feature, that property is removed.
-
-
-
-
-
-
- Conditional properties
-
- Sometime it's desirable to apply certain requirements only for
- specific combination of other properties. For example, one of
- compilers that you use issues a poinless warning that you want to
- suppress by passing a command line option to it. You would not
- want to pass that option to other compilers. Condititional
- properties allow to do that. Their systax is:
-
-
-property ( "," property ) * ":" property
-
-
-
-For example, the problem above would be solved by:
-
-
-exe hello : hello.cpp : <toolset>yfc:<cxxflags>-disable-pointless-warning ;
-
-
-
-
-
-
-
- Initialization
-
- bjam's first job upon startup is to load the Jam code which
- implements the build system. To do this, it searches for a file
- called "boost-build.jam", first in the invocation directory, then
- in its parent and so forth up to the filesystem root, and finally
- in the directories specified by the environment variable
- BOOST_BUILD_PATH. When found, the file is interpreted, and should
- specify the build system location by calling the boost-build
- rule:
-
-
-rule boost-build ( location ? )
-
-
-
-If location is a relative path, it is treated as relative to
-the directory of boost-build.jam. The directory specified by
-location and directories in BOOST_BUILD_PATH are then searched for
-a file called bootstrap.jam which is interpreted and is expected to
-bootstrap the build system. This arrangement allows the build
-system to work without any command-line or environment variable
-settings. For example, if the build system files were located in a
-directory "build-system/" at your project root, you might place a
-boost-build.jam at the project root containing:
-
-
-boost-build build-system ;
-
-
-In this case, running bjam anywhere in the project tree will
-automatically find the build system.
-
- The default "bootstrap.jam", after loading some standard
- definitions, loads two files, which can be provided/customised by
- user: "site-config.jam" and "user-config.jam".
-
- Locations where those files a search are summarized below:
-
-
-
-
-Boost.Build comes with default versions of those files,
- which can serve as templates for customized versions.
-
-
-
-
- Command line
-
- The command line may contain:
-
-
- Jam options,
-
- Boost.Build options,
-
- Command line arguments
-
-
-
- Command line arguments
-
-
- Command line arguments specify targets and build
- request using the following rules.
-
-
-
-
-
- An argument which does not contain slashes or the "="
- symbol is either a value of an implicit feature, or target to
- be built. It is taken to be value of a feature if appropriate
- feature exists. Otherwise, it is considered a target id. Special target name "clean"
- has the same effect as "--clean" option.
-
-
-
-
-
- An argument with either slashes or the "=" symbol specifies
- a number of build
- request
- elements. In the simplest form, it's just a set of properties,
- separated by slashes, which become a single build request
- element, for example:
-
-
-borland/<runtime-link>static
-
-
-More complex form is used to save typing. For example,
-instead of
-
-
-borland/runtime-link=static borland/runtime-link=dynamic
-
-
-one can use
-
-
-borland/runtime-link=static,dynamic
-
-
-Exactly, the conversion from argument to build request
-elements is performed by (1) splitting the argument at each slash,
-(2) converting each split part into a set of properties and (3)
-taking all possible combination of the property sets. Each split
-part should have the either the form
-
-
-feature-name=feature-value1[","feature-valueN]*
-
-
-or, in case of implict feature
-
-
-feature-value1[","feature-valueN;]*
-
-
-and will be converted into property set
-
-
-<feature-name>feature-value1 .... <feature-name>feature-valueN
-
-
-
-
-
-
-
-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.
-
-
-
-
- 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
-
-
-
-
-
- --version
-
- Prints information on Boost.Build and Boost.Jam
- versions.
-
-
-
- --help
-
- Access to the online help system. This prints general
- information on how to use the help system with additional
- --help* options.
-
-
-
- --clean
-
- Removes everything instead of building. Unlike
- clean target in make, it is possible to clean only
- some targets.
-
-
-
- --debug
-
- Enables internal checks.
-
-
-
- --dump-projects
-
- Cause the project structure to be output.
-
-
-
- --no-error-backtrace
-
- Don't print backtrace on errors. Primary usefull for
- testing.
-
-
-
- --ignore-config
-
- Do not load site-config.jam and
- user-config.jam
-
-
-
-
-
-
-
-
-
- Build request
-
-
-
-
-
- Build process
-
- Construction of each main target begins with finding
- properties for this main target. They are found by
- processing both build request, and target requirements,
- which give properties needed for the target to build. For
- example, a given main target might require certian defines, or
- will not work unless compiled in multithreaded mode. The process
- of finding properties for main target is described in property refinement.
-
- After that, dependencies (i.e. other main targets) are build
- recursively. Build request for dependencies is not always equal
- to those of dependent — certain properties are dropped and
- user can explicitly specify desired properties for dependencies.
- See
- propagated features and for details.
-
- When dependencies are constructed, the dependency graph for
- this main target and for this property set is created, which
- describes which files need to be created, on which other files
- they depend and what actions are needed to construct those files.
- There's more that one method, and user can define new ones, but
- usually, this involves generators and target
- types.
-
- Target type is just a way to classify targets. For example,
- there are builtin types EXE, OBJ and
- CPP. Generators are objects
- that know how to convert between different target type. When a
- target of a given type must be created, all generators for that
- type, which can handle needed properties, are found. Each is
- passed the list of sources, and either fails, or returns a
- dependency graph. If a generator cannot produce desired type from
- given sources, it may try to recursively construct types that it
- can handle from the types is was passed. This allows to try all
- possible transformations. When all generators are tried, a
- dependency graph is selected.
-
- Finally, the dependency graph is passed to underlying
- Boost.Jam program, which runs all actions needed to bring all
- main targets up-to date. At this step, implicit dependencies are
- also scanned and accounted for, as described "here." [ link? ]
-
- Given a list of targets ids and a build request, building goes
- this way. First, for each id we obtain the abstract targets
- corresponding to it. This also loads all necessary projects. If
- no target id is given, project in the current directory is used.
- Build request is expanded, and for each resulting property set,
- the generate method of all targets is called, which
- yields a list of virtual targets. After that all virtual targets
- are actualized, and target "all" is set to depend on all created
- actual targets. Lastly, depending on whether --clean
- option was given, either target "all" or target "clean" is
- updated. Generation of virtual target from abstract one is
- performed as follows:
-
-
-
- For project targets, all of main targets are generated
- with the same properties. Then all projects referred via
- "build-project" are generated as well. If it's not possible
- to refine requested properties with project requirements, the
- project is skipped.
-
-
- It is possible to disable building of certain target using the
- explicit rule, available in all project
- modules. The syntax is
-
-
-rule explicit ( target-name )
-
-
- If this rule is invoked on a target, it will be built only
-when it's explicitly requested on the command line.
-
-
-
-
-
- For main target, with several alternatives, one of them is
- selected as described below.
- If there's only one
- alternative, it's used unconditionally.
-
-
-
-
- All main target alternatives which requirements are
- satisfied by the build request are enumerated.
-
-
-
-
-
- If there are several such alternatives, the one which
- longer requirements list is selected.
-
-
-
-
-
-
-
-
- For the selected alternative
-
-
-
-
- Each target reference in the source list are
- recursively constructed.
-
-
-
-
-
- Properties are refined with alternative's requirements,
- and active features in the resulting set are executed.
-
-
-
-
-
- Conditional properties are evaluated.
-
-
-
-
-
- The dependency graph for the target is constructed in a
- way which depends on the kind of main target, typically
- using generators.
-
-
-
-
-
-
-
-
- If, when building sources, the properties on recursively
- created targets are not link-compatibile with build properties,
- a warning is issued.
-
-
-
-
-
-
-
- Alternative selection
-
- When there are several alternatives, one of them must be
- selected. The process is as follows:
-
-
-
-
- For each alternative condition is defined
- as the set of base properies in requirements. [Note: it might be
- better to explicitly specify the condition explicitly, as in
- conditional requirements].
-
-
-
-
-
- An alternative is viable only if all properties in condition
- are present in build request.
-
-
-
-
-
- If there's one viable alternative, it's choosen. Otherwise,
- an attempt is made to find one best alternative. An alternative
- a is better than another alternative b, iff set of properties
- in b's condition is stict subset of the set of properities of
- 'a's condition. If there's one viable alternative, which is
- better than all other, it's selected. Otherwise, an error is
- reported.
-
-
-
-
-
-
-
- Generated headers
-
- Usually, Boost.Build handles implicit dependendies completely
- automatically. For example, for C++ files, all #include
- statements are found and handled. The only aspect where user help
- might be needed is implicit dependency on generated files.
-
- By default, Boost.Build handles such dependencies within one
- main target. For example, assume that main target "app" has two
- sources, "app.cpp" and "parser.y". The latter source is converted
- into "parser.c" and "parser.h". Then, if "app.cpp" includes
- "parser.h", Boost.Build will detect this dependency. Moreover,
- since "parser.h" will be generated into a build directory, the
- path to that directory will automatically added to include
- path.
-
- Making this mechanism work across main target boundaries is
- possible, but imposes certain overhead. For that reason, if
- there's implicit dependency on files from other main targets, the
- <implicit-dependency> [ link ] feature must
- be used, for example:
-
-
-lib parser : parser.y ;
-exe app : app.cpp : <implicit-dependency>parser ;
-
-
-
-The above example tells the build system that when scanning
-all sources of "app" for implicit-dependencies, it should consider
-targets from "parser" as potential dependencies.
-
-
-
-
- Generators
-
- To construct a main target with given properties from sources,
- it is required to create a dependency graph for that main target,
- which will also include actions to be run. The algorithm for
- creating the dependency graph is described here.
-
- The fundamental concept is generator. If encapsulates
- the notion of build tool and is capable to converting a set of
- input targets into a set of output targets, with some properties.
- Generator matches a build tool as closely as possible: it works
- only when the tool can work with requested properties (for
- example, msvc compiler can't work when requested toolset is gcc),
- and should produce exactly the same targets as the tool (for
- example, if Borland's linker produces additional files with debug
- information, generator should also).
-
- Given a set of generators, the fundamental operation is to
- construct a target of a given type, with given properties, from a
- set of targets. That operation is performed by rule
- generators.construct and the used algorithm is described
- below.
-
-
- Selecting and ranking viable generators
-
- Each generator, in addition to target types that it can
- produce, have attribute that affects its applicability in
- particular sitiation. Those attributes are:
-
-
-
-
- Required properties, which are properties absolutely
- necessary for the generator to work. For example, generator
- encapsulating the gcc compiler would have <toolset>gcc as
- required property.
-
-
-
-
-
- Optional properties, which increase the generators
- suitability for a particual build.
-
-
-
-
-
- Generator's required and optional properties may not include
- either free or incidental properties. (Allowing this would
- greatly complicate caching targets).
-
-
- When trying to construct a target, the first step is to select
- all possible generators for the requested target type, which
- required properties are a subset of requested properties.
- Generators which were already selected up the call stack are
- excluded. In addition, if any composing generators were selected
- up the call stack, all other composing generators are ignored
- (TODO: define composing generators). The found generators
- assigned a rank, which is the number of optional properties
- present in requested properties. Finally, generators with highest
- rank are selected for futher processing.
-
-
-
- Running generators
-
- When generators are selected, each is run to produce a list of
- created targets. This list might include targets which are not of
- requested types, because generators create the same targets as
- some tool, and tool's behaviour is fixed. (Note: should specify
- that in some cases we actually want extra targets). If generator
- fails, it returns an empty list. Generator is free to call
- 'construct' again, to convert sources to the types it can handle.
- It also can pass modified properties to 'constuct'. However, a
- generator is not allowed to modify any propagated properties,
- otherwise when actually consuming properties we might discover
- that the set of propagated properties is different from what was
- used for building sources.
-
- For all targets which are not of requested types, we try to
- convert them to requested type, using a second call to
- construct. This is done in order to support
- transformation sequences where single source file expands to
- several later. See this
- message for details.
-
-
-
-
- Selecting dependency graph
-
-
- After all generators are run,
- it is necessary to decide which of successfull invocation will be
- taken as final result. At the moment, this is not done. Instead,
- it is checked whether all successfull generator invocation
- returned the same target list. Error is issued otherwise.
-
-
-
-
-
- Property adjustment
-
- Because target location is determined by the build system, it
- is sometimes necessary to adjust properties, in order to not
- break actions. For example, if there's an action which generates
- a header, say "a_parser.h", and a source file "a.cpp" which
- includes that file, we must make everything work as if a_parser.h
- is generated in the same directory where it would be generated
- without any subvariants.
-
- Correct property adjustment can be done only after all targets
- are created, so the approach taken is:
-
-
-
-
- When dependency graph is constructed, each action can be
- assigned a rule for property adjustment.
-
-
-
-
-
- When virtual target is actualized, that rule is run and
- return the final set of properties. At this stage it can use
- information of all created virtual targets.
-
-
-
-
- In case of quoted includes, no adjustment can give 100%
- correct results. If target dirs are not changed by build system,
- quoted includes are searched in "." and then in include path,
- while angle includes are searched only in include path. When
- target dirs are changed, we'd want to make quoted includes to be
- search in "." then in additional dirs and then in the include
- path and make angle includes be searched in include path,
- probably with additional paths added at some position. Unless,
- include path already has "." as the first element, this is not
- possible. So, either generated headers should not be included
- with quotes, or first element of include path should be ".",
- which essentially erases the difference between quoted and angle
- includes. Note: there only way to get "." as include path
- into compiler command line is via verbatim compiler option. In
- all other case, Boost.Build will convert "." into directory where
- it occurs.
-
-
-
-
- Transformations cache
-
-
- Under certain conditions, an
- attempt is made to cache results of transformation search. First,
- the sources are replaced with targets with special name and the
- found target list is stored. Later, when properties, requested
- type, and source type are the same, the store target list is
- retrieved and cloned, with appropriate change in names.
-
-
-
-
-
-
-
-
- Boost.Build development
-
- [ TODO ]
-
-
-
- Frequently Asked Questions
-
-
- I'm getting "Duplicate name of actual target" error.
- What does it mean?
-
-
-
- The most likely case is that you're trying to
- compile the same file twice, with almost the same,
- but differing properties. For example:
-
-
-exe a : a.cpp : <include>/usr/local/include ;
-exe b : a.cpp ;
-
-
-
-
-
- The above snippet requires two different compilations
- of 'a.cpp', which differ only in 'include' property.
- Since the 'include' property is free, Boost.Build
- can't generate two ojects files into different directories.
- On the other hand, it's dangerous to compile the file only
- once -- maybe you really want to compile with different
- includes.
-
-
-
- To solve this issue, you need to decide if file should
- be compiled once or twice.
-
-
-
- Two compile file only once, make sure that properties
- are the same:
-
-
-exe a : a.cpp : <include>/usr/local/include ;
-exe b : a.cpp : <include>/usr/local/include ;
-
-
-
- If changing the properties is not desirable, for example
- if 'a' and 'b' target have other sources which need
- specific properties, separate 'a.cpp' into it's own target:
-
-
-obj a_obj : a.cpp : <include>/usr/local/include ;
-exe a : a_obj ;
-
-
-
- To compile file twice, you can make the object file local
- to the main target:
-
-
- exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ;
- exe b : [ obj a_obj : a.cpp ] ;
-
-
-
-
- A good question is why Boost.Build can't use some of the above
- approaches automatically. The problem is that such magic would
- require additional implementation complexities and would only
- help in half of the cases, while in other half we'd be silently
- doing the wrong thing. It's simpler and safe to ask user to
- clarify his intention in such cases.
-
-
-
-
-
-
-
-
- Extender Manual
-
-
- Introduction
-
- This document explains how to extend Boost.Build to accomodate
- your local requirements. Let's start with quite simple, but
- realistic example.
-
- Say you're writing an application which generates C++ code. If
- you ever did this, you know that it's not nice. Embedding large
- portions of C++ code in string literals is very awkward. A much
- better solution is:
-
-
-
-
- Write the template of the code to be generated, leaving
- placeholders at the points which will change
-
-
-
-
-
- Access the template in your application and replace
- placeholders with appropriate text.
-
-
-
-
- Write the result.
-
-
-
- It's quite easy to archive. You write special verbatim files,
- which are just C++, except that the very first line of the file
- gives a name of variable that should be generated. A simple tool
- is created which takes verbatim file and creates a cpp file with
- a single char* variable, which name is taken from the first line
- of verbatim file, and which value is properly quoted content of
- the verbatim file.
-
- Let's see what Boost.Build can do.
-
- First off, Boost.Build has no idea about "verbatim files". So,
- you must register a new type. The following code does it:
-
-
-import type ;
-type.register VERBATIM : verbatim ;
-
-
- The first parameter to 'type.register' gives the name of
- declared type. By convention, it's uppercase. The second
- parameter is suffix for this type. So, if Boost.Build sees
- "code.verbatim" in the list of sources, it knows that it's of
- type VERBATIM.
-
- Lastly, you need a tool to convert verbatim files to C++. Say
- you've sketched such a tool in Python. Then, you have to inform
- Boost.Build about the tool. The Boost.Build concept which
- represents a tool is generator.
-
- First, you say that generator 'inline-file' is able to convert
- VERBATIM type into C++:
-
-
-import generators ;
-generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
-
-
- Second, you must specify the commands to be run to actually
- perform convertion:
-
-
-actions inline-file
-{
- "./inline-file.py" $(<) $(>)
-}
-
-
-
- Now, we're ready to tie it all together. Put all the code
- above in file "verbatim.jam", add "import verbatim ;" to
- "project-root.jam", and it's possible to write the following in
- Jamfile:
-
-
-exe codegen : codegen.cpp class_template.verbatim usage.verbatim ;
-
-
-
-The verbatim files will be automatically converted into C++
-and linked it.
-
-
- The complete code is available in example/customization
- directory.
-
-
-
- Target types
-
-
-
-
- Tools
-
-
-
-
- Main target rules
-
-
-
-
- Scanners
-
-
-
-
-
- Boost Build System V2 recipes
-
-
- Targets in site-config.jam
-
- It is desirable to declare standard libraries available on a
- given system. Putting target declaration in Jamfile is not really
- good, since locations of the libraries can vary. The solution is
- to put the following to site-config.jam.
-
-
-import project ;
-project.initialize $(__name__) ;
-project site-config ;
-lib zlib : : <name>z ;
-
-
- The second line allows this module to act as project. The
- third line gives id to this project — it really has no location
- and cannot be used otherwise. The fourth line just declares a
- target. Now, one can write
-
-
-exe hello : hello.cpp /site-config//zlib ;
-
-
- in any Jamfile.
-
-
-
-
-
- Boost.Build v2 architecture
-
-
- This document is work-in progress. Don't expect much from it
- yet.
-
-
-
- Targets
-
- There are two user-visible kinds of targets in Boost.Build.
- First are "abstract" — they correspond to things declared
- by user, for example, projects and executable files. The primary
- thing about abstract target is that it's possible to request them
- to be build with a particular values of some properties. Each
- combination of properties may possible yield different set of
- real file, so abstract target do not have a direct correspondence
- with files.
-
- File targets, on the contary, are associated with concrete
- files. Dependency graphs for abstract targets with specific
- properties are constructed from file targets. User has no was to
- create file targets, however it can specify rules that detect
- file type for sources, and also rules for transforming between
- file targets of different types. That information is used in
- constructing dependency graph, as desribed in the "next section".
- [ link? ] Note:File targets are not
- the same as targets in Jam sense; the latter are created from
- file targets at the latest possible moment. Note:"File
- target" is a proposed name for what we call virtual targets. It
- it more understandable by users, but has one problem: virtual
- targets can potentially be "phony", and not correspond to any
- file.
-
-
- Dependency scanning
-
- Dependency scanning is the process of finding implicit
- dependencies, like "#include" statements in C++. The requirements
- for right dependency scanning mechanism are:
-
-
-
-
- Support for different scanning algorithms. C++ and XML have
- quite different syntax for includes and rules for looking up
- included files.
-
-
-
-
-
- Ability to scan the same file several times. For example,
- single C++ file can be compiled with different include
- paths.
-
-
-
-
-
- Proper detection of dependencies on generated files.
-
-
-
-
-
- Proper detection of dependencies from generated file.
-
-
-
-
-
- Support for different scanning algorithms
-
- Different scanning algorithm are encapsulated by objects
- called "scanners". Please see the documentation for "scanner"
- module for more details.
-
-
-
-
- Ability to scan the same file several times
-
- As said above, it's possible to compile a C++ file twice, with
- different include paths. Therefore, include dependencies for
- those compilations can be different. The problem is that bjam
- does not allow several scans of the same target.
-
- The solution in Boost.Build is straigtforward. When a virtual
- target is converted to bjam target (via
- virtual-target.actualize method), we specify the scanner
- object to be used. The actualize method will create different
- bjam targets for different scanners.
-
- All targets with specific scanner are made dependent on target
- without scanner, which target is always created. This is done in
- case the target is updated. The updating action will be
- associated with target without scanner, but if sources for that
- action are touched, all targets — with scanner and without
- should be considered outdated.
-
- For example, assume that "a.cpp" is compiled by two compilers
- with different include path. It's also copied into some install
- location. In turn, it's produced from "a.verbatim". The
- dependency graph will look like:
-
-
-a.o (<toolset>gcc) <--(compile)-- a.cpp (scanner1) ----+
-a.o (<toolset>msvc) <--(compile)-- a.cpp (scanner2) ----|
-a.cpp (installed copy) <--(copy) ----------------------- a.cpp (no scanner)
- ^
- |
- a.verbose --------------------------------+
-
-
-
-
- Proper detection of dependencies on generated files.
-
- This requirement breaks down to the following ones.
-
-
-
-
- If when compiling "a.cpp" there's include of "a.h", the
- "dir" directory is in include path, and a target called "a.h"
- will be generated to "dir", then bjam should discover the
- include, and create "a.h" before compiling "a.cpp".
-
-
-
-
-
- Since almost always Boost.Build generates targets to a
- "bin" directory, it should be supported as well. I.e. in the
- scanario above, Jamfile in "dir" might create a main target,
- which generates "a.h". The file will be generated to "dir/bin"
- directory, but we still have to recornize the dependency.
-
-
-
-
- The first requirement means that when determining what "a.h"
- means, when found in "a.cpp", we have to iterate over all
- directories in include paths, checking for each one:
-
-
-
-
- If there's file "a.h" in that directory, or
-
-
-
-
-
- If there's a target called "a.h", which will be generated
- to that directory.
-
-
-
-
- Classic Jam has built-in facilities for point (1) above, but
- that's not enough. It's hard to implement the right semantic
- without builtin support. For example, we could try to check if
- there's targer called "a.h" somewhere in dependency graph, and
- add a dependency to it. The problem is that without search in
- include path, the semantic may be incorrect. For example, one can
- have an action which generated some "dummy" header, for system
- which don't have the native one. Naturally, we don't want to
- depend on that generated header on platforms where native one is
- included.
-
- There are two design choices for builtin support. Suppose we
- have files a.cpp and b.cpp, and each one includes header.h,
- generated by some action. Dependency graph created by classic jam
- would look like:
-
-
-a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
-
-
- <d2>header.h --------> header.y
- [generated in d2]
-
-b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4]
-
-
-
-In this case, Jam thinks all header.h target are not
-realated. The right dependency graph might be:
-
-
-a.cpp ----
- \
- \
- >----> <d2>header.h --------> header.y
- / [generated in d2]
- /
-b.cpp ----
-
-
-or
-
-
-a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
- |
- (includes)
- V
- <d2>header.h --------> header.y
- [generated in d2]
- ^
- (includes)
- |
-b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4]
-
-
-
-
-The first alternative was used for some time. The problem
-however is: what include paths should be used when scanning
-header.h? The second alternative was suggested by Matt Armstrong.
-It has similiar effect: add targets which depend on
-<scanner1>header.h will also depend on <d2>header.h.
-But now we have two different target with two different scanners,
-and those targets can be scanned independently. The problem of
-first alternative is avoided, so the second alternative is
-implemented now.
-
-
- The second sub-requirements is that targets generated to "bin"
- directory are handled as well. Boost.Build implements
- semi-automatic approach. When compiling C++ files the process
- is:
-
-
-
-
- The main target to which compiled file belongs is found.
-
-
-
-
-
- All other main targets that the found one depends on are
- found. Those include main target which are used as sources, or
- present as values of "dependency" features.
-
-
-
-
-
- All directories where files belonging to those main target
- will be generated are added to the include path.
-
-
-
-
- After this is done, dependencies are found by the approach
- explained previously.
-
- Note that if a target uses generated headers from other main
- target, that main target should be explicitly specified as
- dependency property. It would be better to lift this requirement,
- but it seems not very problematic in practice.
-
- For target types other than C++, adding of include paths must
- be implemented anew.
-
-
-
- Proper detection of dependencies from generated files
-
- Suppose file "a.cpp" includes "a.h" and both are generated by
- some action. Note that classic jam has two stages. In first stage
- dependency graph graph is build and actions which should be run
- are determined. In second stage the actions are executed.
- Initially, neither file exists, so the include is not found. As
- the result, jam might attempt to compile a.cpp before creating
- a.h, and compilation will fail.
-
- The solution in Boost.Jam is to perform additional dependency
- scans after targets are updated. This break separation between
- build stages in jam — which some people consider a good
- thing — but I'm not aware of any better solution.
-
- In order to understand the rest of this section, you better
- read some details about jam dependency scanning, available
-
- at this link.
-
- Whenever a target is updated, Boost.Jam rescans it for
- includes. Consider this graph, created before any actions are
- run.
-
-
-A -------> C ----> C.pro
- /
-B --/ C-includes ---> D
-
-
-
-Both A and B have dependency on C and C-includes (the latter
-dependency is not shown). Say during building we've tried to create
-A, then tried to create C and successfully created C.
-
-
- In that case, the set of includes in C might well have
- changed. We do not bother to detect precisely which includes were
- added or removed. Instead we create another internal node
- C-includes-2. Then we determine what actions should be run to
- update the target. In fact this mean that we perform logic of
- first stage while already executing stage.
-
- After actions for C-includes-2 are determined, we add
- C-includes-2 to the list of A's dependents, and stage 2 proceeds
- as usual. Unfortunately, we can't do the same with target B,
- since when it's not visited, C target does not know B depends on
- it. So, we add a flag to C which tells and it was rescanned. When
- visiting B target, the flag is notices and C-includes-2 will be
- added to the list of B's dependencies.
-
- Note also that internal nodes are sometimes updated too.
- Consider this dependency graph:
-
-
-a.o ---> a.cpp
- a.cpp-includes --> a.h (scanned)
- a.h-includes ------> a.h (generated)
- |
- |
- a.pro <-------------------------------------------+
-
-
- Here, out handling of generated headers come into play. Say
- that a.h exists but is out of date with respect to "a.pro", then
- "a.h (generated)" and "a.h-includes" will be marking for
- updating, but "a.h (scanned)" won't be marked. We have to rescan
- "a.h" file after it's created, but since "a.h (generated)" has no
- scanner associated with it, it's only possible to rescan "a.h"
- after "a.h-includes" target was updated.
-
- Tbe above consideration lead to decision that we'll rescan a
- target whenever it's updated, no matter if this target is
- internal or not.
-
-
-
- The remainder of this document is not indended to be read at
- all. This will be rearranged in future.
-
-
-
-
- File targets
-
-
- As described above, file targets corresponds
- to files that Boost.Build manages. User's may be concerned about
- file targets in three ways: when declaring file target types,
- when declaring transformations between types, and when
- determining where file target will be placed. File targets can
- also be connected with actions, that determine how the target is
- created. Both file targets and actions are implemented in the
- virtual-target module.
-
-
-
- Types
-
- A file target can be given a file, which determines
- what transformations can be applied to the file. The
- type.register rule declares new types. File type can
- also be assigned a scanner, which is used to find implicit
- dependencies. See "dependency scanning" [ link? ] below.
-
-
-
-
- Target paths
-
- To distinguish targets build with different properties, they
- are put in different directories. Rules for determining target
- paths are given below:
-
-
-
-
- All targets are placed under directory corresponding to the
- project where they are defined.
-
-
-
-
-
- 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].
-
-
-
-
-
- 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
-
-
-
-
-
-
-
-
-