From a281ef28ff13135b9a8a85b30844bb553596f7bb Mon Sep 17 00:00:00 2001
From: Vladimir Prus To verify your installation, you can use bjam --version at
+ the command line. 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 may not contain the
- '<', ':', or '=' characters. Each feature in a build configuration has one or more associated
+ values. Feature values may not contain the '<',
+ ':', or '=' characters. 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 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 value-string is a string of the form
- value-subvalue1-subvalue2...-subvalueN, where value is
- a feature value and subvalue1...subvalueN are values of related
- subfeatures. For example, 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 where no property appears twice, for
- instance: <toolset>gcc <runtime-link>static.
+ A property set is a set of properties where no property
+ appears twice, 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 build specification is a property set which fully describes
+ the set of features used to build a target. 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.
-
+ 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 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. 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. 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. 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
+ 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. 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: 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: 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] 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. 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. TODO: document active features..
@@ -46,15 +49,20 @@
+
+
+
+ Installation
+ When using package management or installers, Boost.Build is ready to work
+ instantly. In other case, two steps are required:
+
+
+
+
+
+boost-build /path/to/boost.build ;
+
+ The directory "examples" in the distribution already has this file,
+ so you can build projects there and add new without doing anything.
+ Reference
+ 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. They main purpose is organization: related targets can
+ be places in one project, then can be build together, or share some
+ definitions. Main targets and project are described mostly in declarative
+ fashion. To make some use of them, user issues build request, which specifies what targets user
+ wants to build, and what properties are desirable. Build request is not
+ necessary explicit. Invoking the build system without parameters will
+ build the project in current directory with defauly properties. The
+ properties describe various aspects of constructed objects. For
+ portability, they are specified in a normalized form, for example
+
+<optimization>full <inlining>off
+
+ Depending on used compiler, this will be translated into appropriate
+ flags. 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 then,
+ 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 target reference 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 type.
+ 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 main 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 type 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.
Features and properties
Definitions
- Feature Attributes
-
+
<define>NDEBUG=1 <define>HAS_CONFIG_H=1
@@ -174,26 +258,25 @@
Feature Declaration
-
- The low-level feature declaration interface is the
- feature rule from the feature module:
-
+ 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.
+ 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 ]
-
+ 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
@@ -302,7 +378,7 @@ it works in V1, so can't document this for V2.". Will clean up soon -DWA ]
requested and actual properties are link-compatible, it's OK. Otherwise,
it's an error.
When a target with certain properties is requested, and that target requires some set of properties, it is needed to find the set of @@ -320,6 +396,22 @@ it works in V1, so can't document this for V2.". Will clean up soon -DWA ] value of non free feature, that property is removed. +
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 ; ++
bjam's first job upon startup is to load the Jam code which implements @@ -366,7 +458,9 @@ it works in V1, so can't document this for V2.". Will clean up soon -DWA ]
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. 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.
+Main target is a named entity which can be build, for example a named executable file. To declare a main target, user invokes some of the main target - rules, passing it things like list of source and requirement.
+ rules, passing it things like list of sources and requirements.It is possible to have different list of sources for different toolsets, therefore it is possible to invoke main target rules several @@ -645,9 +773,9 @@ borland/runtime-link=static,dynamic After that, the target given by local-target-name in the found project is used. -
Target reference is used to specify a source target, and may - additionally specify desired properties for that target. It has this - syntax:
+Target reference 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
@@ -669,6 +797,22 @@ borland/runtime-link=static,dynamic
that project it is used. Otherwise, we just treat the target reference as
a file name.
+ 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 below.
+
Target paths
To distinguish targets build with different properties, they are put
@@ -700,24 +844,30 @@ borland/runtime-link=static,dynamic
+ The build works in this way. On startup, the project in the current - directory is read. In turn, it may request building of other projects, - which will be loaded recursively. Parent projects are also loaded to - inherit some of their properties. As the result, a tree of projects is - constructed. After that, the build request is constructed from the - command line. Then, the steps are:
+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:
-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.
+ +Each generator, in addition to target types that it can produce, have + attribute that affects its applicability in particular sitiation. Those + attributes are:
+ +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.
+ +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.
+ +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:
+ +The dependency graph constructed for each target is build of so called - "virtual targets", which do not yet correspond to jam's targets. It is - therefore converted to jam's dependency graph which is then build.
+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.
+ +Dependency scanning is the process of finding implicit dependencies + due to "include" statements and similar things. It has to take into + account two things:
+ +Dependency scanning is implemented by objects called scanners. See + documentation for the "scanner" module to detail.
+ +Regarding the first problem, we really have no choice. We can't treat + the same actual target differently depending on from where it is used. + Therefore, when handling of includes differers depending on actions, we + have to duplicate targets and assign different properties to it.
+ +For the reason, when actualizing a virtual target we optionally pass + the needed scanner to the "virtual-target.actualize" method. When no + scanner is passed, a new actual target is created, with it's dependencies + and updating actions set accordingly. When a particular scanner is + specified, a new actual target is created. That target will depend on + target created without scanner. In effect, this will allow to use + different scanners for the same file.
+ +++ What shall we do when using subvariants. For user, subvariants must be + more or less transparent. If without subvariant a header was generated to + a certain directory, everything must work. Suppose that file a.cpp + belongs to a dependency graph of main target a. Include paths are + ++ INCLUDES $(<) : [ SEARCH_FOR_TARGET $(>) : $(SEARCH_PATH) ] ; ++
++ We start by finding all places where headers that are part of a's + dependency graph are generated. We insert those places to the include + paths, immediately after ".". For example, we might end with: + ++ "/usr/include" "/home/t" "." ++
++ As a result: + ++ "/usr/include" "/home/t" "." "build" ++
Last modified: Aug 15, 2002
diff --git a/v2/boost_build_v2.html b/v2/boost_build_v2.html index 6711fb773..68d1d650b 100644 --- a/v2/boost_build_v2.html +++ b/v2/boost_build_v2.html @@ -22,6 +22,10 @@ table { align: center; border: thin; } +To verify your installation, you can use bjam --version at
+ the command line. 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 may not contain the
- '<', ':', or '=' characters. Each feature in a build configuration has one or more associated
+ values. Feature values may not contain the '<',
+ ':', or '=' characters. 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 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 value-string is a string of the form
- value-subvalue1-subvalue2...-subvalueN, where value is
- a feature value and subvalue1...subvalueN are values of related
- subfeatures. For example, the properties
- <toolset>gcc <toolset-version>3.0.1 can be
- expressed more conscisely using a value-string, as
- <toolset>gcc-3.0.1.
@@ -46,15 +49,20 @@
+
+
+
+ Installation
+ When using package management or installers, Boost.Build is ready to work
+ instantly. In other case, two steps are required:
+
+
+
+
+
+boost-build /path/to/boost.build ;
+
+ The directory "examples" in the distribution already has this file,
+ so you can build projects there and add new without doing anything.
+ Reference
+ 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. They main purpose is organization: related targets can
+ be places in one project, then can be build together, or share some
+ definitions. Main targets and project are described mostly in declarative
+ fashion. To make some use of them, user issues build request, which specifies what targets user
+ wants to build, and what properties are desirable. Build request is not
+ necessary explicit. Invoking the build system without parameters will
+ build the project in current directory with defauly properties. The
+ properties describe various aspects of constructed objects. For
+ portability, they are specified in a normalized form, for example
+
+<optimization>full <inlining>off
+
+ Depending on used compiler, this will be translated into appropriate
+ flags. 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 then,
+ 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 target reference 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 type.
+ 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 main 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 type 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.
Features and properties
Definitions
-
A property set is a set of properties where no property appears twice, for - instance: <toolset>gcc <runtime-link>static. +
A property set is a set of properties where no property + appears twice, 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 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 build specification is a property set which fully describes + the set of features used to build a target.
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. - + 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 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.
+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.
+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.
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 +
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.
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:
+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@@ -174,26 +258,25 @@
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]
+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.
+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.
TODO: document active features..
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 wit The build system will + provide high-level rules which define features in terms of valid and + useful combinations of attributes.
When a target with certain properties is requested, and that target requires some set of properties, it is needed to find the set of @@ -320,6 +396,22 @@ it works in V1, so can't document this for V2.". Will clean up soon -DWA ] value of non free feature, that property is removed.
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 ; ++
bjam's first job upon startup is to load the Jam code which implements @@ -366,7 +458,9 @@ it works in V1, so can't document this for V2.". Will clean up soon -DWA ]
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. 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.
+Main target is a named entity which can be build, for example a named executable file. To declare a main target, user invokes some of the main target - rules, passing it things like list of source and requirement.
+ rules, passing it things like list of sources and requirements.It is possible to have different list of sources for different toolsets, therefore it is possible to invoke main target rules several @@ -645,9 +773,9 @@ borland/runtime-link=static,dynamic After that, the target given by local-target-name in the found project is used. -
Target reference is used to specify a source target, and may - additionally specify desired properties for that target. It has this - syntax:
+Target reference 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
@@ -669,6 +797,22 @@ borland/runtime-link=static,dynamic
that project it is used. Otherwise, we just treat the target reference as
a file name.
+ 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 below.
+
Target paths
To distinguish targets build with different properties, they are put
@@ -700,24 +844,30 @@ borland/runtime-link=static,dynamic
+ The build works in this way. On startup, the project in the current - directory is read. In turn, it may request building of other projects, - which will be loaded recursively. Parent projects are also loaded to - inherit some of their properties. As the result, a tree of projects is - constructed. After that, the build request is constructed from the - command line. Then, the steps are:
+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:
-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.
+ +Each generator, in addition to target types that it can produce, have + attribute that affects its applicability in particular sitiation. Those + attributes are:
+ +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.
+ +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.
+ +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:
+ +The dependency graph constructed for each target is build of so called - "virtual targets", which do not yet correspond to jam's targets. It is - therefore converted to jam's dependency graph which is then build.
+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.
+ +Dependency scanning is the process of finding implicit dependencies + due to "include" statements and similar things. It has to take into + account two things:
+ +Dependency scanning is implemented by objects called scanners. See + documentation for the "scanner" module to detail.
+ +Regarding the first problem, we really have no choice. We can't treat + the same actual target differently depending on from where it is used. + Therefore, when handling of includes differers depending on actions, we + have to duplicate targets and assign different properties to it.
+ +For the reason, when actualizing a virtual target we optionally pass + the needed scanner to the "virtual-target.actualize" method. When no + scanner is passed, a new actual target is created, with it's dependencies + and updating actions set accordingly. When a particular scanner is + specified, a new actual target is created. That target will depend on + target created without scanner. In effect, this will allow to use + different scanners for the same file.
+ +++ What shall we do when using subvariants. For user, subvariants must be + more or less transparent. If without subvariant a header was generated to + a certain directory, everything must work. Suppose that file a.cpp + belongs to a dependency graph of main target a. Include paths are + ++ INCLUDES $(<) : [ SEARCH_FOR_TARGET $(>) : $(SEARCH_PATH) ] ; ++
++ We start by finding all places where headers that are part of a's + dependency graph are generated. We insert those places to the include + paths, immediately after ".". For example, we might end with: + ++ "/usr/include" "/home/t" "." ++
++ As a result: + ++ "/usr/include" "/home/t" "." "build" ++
Last modified: Aug 15, 2002