diff --git a/v2/doc/src/advanced.xml b/v2/doc/src/advanced.xml
index 9fd2e7ae2..e455247b3 100644
--- a/v2/doc/src/advanced.xml
+++ b/v2/doc/src/advanced.xml
@@ -176,7 +176,7 @@ using gcc : 3.4 : : <compileflags>-m64 <linkflags>-m64 ;
In addition to Jamfiles, Boost.Build has another user-editable
- file, project-root.jam, which is mostly usefull to declare constants
+ file, project-root.jam, which is mostly useful to declare constants
global to all the projects. It is described in more detail below.
@@ -355,8 +355,15 @@ function-name main-target-name
- Some main target rules have shorter list of parameters, and
- you should consult their documentation for details.
+ Note that the actual requirements, default-build and
+ usage-requirements attributes for a target are obtained by combining
+ the explicitly specified one with those specified for the project
+ where a target is declared.
+
+
+ Some main target rules have shorter list of parameters, and
+ you should consult their documentation for details.
+ The list of sources specifies what should be processed to get
the resulting targets. Most of the time, it's just a list of
@@ -402,6 +409,60 @@ exe c : c.cpp /boost/program_options//program_opions ;
necessary for this main target.
-->
+ Requirements are the properties that should always be present when
+ building a target. Typically, they are includes and defines:
+
+exe hello : hello.cpp : <include>/opt/boost <define>MY_DEBUG ;
+
+ In special circumstances, other properties can be used, for example if
+ a library does not work if it's shared, or a file can't be compiled
+ with optimization due to a compiler bug, one can use
+
+lib util : util.cpp : <link>static ;
+obj main : main.cpp : <optimization>off ;
+
+
+
+ Sometimes, requirements are necessary only for a specific
+ compiler, or build variant. The
+ conditional
+ properties can be used in that case:
+
+lib util : util.cpp : <toolset>msvc:<link>static ;
+
+ In means when whenever <toolset>msvc property is
+ in build properties, the <link>static property will
+ be included as well. The conditional requirements can be "chained":
+
+lib util : util.cpp : <toolset>msvc:<link>static
+ <link>static:<define>STATIC_LINK ;
+
+ will set of static link and the STATIC_LINK define on the
+ msvc toolset.
+
+
+ The default-build attribute is
+ a set of properties which should be used if build request does not
+ specify a value. For example:
+
+exe hello : hello.cpp : : <threading>multi ;
+
+ would build the target in multi-threaded mode, unless the user
+ explicitly requests single-threaded version. The difference between
+ requirements and default-build is that requirements cannot be
+ overriden in any way.
+
+
+ A target of the same name can be declared several times. In that
+ case is declaration is called an
+ alternative. When the target is build, one of
+ the alternatives will be selected and use. Alternatives need not be
+ defined by the same main target rule. The following is OK:
+
+lib helpers : helpers.hpp ;
+alias helpers : helpers.lib : <toolset>msvc ;
+
+ Building of the same main target can differ greatly from
platform to platform. For example, you might have different list
@@ -437,7 +498,7 @@ exe hello : hello.cpp
ProjectsAs mentioned before, targets are grouped into project, and each
- Jamfile is a separate project. Projects are usefull because it allows
+ Jamfile is a separate project. Projects are useful because it allows
to group related targets together, define properties common to all
those targets, and assign a symbolic name to the project, allowing to
easily refer to the targets in the project. Two last goals are
@@ -720,27 +781,135 @@ should be absolute project id.
Build process
- This section will describe two things: how you specify what to build,
- and how the main targets are actually build.
-
+ When you've described your targets, you want Boost.Build to run the
+ right tools and create the needed targets. This section will describe
+ two things: how you specify what to build, and how the main targets are
+ actually constructed.
+
-
- The command line specifies which targets to build and with what
- properties. For example:
+ The most important thing to note is that in Boost.Build, unlike
+ other build tools, the targets you declare do not correspond to specific
+ files. What you declare in Jamfiles is more like "metatarget". Depending
+ on the properties that you specify on the command line, each
+ "metatarget" will produce a set of real targets corresponding to the
+ requested properties. It is quite possible that the same metatarget is
+ build several times with different properties, and will, of course,
+ produce different files.
+
+
+
+ This means that for Boost.Build, you cannot directly obtain build
+ variant from Jamfile. There could be several variants requested by the
+ user, and each target can be build with different properties.
+
+
+
+
+ Build request
+
+
+ The command line specifies which targets to build and with what
+ properties. For example:
bjam app1 lib1//lib1 toolset=gcc variant=debug optimization=full
- would build two targets, "app1" and "lib1//lib1" with the specified
- properties. You can refer to any targets, using
- target id and specify arbitrary
- properties. Some of the properties are very common, and for them the name
- of the property can be omitted. For example, the above can be written as:
+ would build two targets, "app1" and "lib1//lib1" with the specified
+ properties. You can refer to any targets, using
+ target id and specify arbitrary
+ properties. Some of the properties are very common, and for them the name
+ of the property can be omitted. For example, the above can be written as:
bjam app1 lib1//lib1 gcc debug optimization=full
- The complete syntax which has some additional shortcuts if described here.
-
+ The complete syntax which has some additional shortcuts if described here.
+
+
+
+ Building a main target
+
+ When you request, directly or indirectly, a build of a main target
+ with specific requirements, the following steps are made. Some brief
+ explanation is provided, and more detailes are given in the reference.
+
+
+ Applying default build. If the default-build
+ property of a target specifies a value of a feature which is not
+ present in the build request, that value is added.
+
+ Selecting the main target alternative to use. For
+ each alternative we look how many properties are present both in
+ alternative's requirements, and in build request. The
+ alternative with large number of matching properties is selected.
+
+
+ Determining "common" properties. The build request
+ is refined
+ with target's requirements. The conditional properties in
+ requirements are handled as well. Finally, default values of
+ features are added.
+
+
+ Building targets referred by the sources list and
+ dependency properties. The list of sources and the properties
+ can refer to other target using target references. For each
+ reference, we take all propagated
+ properties, refine them by explicit properties specified in the
+ target reference, and pass the resulting properties as build
+ request to the other target.
+
+
+ Adding the usage requirements produces when building
+ dependencies to the "common" properties. When dependencies are
+ built in the previous step, they return both the set of created
+ "real" targets, and usage requirements. The usage requirements
+ are added to the common properties and the resulting property
+ set will be used for building the current target.
+
+
+ Building the target using generators. To convert the
+ sources to the desired type, Boost.Build uses "generators" ---
+ objects which correspond to tools like compilers and
+ linkers. Each generator declares what type of targets in can
+ produce and what type of sources it requires. Using this
+ information, Boost.Build determines which generators must be run
+ to produce a specific target from specific sources. When
+ generators are run, they return the "real" targets.
+
+
+ Computing the usage requirements to be returned. The
+ conditional properties in usage requirements are expanded and the
+ result is returned.
+
+
+
+
+ Building a project
+
+ Often, user request a build of a complete project, not just one
+ main target. In fact, invoking bjam without
+ parameters builds the project defined in the current directory.
+
+ When a project is build, the build request is passed without
+ modification to all main targets in that project. It's is possible to
+ prevent implicit building of a target in a project with the
+ explicit rule:
+
+explicit hello_test ;
+
+ would cause the hello_test target to be built only if
+ explicitly requested by the user or by some other target.
+
+
+ The Jamfile for a project can include a number of
+ build-project rule calls, that specify additional projects
+ to be built.
+
+
+
@@ -1171,7 +1340,7 @@ unit-test helpers_test : helpers_test.cpp helpers ;
The usage requirements
is also important mechanism to simplify Jamfile. If a library requires
- all clients to use specific includes, or macroses when compiling the
+ all clients to use specific includes, or macros when compiling the
code which depends on the library, this information can be cleanly
represented.
diff --git a/v2/doc/src/extending.xml b/v2/doc/src/extending.xml
index 6cdb1fc55..4fbcb9529 100644
--- a/v2/doc/src/extending.xml
+++ b/v2/doc/src/extending.xml
@@ -296,7 +296,7 @@ generators.register
converted to the right types to actually create the result.
- The generated-target method can be overrided when you
+ The generated-target method can be overridden when you
want to add additional properties to the generated targets or use
additional sources. For example (which is real), you have a tool for
analysing programs, which should be given a name of executable and the
@@ -420,14 +420,19 @@ actions inline-file
- There are two approaches: using a generic
- feature which is passed to the tool, and using a more specific feature
- which is translated to a specific options. For example, with a C++
- compiler it's possible to pass either <cxxflags>-O3
- or <optimization>speed. A generic feature is
- almost always should be defined, to provide a "back door" for the
- user. Specific features, however, are preferred for a couple of
- reasons:
+ There are two ways to control a tool using features. The
+ first is to declare a "generic" feature, which value is passed to the
+ tool without modification. For example, the value of the
+ cxxflags feature ends up in the compiler's command
+ line. Such a generic feature allows the user to get full control and
+ should be always provided when you write a tool.
+
+
+ The second approach is to declare a more specific feature,
+ which is directly translated to specific options. For example,
+ the <optimization>speed property might add
+ -O3 to the compiler's command line. Specific
+ features are preferred over generic for a couple of reasons:
@@ -452,8 +457,10 @@ actions inline-file
Adding a feature requires three steps:
- Declaring a feature. For that, the "feature.feature" rule is used. You
- should have to decide on the set of feature attributes:
+ Declaring a feature. For that, the "feature.feature"
+ rule is used. You should have to decide on the set of feature
+ attributes:
if feature has several values, and
@@ -476,7 +483,7 @@ actions inline-file
Converting the feature value into variable. To use
feature in build action, it must be converted into a variable,
- acessible in build action. This is accomplished by
+ accessible in build action. This is accomplished by
"toolset.flags" rule.
@@ -491,7 +498,7 @@ actions inline-file
Here's an another example.
Let's see how we can make a feature which refers to a target. For example,
- when linking dynamic libraries on windows, one sometimes needs to specific
+ when linking dynamic libraries on windows, one sometimes needs to specify
"DEF file", telling what functions should be exported. It would be nice to
use this file like this:
@@ -588,15 +595,15 @@ feature.compose <parallelism>fake : <library>/mpi//fake/<parallel
Main target rules
The main target rule is what creates a top-level target, for example "exe" or
- "lib". It's quite likely that's you'll want to declare your own and
- there are as much as three way to do that.
+ "lib". It's quite likely that you'll want to declare your own and
+ there are as many as three ways to do that.
The first is the simplest, but is sufficient in a number of
- case. Just write a wrapper rule, which will redirect to any of existing
- rules. For example, you have only one library per directory and want all
- cpp files in the directory to be compiled. You can achieve this effect
- with:
+ cases. Just write a wrapper rule, which will redirect to any of the
+ existing rules. For example, you have only one library per directory and
+ want all cpp files in the directory to be compiled. You can achieve this
+ effect with:
lib codegen : [ glob *.cpp ] ;
@@ -631,7 +638,7 @@ generators.register-standard obfuscate.file : CPP : OBFUSCATED_CPP ;
- The remaining method is to declared your own main target class. The
+ The remaining method is to declare your own main target class. The
simplest example of this can be found in "build/alias.jam" file. The
current V2 uses this method when transformations are relatively
complex. However, we might deprecate this approach. If you find that you
diff --git a/v2/doc/src/faq.xml b/v2/doc/src/faq.xml
index 18132fb51..eebb01402 100644
--- a/v2/doc/src/faq.xml
+++ b/v2/doc/src/faq.xml
@@ -27,7 +27,7 @@ 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.
+ can't generate two objects 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.
@@ -100,7 +100,7 @@ exe a : a_obj ;
need the following code:
import modules ;
-local path = [ modules.peek : SOME_LIBRARY_PATH ] ;
+local SOME_LIBRARY_PATH = [ modules.peek : SOME_LIBRARY_PATH ] ;
exe a : a.cpp : <include>$(SOME_LIBRARY_PATH) ;
@@ -236,7 +236,7 @@ exe a : a.cpp b ;
obj b : b.cpp : <cflags>-g ;
You can also use conditional
- properties to a finer control:
+ properties for finer control:
exe a : a.cpp b ;
obj b : b.cpp : <variant>release:<optimization>off ;
diff --git a/v2/doc/src/install.xml b/v2/doc/src/install.xml
index fc7e18c77..bf23cf5f9 100644
--- a/v2/doc/src/install.xml
+++ b/v2/doc/src/install.xml
@@ -132,10 +132,10 @@ boost-build /path/to/boost.build ;
N.B.
- When bjam is invokedfrom anywhere in the Boost
+ When bjam is invoked from anywhere in the Boost
directory tree other than the Boost.Build root
and its subdirectories, Boost.Build
- v1 is used by default. To overide the default and use
+ v1 is used by default. To override the default and use
Boost.Build v2, you have to add the command
line option to all bjam invocations.
diff --git a/v2/doc/src/reference.xml b/v2/doc/src/reference.xml
index 38a6e7dbb..e764335e4 100644
--- a/v2/doc/src/reference.xml
+++ b/v2/doc/src/reference.xml
@@ -2,296 +2,897 @@
-
- Detailed reference
+
+ Detailed reference
+
+
+ General information
+
+
+ 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 implicit 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 rebuilt 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 useful for
+ testing.
+
+
+
+ --ignore-config
+
+ Do not load site-config.jam and
+ user-config.jam
+
+
+
+
+
+
+
+
+
+
+
+
+ Writing Jamfiles
+
+ This section describes specific information about writing Jamfiles.
+
+
+ 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.
+
+
+
+
+
+
+
+ Build process
+
+ The general overview of the build process was given in the
+ user documentation.
+ This section provides additional details, and some specific rules.
+
+
+ To recap, building a target with specific properties includes the
+ following steps:
+
+
+ applying default build,
+
+ selecting the main target alternative to use,
+
+
+ determining "common" properties
+
+ building targets referred by the sources list and
+ dependency properties
+
+ adding the usage requirements produces when building
+ dependencies to the "common" properties
+
+ building the target using generators
+
+ computing the usage requirements to be returned
+
+
+
+
+
+ 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 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 strict 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.
+
+
+
+
+
+
+
+ Determining common properties
+
+ The "common" properties is a somewhat artificial term. Those are
+ the intermediate property set from which both the build request for
+ dependencies and properties for building the target are derived.
+
+
+ Since default build and alternatives are already handled, we have
+ only two inputs: build requests and requirements. Here are the rules
+ about common properties.
+
+
+
+ Non-free feature can have only one
+ value
+
+ A non-conditional property in requirement in always
+ present in common properties.
+
+ A property in build request is present in
+ common properties, unless (2) tells otherwise.
+
+ If either build request, or requirements (non-conditional
+ or conditional) include a expandable property (either composite,
+ or property with specified subfeature value), the behaviour is
+ equvivalent to explicitly adding all expanded properties to build
+ request or requirements.
+
+ If requirements include conditional property, and
+ condiiton of this property is true in context of common
+ properties, then the conditional property should be in common
+ properties as well.
+
+ If no value for a property is given by other rules
+ here, it has default value if common properties.
+
+
+ Those rulse are declarative, they don't specify how to compute the
+ common properties. However, they provide enough information for the
+ user. The important point is the handling of conditional
+ requirements. The condition can be satisfied either by property in
+ build request, by non-conditional requirements, or even by another
+ conditional property. For example, for following example works as
+ expected:
+
+exe a : a.cpp
+ : <toolset>gcc:<variant>release
+ <variant>release:<define>FOO ;
+
+
+
+
+
+
+
+
+
+
+
+
+ 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.
-
+ 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.
+ 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 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 duplicates), 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.
-
-
+ 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 duplicates), 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
+ 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.
-
-
+ 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:
-
+
+ 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 an incidental property, for example, is
+ one whose feature 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]
+
-
- optional
+
+ symmetric
- 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]
-
+ 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.
+
-
- symmetric
+
+ path
- 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.
-
+ 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
+
-
- path
+
+ implicit
- 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
-
+ 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.
+
-
- implicit
+
+ composite
- 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 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.
+
-
- composite
+
+ link-incompatible
- 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.
-
+ See below.
+
-
- link-incompatible
+
+ dependency
- See below.
-
+ 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.
-
- 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.
+
+
- 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.
+ Features which are neither free nor incidental are called
+ base features.
- 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:
-
+ 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.
+
+ A feature's allowed-values may be extended with the
+ feature.extend rule.
-
+
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 ]
+ 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 ]
+
-
- 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
+
+ Property refinement
-
-
-
- If original properties and required properties are not
- link-compatible, refinement fails.
-
-
+ 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
-
-
+
+
+ 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.
-
-
-
-
+
+
+ If the original property set includes property with a different
+ value of non free feature, that property is removed.
+
+
+
+
-
- Conditional properties
+
+ 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:
+ Sometime it's desirable to apply certain requirements only for
+ a specific combination of other properties. For example, one of
+ compilers that you use issues a pointless 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. Conditional
+ properties allow you to do just that. Their syntax is:
-
-property ( "," property ) * ":" property
-
+
+ property ( "," property ) * ":" property
+
-
-For example, the problem above would be solved by:
+
+ 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 implicit 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 useful for
- testing.
-
-
-
- --ignore-config
-
- Do not load site-config.jam and
- user-config.jam
-
-
-
-
-
-
-
- Build request
-
Target identifiers and references
-
+
Target identifier is used to denote a
- target. The syntax is:
+ target. The syntax is:
target-id -> (project-id | target-name | file-name )
@@ -647,33 +976,33 @@ directory-name -> path
-This grammar allows some elements to be recognized as either
+ This grammar allows some elements to be recognized as either
+
+
+
+
+ project id (at this point, all project ids start with slash).
+
+
-
-
-
- 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).
+
+
-
-
- 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.
+
+
+
-
-
- 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:
+ 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
@@ -682,47 +1011,47 @@ lib/b.cpp -- regular file
/home/ghost/build/lr_library//parser -- target in specific project
-
+
- Rationale:Target is separated from project by special
- separator (not just slash), because:
+ Rationale:Target is separated from project by special
+ separator (not just slash), because:
-
-
-
- It emphasises that projects and targets are different things.
-
-
+
+
+
+ It emphasises that projects and targets are different things.
+
+
-
-
- It allows to have main target names with slashes.
+
+
+ It allows to have main target names with slashes.
-
-
-
-
+ That makes good rationale for why main target must contain names.
+ -->
+
+
+
-
- Target reference is used to
- specify a source target, and may additionally specify desired
- properties for that target. It has this syntax:
+
+ 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 ]
@@ -730,420 +1059,202 @@ requested-properties -> property-path
-For example,
+ 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.
+
+ 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.
+
+
-
-
+
+ Generators
-
- Build process
+ The information is this section is likely to be outdated
+ and misleading.
+
- 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.
+ 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.
- 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.
+ 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).
- 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.
+ 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.
- 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.
+
+ Selecting and ranking viable generators
- 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.
+ Each generator, in addition to target types that it can
+ produce, have attribute that affects its applicability in
+ particular sitiation. Those attributes are:
- All main target alternatives which requirements are
- satisfied by the build request are enumerated.
+ 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.
- If there are several such alternatives, the one which
- longer requirements list is selected.
+ Optional properties, which increase the generators
+ suitability for a particual build.
-
-
-
-
+
- For the selected alternative
+ 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
+ are 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 'construct'. 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:
-
- Each target reference in the source list are
- recursively constructed.
-
+
+ When dependency graph is constructed, each action can be
+ assigned a rule for property adjustment.
+
-
- 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.
-
+
+ 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.
+
-
-
-
-
- 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.
-
-
-
+ 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: the 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.
-
- 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.
+ 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.
-
+
-
+
+