mirror of
https://github.com/boostorg/build.git
synced 2026-02-17 01:32:12 +00:00
Wholespace merge from HEAD
[SVN r35613]
This commit is contained in:
@@ -63,7 +63,7 @@ rule alias ( name : sources * : requirements * : default-build * : usage-require
|
||||
|
||||
targets.main-target-alternative
|
||||
[ new alias-target-class $(name) : $(project)
|
||||
: [ targets.main-target-sources $(sources) : $(name) ]
|
||||
: [ targets.main-target-sources $(sources) : $(name) : no-renaming ]
|
||||
: [ targets.main-target-requirements $(requirements) : $(project) ]
|
||||
: [ targets.main-target-default-build $(default-build) : $(project) ]
|
||||
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
|
||||
|
||||
@@ -825,22 +825,28 @@ local rule try-one-generator-really ( project name ? : generator :
|
||||
] ;
|
||||
|
||||
local usage-requirements ;
|
||||
if $(targets) && [ class.is-a $(targets[1]) : property-set ]
|
||||
local success ;
|
||||
if $(targets)
|
||||
{
|
||||
usage-requirements = $(targets[1]) ;
|
||||
targets = $(targets[2-]) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage-requirements = [ property-set.empty ] ;
|
||||
success = true ;
|
||||
|
||||
if [ class.is-a $(targets[1]) : property-set ]
|
||||
{
|
||||
usage-requirements = $(targets[1]) ;
|
||||
targets = $(targets[2-]) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage-requirements = [ property-set.empty ] ;
|
||||
}
|
||||
}
|
||||
|
||||
generators.dout [ indent ] " generator" [ $(generator).id ] " spawned " ;
|
||||
generators.dout [ indent ] " " $(targets) ;
|
||||
if $(targets)
|
||||
if $(success)
|
||||
{
|
||||
return $(usage-requirements) $(targets) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Checks if generator invocation can be pruned, because it's guaranteed
|
||||
@@ -1128,12 +1134,7 @@ local rule construct-really (
|
||||
# 'construct' in stack, returns only targets of requested 'target-type',
|
||||
# otherwise, returns also unused sources and additionally generated
|
||||
# targets.
|
||||
#
|
||||
# Does not return target which are not of 'allowed-type' or of type derived from
|
||||
# it. If 'allowed-type' is not specified, it's defaulted to 'target-type'.
|
||||
# See lib-target-class for use case of this.
|
||||
rule construct ( project name ? : target-type : property-set * : sources *
|
||||
: allowed-type * )
|
||||
rule construct ( project name ? : target-type : property-set * : sources * )
|
||||
{
|
||||
if (.construct-stack)
|
||||
{
|
||||
|
||||
@@ -555,7 +555,7 @@ local rule __test__ ( )
|
||||
assert.true path-order $(test-space) <optimization>on <rtti>on ;
|
||||
assert.false path-order $(test-space) <rtti>on <optimization>on ;
|
||||
|
||||
assert.result <toolset>gcc <rtti>off <define>FOO
|
||||
assert.result <define>FOO <rtti>off <toolset>gcc
|
||||
: refine <toolset>gcc <rtti>off
|
||||
: <define>FOO
|
||||
: $(test-space)
|
||||
|
||||
@@ -1369,18 +1369,27 @@ class typed-target : basic-target
|
||||
|
||||
# Return the list of sources to use, if main target rule is invoked
|
||||
# with 'sources'. If there are any objects in 'sources', they are treated
|
||||
# as main target instances, and WRITEME.
|
||||
rule main-target-sources ( sources * : main-target-name )
|
||||
# as main target instances, and the name of such targets are adjusted to
|
||||
# be '<name_of_this_target>__<name_of_source_target>'. Such renaming
|
||||
# is disabled is non-empty value is passed for 'no-renaming' parameter.
|
||||
#
|
||||
rule main-target-sources ( sources * : main-target-name : no-renaming ? )
|
||||
{
|
||||
local result ;
|
||||
for local t in $(sources)
|
||||
{
|
||||
if [ class.is-instance $(t) ]
|
||||
{
|
||||
local name = [ $(t).name ] ;
|
||||
local new-name = $(main-target-name)__$(name) ;
|
||||
$(t).rename $(new-name) ;
|
||||
result += $(new-name) ;
|
||||
local name = [ $(t).name ] ;
|
||||
if ! $(no-renaming)
|
||||
{
|
||||
name = $(main-target-name)__$(name) ;
|
||||
$(t).rename $(name) ;
|
||||
}
|
||||
# Inline targets are not built by default.
|
||||
local p = [ $(t).project ] ;
|
||||
$(p).mark-target-as-explicit $(name) ;
|
||||
result += $(name) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -402,6 +402,14 @@ class abstract-file-target : virtual-target
|
||||
ps = [ property-set.empty ] ;
|
||||
}
|
||||
|
||||
#~ We add ourselves to the properties so that any tag rule can get
|
||||
#~ more direct information about the target than just that available
|
||||
#~ through the properties. This is useful in implementing
|
||||
#~ name changes based on the sources of the target. For example to
|
||||
#~ make unique names of object files based on the source file.
|
||||
#~ --grafik
|
||||
ps = [ property-set.create [ $(ps).raw ] <target>$(__name__) ] ;
|
||||
|
||||
local tag = [ $(ps).get <tag> ] ;
|
||||
|
||||
if $(tag)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<chapter id="bbv2.advanced">
|
||||
<title>User documentation</title>
|
||||
<title>Overview</title>
|
||||
|
||||
<para>This section will provide the information necessary to create your own
|
||||
projects using Boost.Build. The information provided here is relatively
|
||||
@@ -73,7 +73,7 @@
|
||||
</para>
|
||||
|
||||
<section id="bbv2.advanced.jam_language">
|
||||
<title>Boost.Jam language</title>
|
||||
<title>Boost.Jam Language</title>
|
||||
|
||||
<para>This section will describe the basics of the Boost.Jam
|
||||
language—just enough for writing Jamfiles. For more information,
|
||||
@@ -536,7 +536,7 @@ bjam optimization=space
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.targets">
|
||||
<title>Declaring targets</title>
|
||||
<title>Declaring Targets</title>
|
||||
|
||||
<para id="bbv2.advanced.targets.main">
|
||||
A <firstterm>Main target</firstterm> is a user-defined named
|
||||
@@ -769,7 +769,7 @@ rule my-rule ( properties * )
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Default build</title>
|
||||
<title>Default Build</title>
|
||||
|
||||
<para>The <varname>default-build</varname> parameter
|
||||
is a set of properties to be used if the build request does
|
||||
@@ -785,7 +785,7 @@ exe hello : hello.cpp : : <threading>multi ;
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Additional information</title>
|
||||
<title>Additional Information</title>
|
||||
|
||||
<para>
|
||||
The ways a target is built can be so different that
|
||||
@@ -826,7 +826,7 @@ exe hello : hello.cpp
|
||||
explicit request, this can be expressed by the
|
||||
<functionname>explicit</functionname> rule:
|
||||
<programlisting>
|
||||
explicit install_programs ;</programlisting>
|
||||
explicit install_programs ;</programlisting>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
@@ -1028,90 +1028,6 @@ project tennis
|
||||
perfectly appropriate to start a user guide with that kind
|
||||
of material. -->
|
||||
</section>
|
||||
|
||||
|
||||
<section id="bbv2.advanced.other-rules">
|
||||
<title>Jamfile Utility Rules</title>
|
||||
|
||||
<para>The following table describes utility rules that can be
|
||||
used in Jamfiles. Detailed information for any of these rules can
|
||||
be obtained by running:
|
||||
<screen>
|
||||
bjam --help project.<replaceable>rulename</replaceable>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title/>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Rule</entry>
|
||||
|
||||
<entry>Semantics</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><link linkend=
|
||||
"bbv2.advanced.projects.attributes.projectrule">project</link>
|
||||
</entry>
|
||||
|
||||
<entry>Define this project's symbolic ID or attributes.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><xref linkend=
|
||||
"bbv2.advanced.projects.relationships.useprojectrule">use-project</xref></entry>
|
||||
|
||||
<entry>Make another project known so that it can be referred to by symbolic ID.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><xref linkend=
|
||||
"bbv2.advanced.projects.relationships.buildprojectrule">build-project</xref></entry>
|
||||
|
||||
<entry>Cause another project to be built when this one is built.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><xref linkend=
|
||||
"bbv2.reference.buildprocess.explict">explicit</xref></entry>
|
||||
|
||||
<entry>State that a target should be built only by explicit
|
||||
request.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>glob</entry>
|
||||
|
||||
<entry>Translate a list of shell-style wildcards into a
|
||||
corresponding list of files.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>constant</entry>
|
||||
|
||||
<entry>Injects a variable setting into this project's
|
||||
Jamfile module and those of all its subprojects.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>path-constant</entry>
|
||||
|
||||
<entry>Injects a variable set to a path value into
|
||||
this project's Jamfile module and those of all its subprojects.
|
||||
If the value is a relative path it will be adjusted for
|
||||
each subproject so that it refers to the same
|
||||
directory.</entry>
|
||||
</row>
|
||||
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.build_process">
|
||||
<title>The Build Process</title>
|
||||
@@ -1147,7 +1063,7 @@ bjam --help project.<replaceable>rulename</replaceable>
|
||||
</tip>
|
||||
|
||||
<section>
|
||||
<title>Build request</title>
|
||||
<title>Build Request</title>
|
||||
|
||||
<para>
|
||||
The command line specifies which targets to build and with which
|
||||
@@ -1253,7 +1169,7 @@ bjam app1 lib1//lib1 gcc debug optimization=full
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section><title>Building a project</title>
|
||||
<section><title>Building a Project</title>
|
||||
|
||||
<para>Often, a user builds a complete project, not just one main
|
||||
target. In fact, invoking <command>bjam</command> without
|
||||
@@ -1287,763 +1203,6 @@ explicit hello_test ;
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.builtins.targets">
|
||||
<title>Builtin target types</title>
|
||||
|
||||
<para>This section describes main targets types that Boost.Build supports
|
||||
of-of-the-box. Unless otherwise noted, all mentioned main target rules
|
||||
have the common signature, described in <xref
|
||||
linkend="bbv2.main-target-rule-syntax"/>.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Programs</title>
|
||||
|
||||
<indexterm><primary>Builtin
|
||||
rules</primary><secondary>exe</secondary></indexterm>
|
||||
<para>Programs are created using the <code>exe</code> rule, which
|
||||
follows the <link linkend="bbv2.main-target-rule-syntax">common
|
||||
syntax</link>. For example:
|
||||
<programlisting>
|
||||
exe hello : hello.cpp some_library.lib /some_project//library
|
||||
: <threading>multi
|
||||
;
|
||||
</programlisting>
|
||||
This will create an executable file from the sources -- in this case,
|
||||
one C++ file, one library file present in the same directory, and
|
||||
another library that is created by Boost.Build. Generally, sources
|
||||
can include C and C++ files, object files and libraries. Boost.Build
|
||||
will automatically try to convert targets of other types.
|
||||
</para>
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
On Windows, if an application uses dynamic libraries, and both
|
||||
the application and the libraries are built by Boost.Build, its not
|
||||
possible to immediately run the application, because the
|
||||
<literal>PATH</literal> environment variable should include the path
|
||||
to the libraries. It means you have to either add the paths
|
||||
manually, or place the application and the libraries to the same
|
||||
directory, for example using the <link linkend="bbv2.builtins.stage">
|
||||
stage</link> rule.
|
||||
</para>
|
||||
<!-- We should be emphasizing the use of the built-in testing
|
||||
rules rather than continually discussing these quirks of
|
||||
running programs with dynamic libraries. -->
|
||||
</tip>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Libraries</title>
|
||||
|
||||
<para>Libraries are created using the <code>lib</code> rule, which
|
||||
follows the <link linkend="bbv2.main-target-rule-syntax">common
|
||||
syntax</link>. For example:
|
||||
<programlisting>
|
||||
lib helpers : helpers.cpp : <include>boost : : <include>. ;
|
||||
</programlisting>
|
||||
</para>
|
||||
<!-- Add one sentence that says what the above does. -->
|
||||
<para>In the most common case, the <code>lib</code> creates a library
|
||||
from the specified sources. Depending on the value of
|
||||
<link> feature the library will be either static or
|
||||
shared. There are two other cases. First is when the library is
|
||||
installed somewhere in compiler's search paths, and should be
|
||||
searched by the compiler (typically, using the <option>-l</option>
|
||||
option). The second case is where the library is available as a
|
||||
prebuilt file and the full path is known.
|
||||
<!-- But the first case is also prebuilt. This is confusingly phrased. -->
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The syntax for these case is given below:
|
||||
<programlisting>
|
||||
lib z : : <name>z <search>/home/ghost ;
|
||||
lib compress : : <file>/opt/libs/compress.a ;
|
||||
</programlisting>
|
||||
The <code>name</code> property specifies the name that should be
|
||||
passed to the <option>-l</option> option, and the <code>file</code>
|
||||
property specifies the file location. The <varname>search</varname> feature
|
||||
specifies paths in which to search for the library. That feature can
|
||||
be specified several times, or it can be omitted, in which case only
|
||||
default compiler paths will be searched.
|
||||
</para>
|
||||
|
||||
<para>The difference between using the <varname>file</varname> feature as
|
||||
opposed to the <varname>name</varname> feature together with the
|
||||
<varname>search</varname> feature is that <varname>file</varname> is more
|
||||
precise. A specific file will be used. On the other hand, the
|
||||
<varname>search</varname> feature only adds a library path, and the
|
||||
<varname>name</varname> feature gives the basic name of the library. The
|
||||
search rules are specific to the linker. For example, given these
|
||||
definition:
|
||||
<programlisting>
|
||||
lib a : : <variant>release <file>/pool/release/a.so ;
|
||||
lib a : : <variant>debug <file>/pool/debug/a.so ;
|
||||
lib b : : <variant>release <file>/pool/release/b.so ;
|
||||
lib b : : <variant>debug <file>/pool/debug/b.so ;
|
||||
</programlisting>
|
||||
It's possible to use release version of <code>a</code> and debug
|
||||
version of <code>b</code>. Had we used the <varname>name</varname> and
|
||||
<varname>search</varname> features, the linker would always pick either
|
||||
release or debug versions.
|
||||
<!-- explain -->
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For convenience, the following syntax is allowed:
|
||||
<programlisting>
|
||||
lib z ;
|
||||
lib gui db aux ;
|
||||
</programlisting>
|
||||
and is does exactly the same as:
|
||||
<programlisting>
|
||||
lib z : : <name>z ;
|
||||
lib gui : : <name>gui ;
|
||||
lib db : : <name>db ;
|
||||
lib aux : : <name>aux ;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>When a library uses another library you should put that other
|
||||
library in the list of sources. This will do the right thing in all
|
||||
cases. For portability, you should specify library dependencies even
|
||||
for searched and prebuilt libraries, othewise, static linking on
|
||||
Unix won't work. For example:
|
||||
<programlisting>
|
||||
lib z ;
|
||||
lib png : z : <name>png ;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>When a library (say, <code>a</code>), that has another
|
||||
library, (say, <code>b</code>)
|
||||
<!-- how can a library "have" a library? -->
|
||||
is linked dynamically, the <code>b</code>
|
||||
library will be incorporated
|
||||
<!-- Incorporated? Be precise. -->
|
||||
in <code>a</code>. (If <code>b</code>
|
||||
is dynamic library as well, then <code>a</code> will only refer to
|
||||
it, and not include any extra code.)
|
||||
<!-- Don't parenthesize a whole sentence. -->
|
||||
When the <code>a</code>
|
||||
library is linked statically, Boost.Build will assure that all
|
||||
executables that link to <code>a</code> will also link to
|
||||
<code>b</code>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>One feature of Boost.Build that is very important for libraries
|
||||
is usage requirements.
|
||||
<!-- Rephrase that. But then, it's much too late for an
|
||||
introduction of usage requirements - you've already
|
||||
discussed them many times. -->
|
||||
For example, if you write:
|
||||
<programlisting>
|
||||
lib helpers : helpers.cpp : : : <include>. ;
|
||||
</programlisting>
|
||||
then the compiler include path for all targets that use
|
||||
<code>helpers</code> will contain the directory
|
||||
<!-- The rest of this sentence is unintelligible -->
|
||||
where the target is defined.path to "helpers.cpp". The user
|
||||
only needs to add <code>helpers</code> to the list of sources,
|
||||
and needn't consider the requirements its use imposes on a
|
||||
dependent target. This feature greatly simplifies Jamfiles.
|
||||
<!-- You can't say “allows to”—you need a noun. This error is
|
||||
repeated throughout. -->
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>If you don't want shared libraries to include all libraries
|
||||
that are specified in sources (especially statically linked ones),
|
||||
you'd need to use the following:
|
||||
<programlisting>
|
||||
lib b : a.cpp ;
|
||||
lib a : a.cpp : <use>b : : <library>b ;
|
||||
</programlisting>
|
||||
This specifies that <code>a</code> uses <code>b</code>, and causes
|
||||
all executables that link to <code>a</code> also link to
|
||||
<code>b</code>. In this case, even for shared linking, the
|
||||
<code>a</code> library won't even refer to <code>b</code>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.builtins.alias">
|
||||
<title>Alias</title>
|
||||
|
||||
<para>
|
||||
The <functionname>alias</functionname> rule gives alternative name to
|
||||
a group of targets. For example, to give the name
|
||||
<filename>core</filename> to a group of three other targets with the
|
||||
following code:
|
||||
<programlisting>
|
||||
alias core : im reader writer ;</programlisting>
|
||||
Using <filename>core</filename> on the command line, or in the source list
|
||||
of any other target is the same as explicitly using
|
||||
<filename>im</filename>, <filename>reader</filename>, and
|
||||
<filename>writer</filename>, but it is just more convenient.
|
||||
|
||||
</para>
|
||||
|
||||
|
||||
<para>
|
||||
Another use of the <code>alias</code> rule is to change build
|
||||
properties. For example, if you always want static linking for a
|
||||
specific C++ Boost library, you can write the following:
|
||||
<programlisting>
|
||||
alias threads : /boost/thread//boost_thread : <link>static ;
|
||||
</programlisting>
|
||||
and use only the <code>threads</code> alias in your Jamfiles.
|
||||
<!-- changed name for clarity -->
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can also specify usage requirements for the
|
||||
<code>alias</code> target. If you write the following:
|
||||
<programlisting>
|
||||
alias header_only_library : : : : <include>/usr/include/header_only_library ;
|
||||
</programlisting>
|
||||
then using <code>header_only_library</code> in sources will only add an
|
||||
include path. Also note that when there are some sources, their usage
|
||||
requirements are propagated, too. For example:
|
||||
<programlisting>
|
||||
lib lib : lib.cpp : : : <include>. ;
|
||||
alias lib_alias ; <!-- This line can't possibly be correct!?? -->
|
||||
exe main : main.cpp lib_alias ;
|
||||
</programlisting>
|
||||
will compile <filename>main.cpp</filename> with the additional include.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.builtins.stage">
|
||||
<title>Installing</title>
|
||||
|
||||
<para>For installing a built target you should use the
|
||||
<code>install</code> rule, which follows the <link
|
||||
linkend="bbv2.main-target-rule-syntax">common syntax</link>. For
|
||||
example:
|
||||
<programlisting>
|
||||
install dist : hello helpers ;
|
||||
</programlisting>
|
||||
will cause the targets <code>hello</code> and <code>helpers</code> to
|
||||
be moved to the <filename>dist</filename> directory, relative to
|
||||
Jamfile's directory. The directory can
|
||||
be changed with the <code>location</code> property:
|
||||
<programlisting>
|
||||
install dist : hello helpers : <location>/usr/bin ;
|
||||
</programlisting>
|
||||
While you can achieve the same effect by changing the target name to
|
||||
<filename>/usr/bin</filename>, using the <code>location</code>
|
||||
property is better, because it allows you to use a mnemonic target
|
||||
name.
|
||||
</para>
|
||||
|
||||
<para>The <code>location</code> property is especially handy when the location
|
||||
is not fixed, but depends on build variant or environment variables:
|
||||
<programlisting>
|
||||
install dist : hello helpers : <variant>release:<location>dist/release
|
||||
<variant>debug:<location>dist/debug ;
|
||||
install dist2 : hello helpers : <location>$(DIST) ;
|
||||
</programlisting>
|
||||
See also <link linkend="bbv2.reference.variants.propcond">conditional
|
||||
properties</link> and <link linkend="bbv2.faq.envar">environment variables</link>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Specifying the names of all libraries to install can be boring. The
|
||||
<code>install</code> allows you to specify only the top-level executable
|
||||
targets to install, and automatically install all dependencies:
|
||||
<programlisting>
|
||||
install dist : hello
|
||||
: <install-dependencies>on <install-type>EXE
|
||||
<install-type>LIB
|
||||
;
|
||||
</programlisting>
|
||||
will find all targets that <code>hello</code> depends on, and install
|
||||
all of those which are either executables or libraries. More
|
||||
specifically, for each target, other targets that were specified as
|
||||
sources or as dependency properties, will be recursively found. One
|
||||
exception is that targets referred with the <link
|
||||
linkend="bbv2.builtin.features.use"><code>use</code></link> feature
|
||||
are not considered, because that feature is typically used to refer to
|
||||
header-only libraries.
|
||||
If the set of target types is specified, only targets of that type
|
||||
will be installed, otherwise, all found target will be installed.
|
||||
</para>
|
||||
|
||||
<para>The <link linkend="bbv2.builtins.alias"><code>alias</code></link>
|
||||
rule can be used when targets must be installed into several
|
||||
directories:
|
||||
<programlisting>
|
||||
alias install : install-bin install-lib ;
|
||||
install install-bin : applications : /usr/bin ;
|
||||
install install-lib : helper : /usr/lib ;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>Because the <code>install</code> rule just copies targets, most
|
||||
free features <footnote><para>see the definition of "free" in <xref
|
||||
linkend="bbv2.reference.features.attributes"/>.</para></footnote>
|
||||
have no effect when used in requirements of the <code>install</code> rule.
|
||||
The only two which matter are
|
||||
<link linkend="bbv2.builtin.features.dependency">
|
||||
<varname>dependency</varname></link> and, on Unix,
|
||||
<link linkend="bbv2.builtin.feature.dll-path"><varname>dll-path</varname></link>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
(Unix specific). On Unix, executables built with Boost.Build typically
|
||||
contain the list of paths to all used dynamic libraries. For
|
||||
installing, this is not desired, so Boost.Build relinks the executable
|
||||
with an empty list of paths. You can also specify additional paths for
|
||||
installed executables with the <varname>dll-path</varname> feature.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.builtins.testing">
|
||||
|
||||
<title>Testing</title>
|
||||
|
||||
<para>Boost.Build has convenient support for running unit tests. The
|
||||
simplest way is the <code>unit-test</code> rule, which follows the
|
||||
<link linkend="bbv2.main-target-rule-syntax">common syntax</link>. For
|
||||
example:
|
||||
<programlisting>
|
||||
unit-test helpers_test : helpers_test.cpp helpers ;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>The <functionname>unit-test</functionname> rule behaves like the
|
||||
<functionname>exe</functionname> rule, but after the executable is created it is
|
||||
run. If the executable returns an error code, the build system will also
|
||||
return an error and will try running the executable on the next
|
||||
invocation until it runs successfully. This behaviour ensures that you
|
||||
can't miss a unit test failure.
|
||||
</para>
|
||||
|
||||
<para>By default, the executable is run directly. Sometimes, it's
|
||||
desirable to run the executable using some helper command. You should use the
|
||||
<literal>testing.launcher</literal> property to specify the name of the
|
||||
helper command. For example, if you write:
|
||||
</para>
|
||||
<programlisting>
|
||||
unit-test helpers_test
|
||||
: helpers_test.cpp helpers
|
||||
: <emphasis role="bold"><testing.launcher>valgrind</emphasis>
|
||||
;
|
||||
</programlisting>
|
||||
<para>The command used to run the executable will be:</para>
|
||||
<screen>
|
||||
<emphasis role="bold">valgrind</emphasis> bin/$toolset/debug/helpers_test
|
||||
</screen>
|
||||
|
||||
|
||||
|
||||
<para>There are rules for more elaborate testing: <code>compile</code>,
|
||||
<code>compile-fail</code>, <code>run</code> and
|
||||
<code>run-fail</code>. They are more suitable for automated testing, and
|
||||
are not covered here.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.builtins.raw">
|
||||
|
||||
<title>Raw commands: 'make' and 'notfile'</title>
|
||||
|
||||
<para>Sometimes, the builtin target types are not enough, and you
|
||||
want Boost.Build to just run specific commands. There are two main
|
||||
target rules that make it possible: <functionname>make</functionname>
|
||||
and <functionname>notfile</functionname>.
|
||||
</para>
|
||||
|
||||
<para>The <functionname>make</functionname> rule is used when you want to
|
||||
create one file from a number of sources using some specific command.
|
||||
The <functionname>notfile</functionname> is used to unconditionally run
|
||||
a command.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Suppose you want to create file <filename>file.out</filename> from
|
||||
file <filename>file.in</filename> by running command
|
||||
<command>in2out</command>. Here's how you'd do this in Boost.Build:
|
||||
<programlisting>
|
||||
actions in2out
|
||||
{
|
||||
in2out $(<) $(>)
|
||||
}
|
||||
make file.out : file.in : @in2out ;
|
||||
</programlisting>
|
||||
If you run <command>bjam</command> and <filename>file.out</filename>
|
||||
does not exist, Boost.Build will run the <command>in2out</command>
|
||||
command to create that file. For more details on specifying actions,
|
||||
see <xref linkend="bbv2.advanced.jam_language.actions"/>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
The <functionname>make</functionname> rule is useful to express custom
|
||||
transformation that are used just once or twice in your project. For
|
||||
transformations that are used often, you are advised to declare
|
||||
new generator, as described in <xref linkend="bbv2.extending.tools"/>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
It could be that you just want to run some command unconditionally,
|
||||
and that command does not create any specific files. The, you can use
|
||||
the <functionname>notfile</functionname> rule. For example:
|
||||
<programlisting>
|
||||
notfile echo_something : @echo ;
|
||||
actions echo
|
||||
{
|
||||
echo "something"
|
||||
}
|
||||
</programlisting>
|
||||
The only difference from the <functionname>make</functionname> rule is
|
||||
that the name of the target is not considered a name of a file, so
|
||||
Boost.Build will unconditionally run the action.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.builtins.features">
|
||||
<title>Builtin features</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>variant</literal></term>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
A feature that combines several low-level features, making
|
||||
it easy to request common build configurations.
|
||||
</para>
|
||||
|
||||
<para><emphasis role="bold">Allowed values:</emphasis> <literal>debug</literal>, <literal>release</literal>,
|
||||
<literal>profile</literal>.</para>
|
||||
|
||||
<para>The value <literal>debug</literal> expands to</para>
|
||||
|
||||
<programlisting>
|
||||
<optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on
|
||||
</programlisting>
|
||||
|
||||
<para>The value <literal>release</literal> expands to</para>
|
||||
|
||||
<programlisting>
|
||||
<optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off
|
||||
</programlisting>
|
||||
|
||||
<para>The value <literal>profile</literal> expands to the same as
|
||||
<literal>release</literal>, plus:</para>
|
||||
|
||||
<programlisting>
|
||||
<profiling>on <debug-symbols>on
|
||||
</programlisting>
|
||||
|
||||
<para>User can define his own build variants using the <code>variant</code> rule from the <code>common</code>
|
||||
module.</para>
|
||||
|
||||
<para><emphasis role="bold">Notee:</emphasis> Runtime
|
||||
debugging is on in debug builds to suit the expectations of
|
||||
people used to various IDEs.
|
||||
<!-- Define "runtime debugging." Why will those people expect it to be on in debug builds? -->
|
||||
</para>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry id="bbv2.advanced.builtins.features.link">
|
||||
<term><literal>link</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
A feature that controls how libraries are built.
|
||||
</simpara>
|
||||
|
||||
<para><emphasis role="bold">Allowed values:</emphasis> <literal>shared</literal>,
|
||||
<literal>static</literal></para>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><literal>source</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
The <code><source>X</code> feature has the same effect on
|
||||
building a target as putting X in the list of sources.
|
||||
It's useful when you want to add
|
||||
the same source to all targets in the project
|
||||
(you can put <source> in requirements) or to conditionally
|
||||
include a source (using conditional requirements, see <xref linkend="bbv2.tutorial.conditions"/>)
|
||||
See also the <code><library></code> feature.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>library</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
This feature is almost equivalent to the <code><source></code> feature,
|
||||
except that it takes effect only for linking. When you want to
|
||||
link all targets in a Jamfile to certain library, the
|
||||
<code><library></code> feature is preferred over
|
||||
<code><source>X</code> -- the latter will add the library to
|
||||
all targets, even those that have nothing to do with libraries.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><anchor id="bbv2.builtin.features.dependency"/>
|
||||
<literal>dependency</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Introduces a dependency on the target named by the
|
||||
value of this feature (so it will be brought
|
||||
up-to-date whenever the target being declared is).
|
||||
The dependency is not used in any other way. For example, in
|
||||
application with plugins, the plugins are not used when linking
|
||||
the application,
|
||||
application might have dependency on its plugins, even though
|
||||
|
||||
|
||||
, and
|
||||
adds its usage requirements to the build properties
|
||||
of the target being declared.
|
||||
|
||||
The primary use case is when you want
|
||||
the usage requirements (such as <code>#include</code> paths) of some
|
||||
library to be applied, but don't want to link to it.
|
||||
<!-- It's hard to picture why anyone would want to do
|
||||
that. Please flesh out this motivation -->
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><anchor id="bbv2.builtin.features.use"/>
|
||||
<literal>use</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Introduces a dependency on the target named by the
|
||||
value of this feature (so it will be brought
|
||||
up-to-date whenever the target being declared is), and
|
||||
adds its usage requirements to the build properties
|
||||
<!-- Do you really mean "to the requirements?" -->
|
||||
of the target being declared. The dependency is not used
|
||||
in any other way. The primary use case is when you want
|
||||
the usage requirements (such as <code>#include</code> paths) of some
|
||||
library to be applied, but don't want to link to it.
|
||||
<!-- It's hard to picture why anyone would want to do
|
||||
that. Please flesh out this motivation -->
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><anchor id="bbv2.builtin.features.dll-path"/>
|
||||
<literal>dll-path</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Specify an additional directory where the system should
|
||||
look for shared libraries when the executable or shared
|
||||
library is run. This feature only affects Unix
|
||||
compilers. Plase see <xref linkend="bbv2.faq.dll-path"/>
|
||||
in <xref linkend="bbv2.faq"/> for details.
|
||||
</simpara>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><literal>hardcode-dll-paths</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Controls automatic generation of dll-path properties.
|
||||
</simpara>
|
||||
|
||||
<para><emphasis role="bold">Allowed values:</emphasis>
|
||||
<literal>true</literal>, <literal>false</literal>. This property
|
||||
is specific to Unix systems. If an executable is built with
|
||||
<code><hardcode-dll-paths>true</code>, the generated binary
|
||||
will contain the list of all the paths to the used shared
|
||||
libraries. As the result, the executable can be run without
|
||||
changing system paths to shared libraries or installing the
|
||||
libraries to system paths. This
|
||||
<!-- you need an antecedent. This _what_? -->
|
||||
is very convenient during
|
||||
development. Plase see the <link
|
||||
linkend="bbv2.faq.dll-path">FAQ entry</link> for details.
|
||||
Note that on Mac OSX, the paths are unconditionally hardcoded by
|
||||
the linker, and it's not possible to disable that behaviour.
|
||||
</para>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>cflags</literal></term>
|
||||
<term><literal>cxxflags</literal></term>
|
||||
<term><literal>linkflags</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
The value of those features is passed without modification to the
|
||||
corresponding tools. For <code>cflags</code> that's both the C and C++
|
||||
compilers, for <code>cxxflags</code> that's the C++ compiler and for
|
||||
<code>linkflags</code> that's the linker. The features are handy when
|
||||
you're trying to do something special that cannot be achieved by
|
||||
higher-level feature in Boost.Build.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>warnings</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
The <code><warnings></code> feature controls the warning level of compilers. It has the following values:
|
||||
<itemizedlist>
|
||||
<listitem><para><code>off</code> - disables all warnings.</para></listitem>
|
||||
<listitem><para><code>on</code> - enables default warning level for the tool.</para></listitem>
|
||||
<listitem><para><code>all</code> - enables all warnings.</para></listitem>
|
||||
</itemizedlist>
|
||||
Default value is <code>all</code>.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>warnings-as-errors</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
The <code><warnings-as-errors></code> makes it possible to treat warnings as errors and abort
|
||||
compilation on a warning. The value <code>on</code> enables this behaviour. The default value is
|
||||
<code>off</code>.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>build</literal></term>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis role="bold">Allowed values:</emphasis> <literal>no</literal></para>
|
||||
|
||||
<para>
|
||||
The <code>build</code> feature is used to conditionally disable build of a target. If <code><build>no</code>
|
||||
is in properties when building a target, build of that target is skipped. Combined with conditional requirements this
|
||||
allows to skip building some target in configurations where the build is known to fail.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</variablelist>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.differences_to_v1">
|
||||
<title>Differences to Boost.Build V1</title>
|
||||
<!-- "Differences to" is the British English usage. American
|
||||
English is "differences from." You can use the former but be
|
||||
sure you know what you're doing -->
|
||||
|
||||
<para>While Boost.Build V2 is based on the same ideas as Boost.Build V1,
|
||||
some of the syntax was changed, and some new important features were
|
||||
added. This chapter describes most of the changes.</para>
|
||||
|
||||
<section id="bbv2.advanced.differences_to_v1.configuration">
|
||||
<title>Configuration</title>
|
||||
|
||||
<para>In V1, toolsets were configured by environment variables. If you
|
||||
wanted to use two versions of the same toolset, you had to create a new
|
||||
toolset module that would set the variables and then invoke the base
|
||||
toolset. In V2, toolsets are configured by the
|
||||
<functionname>using</functionname>, and you can easily configure several
|
||||
versions of a toolset. See <xref
|
||||
linkend="bbv2.advanced.configuration"/> for details.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.differences_to_v1.jamfiles">
|
||||
<title>Writing Jamfiles</title>
|
||||
|
||||
<para>Probably one of the most important differences in V2 Jamfiles is
|
||||
the use of project requirements. In V1, if several targets had the same
|
||||
requirements (for example, a common <code>#include</code> path), it was necessary to
|
||||
manually write the requirements or use a helper rule or template target. In V2, the
|
||||
common properties can be specified with the <code>requirements</code> project
|
||||
attribute, as documented in <xref linkend="bbv2.advanced.projects"/>.
|
||||
</para>
|
||||
|
||||
<para><link linkend="bbv2.tutorial.libs">Usage requirements</link>
|
||||
also help to simplify Jamfiles.
|
||||
<!-- Simplify, simplify, simplify! You could go through the
|
||||
entire document several times and make changes like that
|
||||
one -->
|
||||
If a library requires
|
||||
all clients to use specific <code>#include</code> paths or macros when compiling
|
||||
code that depends on the library, that information can be cleanly
|
||||
represented.</para>
|
||||
|
||||
<para>The difference between <code>lib</code> and <code>dll</code> targets in V1 is completely
|
||||
eliminated in V2. There's only one library target type, <code>lib</code>, which can create
|
||||
either static or shared libraries depending on the value of the
|
||||
<link linkend="bbv2.advanced.builtins.features.link"><varname><link></varname>
|
||||
feature</link>. If your target should be only built in one way<!--"variant" has a different meaning here-->, you
|
||||
can add <code><link>shared</code> or <code><link>static</code> to its requirements.
|
||||
</para>
|
||||
|
||||
<para>The syntax for referring to other targets was changed a bit. While
|
||||
in V1 one would use:
|
||||
<programlisting>
|
||||
exe a : a.cpp <lib>../foo/bar ;
|
||||
</programlisting>
|
||||
the V2 syntax is:
|
||||
<programlisting>
|
||||
exe a : a.cpp ../foo//bar ;
|
||||
</programlisting>
|
||||
Note that you don't need to specify the type of other target, but the
|
||||
last element should be separated from the others by a double slash to indicate that
|
||||
you're referring to target <filename>bar</filename> in project <filename>../foo</filename>, and not to
|
||||
project <filename>../foo/bar</filename>.
|
||||
</para>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.differences_to_v1.build_process">
|
||||
<title>Build process</title>
|
||||
|
||||
<para>The command line syntax in V2 is completely different. For example
|
||||
<programlisting>
|
||||
bjam -sTOOLS=msvc -sBUILD=release some_target
|
||||
</programlisting>
|
||||
now becomes:
|
||||
<programlisting>
|
||||
bjam toolset=msvc variant=release some_target
|
||||
</programlisting>
|
||||
or, using implicit features, just:
|
||||
<programlisting>
|
||||
bjam msvc release some_target
|
||||
</programlisting>
|
||||
See <link linkend="bbv2.reference.commandline">the reference</link> for a
|
||||
complete description of the syntax.
|
||||
</para>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
|
||||
@@ -228,49 +228,90 @@ target1 debug gcc/runtime-link=dynamic,static
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.reference.jamfiles">
|
||||
<title>Writing Jamfiles</title>
|
||||
<section id="bbv2.advanced.other-rules">
|
||||
<title>Jamfile Utility Rules</title>
|
||||
|
||||
<para>This section describes specific information about writing Jamfiles.</para>
|
||||
|
||||
<section id="bbv2.reference.headers">
|
||||
<title>Generated headers</title>
|
||||
|
||||
<para>Usually, Boost.Build handles implicit dependendies completely
|
||||
automatically. For example, for C++ files, all <literal>#include</literal>
|
||||
statements are found and handled. The only aspect where user help
|
||||
might be needed is implicit dependency on generated files.</para>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
<para>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
|
||||
<literal><implicit-dependency></literal> [ link ] feature must
|
||||
be used, for example:</para>
|
||||
|
||||
<programlisting>
|
||||
lib parser : parser.y ;
|
||||
exe app : app.cpp : <implicit-dependency>parser ;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
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.
|
||||
<para>The following table describes utility rules that can be
|
||||
used in Jamfiles. Detailed information for any of these rules can
|
||||
be obtained by running:
|
||||
<screen>
|
||||
bjam --help project.<replaceable>rulename</replaceable>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title/>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Rule</entry>
|
||||
|
||||
<entry>Semantics</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><link linkend=
|
||||
"bbv2.advanced.projects.attributes.projectrule">project</link>
|
||||
</entry>
|
||||
|
||||
<entry>Define this project's symbolic ID or attributes.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><xref linkend=
|
||||
"bbv2.advanced.projects.relationships.useprojectrule">use-project</xref></entry>
|
||||
|
||||
<entry>Make another project known so that it can be referred to by symbolic ID.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><xref linkend=
|
||||
"bbv2.advanced.projects.relationships.buildprojectrule">build-project</xref></entry>
|
||||
|
||||
<entry>Cause another project to be built when this one is built.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><xref linkend=
|
||||
"bbv2.reference.buildprocess.explict">explicit</xref></entry>
|
||||
|
||||
<entry>State that a target should be built only by explicit
|
||||
request.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>glob</entry>
|
||||
|
||||
<entry>Translate a list of shell-style wildcards into a
|
||||
corresponding list of files.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>constant</entry>
|
||||
|
||||
<entry>Injects a variable setting into this project's
|
||||
Jamfile module and those of all its subprojects.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>path-constant</entry>
|
||||
|
||||
<entry>Injects a variable set to a path value into
|
||||
this project's Jamfile module and those of all its subprojects.
|
||||
If the value is a relative path it will be adjusted for
|
||||
each subproject so that it refers to the same
|
||||
directory.</entry>
|
||||
</row>
|
||||
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.reference.buildprocess">
|
||||
<title>Build process</title>
|
||||
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE part PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
<!DOCTYPE book PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<part xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
<book xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
id="bbv2" last-revision="$Date$">
|
||||
|
||||
<title>Boost.Build v2 User Manual</title>
|
||||
<title>Boost.Build V2 User Manual</title>
|
||||
|
||||
<!-- Chapters -->
|
||||
<xi:include href="howto.xml"/>
|
||||
<xi:include href="install.xml"/>
|
||||
<xi:include href="tutorial.xml"/>
|
||||
<xi:include href="advanced.xml"/>
|
||||
<xi:include href="tasks.xml"/>
|
||||
<xi:include href="extending.xml"/>
|
||||
<xi:include href="reference.xml"/>
|
||||
<xi:include href="faq.xml"/>
|
||||
|
||||
<!-- Appendicies -->
|
||||
<xi:include href="architecture.xml"/>
|
||||
<!-- <xi:include href="architecture.xml"/> -->
|
||||
<appendix id="bbv2.jam">
|
||||
<title>Boost.Jam documentation</title>
|
||||
<title>Boost.Jam Documentation</title>
|
||||
<xi:include href="jam_docs.xml" parse="xml"
|
||||
xpointer="xpointer(id('jam.intro')|id('jam.intro')/following-sibling::*)"/>
|
||||
</appendix>
|
||||
|
||||
</part>
|
||||
<xi:include href="v1_vs_v2.xml"/>
|
||||
|
||||
</book>
|
||||
|
||||
@@ -5,18 +5,20 @@
|
||||
<part xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
id="bbv2" last-revision="$Date$">
|
||||
|
||||
<title>Boost.Build v2 User Manual</title>
|
||||
<title>Boost.Build V2 User Manual</title>
|
||||
|
||||
<!-- Chapters -->
|
||||
<xi:include href="howto.xml"/>
|
||||
<xi:include href="install.xml"/>
|
||||
<xi:include href="tutorial.xml"/>
|
||||
<xi:include href="advanced.xml"/>
|
||||
<xi:include href="tasks.xml"/>
|
||||
<xi:include href="extending.xml"/>
|
||||
<xi:include href="reference.xml"/>
|
||||
<xi:include href="faq.xml"/>
|
||||
|
||||
<!-- Appendicies -->
|
||||
<xi:include href="architecture.xml"/>
|
||||
<!-- <xi:include href="architecture.xml"/> -->
|
||||
<xi:include href="v1_vs_v2.xml"/>
|
||||
|
||||
</part>
|
||||
|
||||
@@ -5,12 +5,21 @@
|
||||
|
||||
# Create the packages
|
||||
set -e
|
||||
trap "echo 'Nightly build failed'" ERR
|
||||
|
||||
export QTDIR=/usr/share/qt3
|
||||
export LC_ALL=C
|
||||
export LC_MESSAGES=C
|
||||
export LANG=C
|
||||
cd /tmp
|
||||
rm -rf boost-build
|
||||
echo "Checking out sources"
|
||||
cvs -d :ext:vladimir_prus@boost.cvs.sourceforge.net:/cvsroot/boost co -P -d boost-build boost/tools > /tmp/boost_build_checkout_log
|
||||
mv /tmp/boost_build_checkout_log boost-build/checkout-log
|
||||
cd boost-build/build/v2
|
||||
./roll.sh > ../roll-log
|
||||
echo "Building packages and uploading docs"
|
||||
./roll.sh > ../roll-log 2>&1
|
||||
cd ..
|
||||
scp boost-build.zip boost-build.tar.bz2 vladimir_prus@shell.sf.net:/home/groups/b/bo/boost/htdocs/boost-build2 > scp-log
|
||||
echo "Upload successfull"
|
||||
echo "Uploading packages"
|
||||
scp boost-build.zip boost-build.tar.bz2 vladimir_prus@shell.sourceforge.net:/home/groups/b/bo/boost/htdocs/boost-build2 > scp-log
|
||||
echo "Nightly build successful"
|
||||
|
||||
@@ -234,6 +234,13 @@ class Tester(TestCmd.TestCmd):
|
||||
self.wait_for_time_change()
|
||||
self.write(dst, self.read(src))
|
||||
|
||||
def copy_preserving_timestamp(self, src, dst):
|
||||
src_name = self.native_file_name(src)
|
||||
dst_name = self.native_file_name(dst)
|
||||
stats = os.stat(src_name)
|
||||
self.write(dst, self.read(src))
|
||||
os.utime(dst_name, (stats.st_atime, stats.st_mtime))
|
||||
|
||||
def touch(self, names):
|
||||
self.wait_for_time_change()
|
||||
for name in self.adjust_names(names):
|
||||
|
||||
@@ -9,12 +9,13 @@ from BoostBuild import Tester, List
|
||||
|
||||
t = Tester()
|
||||
|
||||
t.write("project-root.jam", "")
|
||||
t.write("Jamfile", """
|
||||
alias everything : [ exe a : a.cpp ] ;
|
||||
t.write("Jamroot", """
|
||||
project : requirements <link>static ;
|
||||
exe a : a.cpp [ lib helper : helper.cpp ] ;
|
||||
""")
|
||||
|
||||
t.write("a.cpp", """
|
||||
t.write("a.cpp", """
|
||||
extern void helper();
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
@@ -22,29 +23,49 @@ int main()
|
||||
|
||||
""")
|
||||
|
||||
t.run_build_system()
|
||||
t.expect_addition("bin/$toolset/debug/everything__a.exe")
|
||||
t.rm("bin/$toolset/debug/everything__a.exe")
|
||||
t.write("helper.cpp", """
|
||||
void helper()
|
||||
{
|
||||
}
|
||||
""")
|
||||
|
||||
t.run_build_system("everything__a")
|
||||
t.expect_addition("bin/$toolset/debug/everything__a.exe")
|
||||
t.run_build_system()
|
||||
t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib")
|
||||
t.rm("bin/$toolset/debug/link-static/a__helper.lib")
|
||||
|
||||
t.run_build_system("a__helper")
|
||||
t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib")
|
||||
|
||||
t.rm("bin")
|
||||
|
||||
# Now check that inline targets with the same name but
|
||||
# present in different places are not confused between
|
||||
# each other, and with top-level targets.
|
||||
t.write("Jamfile", """
|
||||
exe a : a.cpp ;
|
||||
alias everything : [ exe a : a.cpp ] ;
|
||||
alias everything2 : [ exe a : a.cpp ] ;
|
||||
t.write("Jamroot", """
|
||||
project : requirements <link>static ;
|
||||
exe a : a.cpp [ lib helper : helper.cpp ] ;
|
||||
exe a2 : a.cpp [ lib helper : helper.cpp ] ;
|
||||
""")
|
||||
|
||||
t.run_build_system()
|
||||
t.expect_addition("bin/$toolset/debug/a.exe")
|
||||
t.expect_addition("bin/$toolset/debug/everything__a.exe")
|
||||
t.expect_addition("bin/$toolset/debug/everything2__a.exe")
|
||||
t.expect_addition("bin/$toolset/debug/link-static/a.exe")
|
||||
t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib")
|
||||
t.expect_addition("bin/$toolset/debug/link-static/a2__helper.lib")
|
||||
|
||||
# Check that the 'alias' target does not change name of
|
||||
# inline targets, and that inline targets are explicit.
|
||||
t.write("Jamroot", """
|
||||
project : requirements <link>static ;
|
||||
alias a : [ lib helper : helper.cpp ] ;
|
||||
explicit a ;
|
||||
""")
|
||||
t.rm("bin")
|
||||
|
||||
t.run_build_system()
|
||||
t.expect_nothing_more()
|
||||
|
||||
t.run_build_system("a")
|
||||
t.expect_addition("bin/$toolset/debug/link-static/helper.lib")
|
||||
|
||||
t.cleanup()
|
||||
|
||||
|
||||
@@ -41,9 +41,35 @@ int main() { return 0; }
|
||||
|
||||
t.run_build_system()
|
||||
|
||||
|
||||
t.expect_addition("child/bin/$toolset/debug/main.exe")
|
||||
t.fail_test(find(t.stdout(), "Setting child requirements") <
|
||||
find(t.stdout(), "Setting parent requirements"))
|
||||
|
||||
|
||||
# Regression test: parent requirements were ignored in some cases
|
||||
t.rm(".")
|
||||
t.write("Jamroot", """
|
||||
build-project src ;
|
||||
""")
|
||||
|
||||
t.write("src/Jamfile", """
|
||||
project : requirements <define>EVERYTHING_OK ;
|
||||
""")
|
||||
|
||||
t.write("src/app/Jamfile", """
|
||||
exe test : test.cpp ;
|
||||
""")
|
||||
|
||||
t.write("src/app/test.cpp", """
|
||||
#ifdef EVERYTHING_OK
|
||||
int main() {}
|
||||
#endif
|
||||
|
||||
""")
|
||||
|
||||
t.run_build_system(subdir="src/app")
|
||||
t.expect_addition("src/app/bin/$toolset/debug/test.exe")
|
||||
|
||||
|
||||
t.cleanup()
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#
|
||||
# 02/21/02! Jürgen Hunold
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# ================================================================
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ if os.name == 'posix':
|
||||
|
||||
if string.find(get_toolset(), 'gcc') == 0:
|
||||
tests.append("gcc_runtime")
|
||||
tests.append("pch")
|
||||
|
||||
if "--extras" in sys.argv:
|
||||
tests.append("boostbook")
|
||||
|
||||
@@ -25,9 +25,61 @@ import project ;
|
||||
|
||||
# This feature is used to determine which OS we're on.
|
||||
# In future, this may become <target-os> and <host-os>
|
||||
# The future is now...
|
||||
local os = [ modules.peek : OS ] ;
|
||||
feature os : $(os) : propagated link-incompatible ;
|
||||
|
||||
# Translates from bjam current OS to the os tags used
|
||||
# in host-os and target-os. I.e. it returns the
|
||||
# running host-os.
|
||||
local rule default-host-os ( )
|
||||
{
|
||||
local host-os ;
|
||||
local os-list = [ feature.values host-os ] ;
|
||||
if [ os.name ] in $(os-list:U)
|
||||
{
|
||||
host-os = [ os.name ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch [ os.name ]
|
||||
{
|
||||
case NT : host-os = windows ;
|
||||
case AS400 : host-os = unix ;
|
||||
case MINGW : host-os = windows ;
|
||||
case BSDI : host-os = bsd ;
|
||||
case COHERENT : host-os = unix ;
|
||||
case DRAGONFLYBSD : host-os = bsd ;
|
||||
case IRIX : host-os = sgi ;
|
||||
case MACOSX : host-os = darwin ;
|
||||
case KFREEBSD : host-os = freebsd ;
|
||||
case LINUX : host-os = linux ;
|
||||
case * : host-os = unix ;
|
||||
}
|
||||
}
|
||||
return $(host-os:L) ;
|
||||
}
|
||||
|
||||
# The two OS features define a known set of abstract OS
|
||||
# names. The host-os is the OS under which bjam is running.
|
||||
# Even though this should really be a fixed property we need
|
||||
# to list all the values to prevent unkown value errors.
|
||||
# Both set the default value to the current OS to account for
|
||||
# the default use case of building on the target OS.
|
||||
feature host-os
|
||||
: amiga aix bsd cygwin darwin dos emx freebsd hpux
|
||||
linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos
|
||||
svr4 sysv ultrix unix unixware vms windows
|
||||
: optional ;
|
||||
feature.set-default host-os : [ default-host-os ] ;
|
||||
feature target-os
|
||||
: amiga aix bsd cygwin darwin dos emx freebsd hpux
|
||||
linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos
|
||||
svr4 sysv ultrix unix unixware vms windows
|
||||
: propagated link-incompatible ;
|
||||
feature.set-default target-os : [ default-host-os ] ;
|
||||
|
||||
|
||||
feature toolset : : implicit propagated symmetric ;
|
||||
|
||||
feature stdlib : native : propagated composite ;
|
||||
@@ -405,8 +457,8 @@ class lib-generator : generator
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
# Determine the needed target type
|
||||
local actual-type ;
|
||||
# <source>files can be generated by <conditional>@rule feature
|
||||
# in which case we don't consider it a SEARCHED_LIB type.
|
||||
# <source>files can be generated by <conditional>@rule feature
|
||||
# in which case we don't consider it a SEARCHED_LIB type.
|
||||
if ! <source> in $(properties:G) &&
|
||||
( <search> in $(properties:G) || <name> in $(properties:G) )
|
||||
{
|
||||
@@ -428,7 +480,7 @@ class lib-generator : generator
|
||||
property-set = [ $(property-set).add-raw <main-target-type>LIB ] ;
|
||||
# Construct the target.
|
||||
return [ generators.construct $(project) $(name) : $(actual-type)
|
||||
: $(property-set) : $(sources) : LIB ] ;
|
||||
: $(property-set) : $(sources) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,6 +499,7 @@ generators.register [ new lib-generator builtin.lib-generator : : LIB ] ;
|
||||
rule lib ( names + : sources * : requirements * : default-build *
|
||||
: usage-requirements * )
|
||||
{
|
||||
local result ;
|
||||
local project = [ project.current ] ;
|
||||
|
||||
# This is a circular module dependency, so it must be imported here
|
||||
@@ -842,6 +895,20 @@ rule register-archiver ( id composing ? : source-types + : target-types + :
|
||||
generators.register $(g) ;
|
||||
}
|
||||
|
||||
# Generators that accepts everything, and produces nothing.
|
||||
# Usefull as general fallback for toolset-specific actions, like
|
||||
# PCH generation.
|
||||
class dummy-generator : generator
|
||||
{
|
||||
import property-set ;
|
||||
|
||||
rule run ( project name ? : property-set : sources + )
|
||||
{
|
||||
return [ property-set.empty ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
IMPORT $(__name__) : register-linker register-archiver
|
||||
: : generators.register-linker generators.register-archiver ;
|
||||
|
||||
@@ -16,6 +16,7 @@ import errors ;
|
||||
import path ;
|
||||
import sequence ;
|
||||
import toolset ;
|
||||
import virtual-target ;
|
||||
|
||||
if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
|
||||
{
|
||||
@@ -565,6 +566,148 @@ actions quietly updated piecemeal together RmTemps
|
||||
$(RM) "$(>)" $(IGNORE)
|
||||
}
|
||||
|
||||
rule format-name ( format * : name : type ? : property-set )
|
||||
{
|
||||
if [ type.is-derived $(type) LIB ]
|
||||
{
|
||||
local result = "" ;
|
||||
for local f in $(format)
|
||||
{
|
||||
switch $(f:G)
|
||||
{
|
||||
case <base> :
|
||||
result += $(name:B) ;
|
||||
|
||||
case <toolset> :
|
||||
result += [ join-tag $(f:G=) :
|
||||
[ toolset-tag $(name) : $(type) : $(property-set) ] ] ;
|
||||
|
||||
case <threading> :
|
||||
result += [ join-tag $(f:G=) :
|
||||
[ threading-tag $(name) : $(type) : $(property-set) ] ] ;
|
||||
|
||||
case <threading> :
|
||||
result += [ join-tag $(f:G=) :
|
||||
[ runtime-tag $(name) : $(type) : $(property-set) ] ] ;
|
||||
|
||||
case <version:*> :
|
||||
local key = [ MATCH <version:(.*)> : $(f:G) ] ;
|
||||
local version = [ $(property-set).get <$(key)> ] ;
|
||||
version ?= $(key) ;
|
||||
version = [ MATCH "^([^.]+)[.]([^.]+)[.]([^.]+)"
|
||||
: $(version) ] ;
|
||||
result += [ join-tag $(f:G=) : $(version[1])_$(version[2]) ] ;
|
||||
|
||||
case <property:*> :
|
||||
local key = [ MATCH <property:(.*)> : $(f:G) ] ;
|
||||
local p = [ $(property-set).get [ MATCH <property:(.*)> : $(f:G) ] ] ;
|
||||
if $(p)
|
||||
{
|
||||
result += [ join-tag $(f:G=) : $(p) ] ;
|
||||
}
|
||||
|
||||
case * :
|
||||
result += $(f:G=) ;
|
||||
}
|
||||
}
|
||||
result = [ virtual-target.add-prefix-and-suffix
|
||||
$(result:J=) : $(type) : $(property-set) ] ;
|
||||
return $(result) ;
|
||||
}
|
||||
}
|
||||
|
||||
local rule join-tag ( joiner ? : tag ? )
|
||||
{
|
||||
if ! $(joinder) { joiner = - ; }
|
||||
return $(joiner)$(tag) ;
|
||||
}
|
||||
|
||||
local rule toolset-tag ( name : type ? : property-set )
|
||||
{
|
||||
local tag = ;
|
||||
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
switch [ $(property-set).get <toolset> ]
|
||||
{
|
||||
case borland* : tag += bcb ;
|
||||
case como* : tag += como ;
|
||||
case cw : tag += cw ;
|
||||
case darwin* : tag += ;
|
||||
case edg* : tag += edg ;
|
||||
case gcc* : tag += gcc ;
|
||||
case intel :
|
||||
if [ $(property-set).get <toolset-intel:platform> ] = win
|
||||
{
|
||||
tag += iw ;
|
||||
}
|
||||
else
|
||||
{
|
||||
tag += il ;
|
||||
}
|
||||
case kcc* : tag += kcc ;
|
||||
case kylix* : tag += bck ;
|
||||
#case metrowerks* : tag += cw ;
|
||||
#case mingw* : tag += mgw ;
|
||||
case mipspro* : tag += mp ;
|
||||
case msvc* : tag += vc ;
|
||||
case sun* : tag += sw ;
|
||||
case tru64cxx* : tag += tru ;
|
||||
case vacpp* : tag += xlc ;
|
||||
}
|
||||
local version = [ MATCH "<toolset.*version>([0123456789]+)[.]([0123456789]*)"
|
||||
: $(properties) ] ;
|
||||
# For historical reasons, vc6.0 and vc7.0 use different
|
||||
# naming.
|
||||
if $(tag) = vc
|
||||
{
|
||||
if $(version[1]) = 6
|
||||
{
|
||||
# Cancel minor version.
|
||||
version = 6 ;
|
||||
}
|
||||
else if $(version[1]) = 7 && $(version[2]) = 0
|
||||
{
|
||||
version = 7 ;
|
||||
}
|
||||
}
|
||||
# On intel, version is not added, because it does not
|
||||
# matter and it's the version of vc used as backend
|
||||
# that matters. Ideally, we'd encode the backend
|
||||
# version but that will break compatibility with
|
||||
# V1.
|
||||
if $(tag) = iw
|
||||
{
|
||||
version = ;
|
||||
}
|
||||
tag += $(version) ;
|
||||
|
||||
return $(tag:J=) ;
|
||||
}
|
||||
|
||||
local rule threading-tag ( name : type ? : property-set )
|
||||
{
|
||||
local tag = ;
|
||||
if <threading>multi in $(properties) { tag = mt ; }
|
||||
|
||||
return $(tag:J=) ;
|
||||
}
|
||||
|
||||
local rule runtime-tag ( name : type ? : property-set )
|
||||
{
|
||||
local tag = ;
|
||||
|
||||
local properties = [ $(property-set).raw ] ;
|
||||
if <runtime-link>static in $(properties) { tag += s ; }
|
||||
if <runtime-debugging>on in $(properties) { tag += g ; }
|
||||
|
||||
if <variant>debug-python in $(properties) { tag += y ; }
|
||||
if <variant>debug in $(properties) { tag += d ; }
|
||||
if <stdlib>stlport in $(properties) { tag += p ; }
|
||||
if <stdlib-stlport:iostream>hostios in $(properties) { tag += n ; }
|
||||
|
||||
return $(tag:J=) ;
|
||||
}
|
||||
|
||||
rule __test__ ( ) {
|
||||
|
||||
import assert ;
|
||||
|
||||
110
v2/tools/gcc.jam
110
v2/tools/gcc.jam
@@ -1,6 +1,8 @@
|
||||
# Copyright 2001 David Abrahams.
|
||||
# Copyright 2002-2006 Rene Rivera.
|
||||
# Copyright 2002-2003 Vladimir Prus.
|
||||
# Copyright (c) 2005 Reece H. Dunn.
|
||||
# Copyright 2006 Ilya Sokolov.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -16,6 +18,8 @@ import "class" : new ;
|
||||
import set ;
|
||||
import common ;
|
||||
import errors ;
|
||||
import property-set ;
|
||||
import pch ;
|
||||
|
||||
if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
|
||||
{
|
||||
@@ -144,6 +148,84 @@ generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : <toolset>gcc ;
|
||||
generators.register-c-compiler gcc.compile.c : C : OBJ : <toolset>gcc ;
|
||||
generators.register-c-compiler gcc.compile.asm : ASM : OBJ : <toolset>gcc ;
|
||||
|
||||
# pch support
|
||||
|
||||
# The compiler looks for a precompiled header in each directory just
|
||||
# before it looks for the include file in that directory.
|
||||
# The name searched for is the name specified in the #include directive
|
||||
# with ".gch" suffix appended.
|
||||
# The logic in gcc-pch-generator will make sure that BASE_PCH suffix is
|
||||
# appended to full name of the header.
|
||||
|
||||
type.set-generated-target-suffix PCH : <toolset>gcc : gch ;
|
||||
|
||||
# GCC-specific pch generator.
|
||||
class gcc-pch-generator : pch-generator
|
||||
{
|
||||
import project ;
|
||||
import property-set ;
|
||||
import type ;
|
||||
|
||||
rule run-pch ( project name ? : property-set : sources + )
|
||||
{
|
||||
# Find the header in sources. Ignore any CPP sources.
|
||||
local header ;
|
||||
for local s in $(sources)
|
||||
{
|
||||
if [ type.is-derived [ $(s).type ] H ]
|
||||
{
|
||||
header = $(s) ;
|
||||
}
|
||||
}
|
||||
|
||||
# error handling
|
||||
# base name of header file should be the same as the base name
|
||||
# of precompiled header.
|
||||
local header-name = [ $(header).name ] ;
|
||||
local header-basename = $(header-name:B) ;
|
||||
if $(header-basename) != $(name)
|
||||
{
|
||||
local location = [ $(project).project-module ] ;
|
||||
errors.user-error "in" $(location)": pch target name `"$(name)"' should be the same as the base name of header file `"$(header-name)"'" ;
|
||||
}
|
||||
|
||||
local pch-file =
|
||||
[
|
||||
generator.run $(project) $(name)
|
||||
: $(property-set)
|
||||
: $(header)
|
||||
]
|
||||
;
|
||||
|
||||
# return result of base class and pch-file property as usage-requirements
|
||||
return
|
||||
[ property-set.create <pch-file>$(pch-file) ]
|
||||
$(pch-file)
|
||||
;
|
||||
}
|
||||
|
||||
# Calls the base version specifying source's name as the
|
||||
# name of the created target. As result, the PCH will be named
|
||||
# whatever.hpp.gch, and not whatever.gch.
|
||||
rule generated-targets ( sources + : property-set : project name ? )
|
||||
{
|
||||
name = [ $(sources[1]).name ] ;
|
||||
return [ generator.generated-targets $(sources)
|
||||
: $(property-set) : $(project) $(name) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The latter
|
||||
# have HPP type, but HPP type is derived from H. The type of compilation is determined
|
||||
# entirely by the destination type.
|
||||
generators.register [ new gcc-pch-generator gcc.compile.c.pch : H : C_PCH : <pch>on <toolset>gcc ] ;
|
||||
generators.register [ new gcc-pch-generator gcc.compile.c++.pch : H : CPP_PCH : <pch>on <toolset>gcc ] ;
|
||||
|
||||
# Override default do-nothing generators.
|
||||
generators.override gcc.compile.c.pch : pch.default-c-pch-generator ;
|
||||
generators.override gcc.compile.c++.pch : pch.default-cpp-pch-generator ;
|
||||
|
||||
flags gcc.compile PCH_FILE <pch>on : <pch-file> ;
|
||||
|
||||
# Declare flags and action for compilation
|
||||
flags gcc.compile OPTIONS <optimization>off : -O0 ;
|
||||
@@ -205,6 +287,16 @@ flags gcc.compile.c++ USER_OPTIONS <cxxflags> ;
|
||||
flags gcc.compile DEFINES <define> ;
|
||||
flags gcc.compile INCLUDES <include> ;
|
||||
|
||||
actions compile.c++.pch
|
||||
{
|
||||
"$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
|
||||
}
|
||||
|
||||
actions compile.c.pch
|
||||
{
|
||||
"$(CONFIG_COMMAND)" -x c-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
|
||||
}
|
||||
|
||||
rule compile.c++
|
||||
{
|
||||
# Some extensions are compiled as C++ by default. For others, we need
|
||||
@@ -214,12 +306,7 @@ rule compile.c++
|
||||
{
|
||||
LANG on $(<) = "-x c++" ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
actions compile.c++
|
||||
{
|
||||
"$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-128 $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
|
||||
DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
|
||||
}
|
||||
|
||||
rule compile.c
|
||||
@@ -231,12 +318,17 @@ rule compile.c
|
||||
#{
|
||||
LANG on $(<) = "-x c" ;
|
||||
#}
|
||||
DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
|
||||
}
|
||||
|
||||
|
||||
actions compile.c
|
||||
actions compile.c++ bind PCH_FILE
|
||||
{
|
||||
"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
|
||||
"$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-128 $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<:W)" "$(>:W)"
|
||||
}
|
||||
|
||||
actions compile.c bind PCH_FILE
|
||||
{
|
||||
"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
|
||||
}
|
||||
|
||||
rule compile.asm
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Copyright (c) 2005 Vladimir Prus.
|
||||
# Copyright (c) 2005 Alexey Pakhunov.
|
||||
# Copyright (c) 2006 Bojan Resnik.
|
||||
# Copyright (c) 2006 Ilya Sokolov.
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software
|
||||
# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
|
||||
@@ -534,7 +535,92 @@ generators.override msvc.compile.idl : midl.compile.idl ;
|
||||
generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
|
||||
generators.override msvc.compile.mc : mc.compile ;
|
||||
|
||||
generators.register [ new pch-generator msvc.compile.pch : PCHEADER : OBJ PCH : <toolset>msvc ] ;
|
||||
# pch support
|
||||
|
||||
feature pch-source : : free dependency ;
|
||||
|
||||
class msvc-pch-generator : pch-generator
|
||||
{
|
||||
import property-set ;
|
||||
|
||||
rule run-pch ( project name ? : property-set : source-1 source-2 )
|
||||
{
|
||||
# searching header and source file in the sources
|
||||
local sources = $(source-1) $(source-2) ;
|
||||
local pch-header ;
|
||||
local pch-source ;
|
||||
for local s in $(sources)
|
||||
{
|
||||
if [ type.is-derived [ $(s).type ] H ]
|
||||
{
|
||||
pch-header = $(s) ;
|
||||
}
|
||||
else if
|
||||
[ type.is-derived [ $(s).type ] CPP ]
|
||||
|| [ type.is-derived [ $(s).type ] C ]
|
||||
{
|
||||
pch-source = $(s) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ! $(pch-header)
|
||||
{
|
||||
errors.user-error "can't build pch without pch-header" ;
|
||||
}
|
||||
|
||||
if ! $(pch-source)
|
||||
{
|
||||
errors.user-error "can't build pch without pch-source" ;
|
||||
}
|
||||
|
||||
local generated =
|
||||
[
|
||||
# Passing of <pch-source> is a dirty trick,
|
||||
# needed because non-composing generators
|
||||
# with multiple inputs are subtly broken:
|
||||
# https://zigzag.cs.msu.su:7813/boost.build/ticket/111
|
||||
generator.run $(project) $(name)
|
||||
: [
|
||||
property-set.create
|
||||
<pch-source>$(pch-source)
|
||||
[ $(property-set).raw ]
|
||||
]
|
||||
: $(pch-header)
|
||||
]
|
||||
;
|
||||
|
||||
local pch-file ;
|
||||
for local g in $(generated)
|
||||
{
|
||||
if [ type.is-derived [ $(g).type ] PCH ]
|
||||
{
|
||||
pch-file = $(g) ;
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
[
|
||||
property-set.create
|
||||
<pch-header>$(pch-header)
|
||||
<pch-file>$(pch-file)
|
||||
]
|
||||
$(generated)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The latter
|
||||
# have HPP type, but HPP type is derived from H. The type of compilation is determined
|
||||
# entirely by the destination type.
|
||||
generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
|
||||
generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
|
||||
|
||||
generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
|
||||
generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
|
||||
|
||||
flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
|
||||
flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
|
||||
flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
|
||||
|
||||
#
|
||||
# Declare flags and action for compilation
|
||||
@@ -580,10 +666,6 @@ flags msvc.compile DEFINES <define> ;
|
||||
flags msvc.compile UNDEFS <undef> ;
|
||||
flags msvc.compile INCLUDES <include> ;
|
||||
|
||||
flags msvc.compile PCH_SOURCE <pch-source> ;
|
||||
flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
|
||||
flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
|
||||
|
||||
rule get-rspline ( target : lang-opt )
|
||||
{
|
||||
CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS) $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(nl)-D$(DEFINES) $(nl)\"-I$(INCLUDES)\" ] ;
|
||||
@@ -609,20 +691,30 @@ rule compile.c ( targets + : sources * : properties * )
|
||||
|
||||
rule compile.c++ ( targets + : sources * : properties * )
|
||||
{
|
||||
get-rspline $(targets[1]) : -TP ;
|
||||
get-rspline $(targets) : -TP ;
|
||||
compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
|
||||
}
|
||||
|
||||
actions compile-pch
|
||||
actions compile-c-c++-pch
|
||||
{
|
||||
$(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[1]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[2]:W)" $(CC_RSPLINE))"
|
||||
$(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" -Yl"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))"
|
||||
}
|
||||
|
||||
rule compile.pch ( targets + : sources * : properties * )
|
||||
rule compile.c.pch ( targets + : sources * : properties * )
|
||||
{
|
||||
C++FLAGS on $(targets[1]) = ;
|
||||
DEPENDS $(<) : [ on $(<) return $(PCH_SOURCE) ] ;
|
||||
get-rspline $(targets[1]) : -TC ;
|
||||
get-rspline $(targets[2]) : -TC ;
|
||||
compile-c-c++-pch $(targets) : $(sources) [ on $(<) return $(PCH_SOURCE) ] ;
|
||||
}
|
||||
|
||||
rule compile.c++.pch ( targets + : sources * : properties * )
|
||||
{
|
||||
DEPENDS $(<) : [ on $(<) return $(PCH_SOURCE) ] ;
|
||||
get-rspline $(targets[1]) : -TP ;
|
||||
compile-pch $(targets) : $(sources) [ on $(<) return $(PCH_SOURCE) ] ;
|
||||
get-rspline $(targets[2]) : -TP ;
|
||||
compile-c-c++-pch $(targets) : $(sources) [ on $(<) return $(PCH_SOURCE) ] ;
|
||||
}
|
||||
|
||||
actions compile.rc
|
||||
|
||||
116
v2/tools/pch.jam
116
v2/tools/pch.jam
@@ -1,79 +1,93 @@
|
||||
# Copyright (c) 2005 Reece H. Dunn.
|
||||
# Copyright 2006 Ilya Sokolov
|
||||
#
|
||||
# Use, modification and distribution is subject to the Boost Software
|
||||
# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
##### Using Precompiled Headers (Quick Guide) #####
|
||||
#
|
||||
# Make precompiled mypch.hpp:
|
||||
#
|
||||
# import pch ;
|
||||
#
|
||||
# cpp-pch mypch
|
||||
# : # sources
|
||||
# mypch.hpp
|
||||
# : # requiremnts
|
||||
# <toolset>msvc:<source>mypch.cpp
|
||||
# ;
|
||||
#
|
||||
# Add cpp-pch to sources:
|
||||
#
|
||||
# exe hello
|
||||
# : main.cpp hello.cpp mypch
|
||||
# ;
|
||||
|
||||
import "class" : new ;
|
||||
import type ;
|
||||
import feature : feature ;
|
||||
import feature ;
|
||||
import generators ;
|
||||
|
||||
##### Using Pre-compiled Headers (Quick Guide) #####
|
||||
#
|
||||
# Make mypch.hpp a pre-compiled header (PCH) using mypch.cpp as the source file:
|
||||
# import cast ;
|
||||
# pch mypch : [ cast _ pcheader : pch.hpp ] pch.cpp ;
|
||||
#
|
||||
# Enable PCHs in a target:
|
||||
# exe hello : mypch main.cpp hello.cpp ;
|
||||
# ^^^^^ -- mypch.hpp is a PCH
|
||||
#
|
||||
# Don't use PCHs for a specific source:
|
||||
# obj nopch : nopch.cpp : <pch>off ;
|
||||
#
|
||||
type.register PCH : pch ;
|
||||
|
||||
type.register PCH : pch ;
|
||||
type.register PCHEADER : pcheader ;
|
||||
type.register C_PCH : : PCH ;
|
||||
type.register CPP_PCH : : PCH ;
|
||||
|
||||
feature pch : # control precompiled header (PCH) generation
|
||||
on # this file has support for using PCHs (if available)
|
||||
off # this file doesn't use PCHs
|
||||
# control precompiled header (PCH) generation
|
||||
feature.feature pch :
|
||||
on
|
||||
off
|
||||
;
|
||||
|
||||
feature pch-source : : free dependency ; # mypch.cpp
|
||||
feature pch-header : : free dependency ; # mypch.h[pp]
|
||||
feature pch-file : : free dependency ; # mypch.pch
|
||||
feature.feature pch-header : : free dependency ;
|
||||
feature.feature pch-file : : free dependency ;
|
||||
|
||||
# Base PCH generator. The 'run' method has the logic to
|
||||
# prevent this generator from being run unless it's used
|
||||
# in top-level PCH target.
|
||||
class pch-generator : generator
|
||||
{
|
||||
import property-set ;
|
||||
|
||||
rule __init__ ( * : * )
|
||||
{
|
||||
generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
|
||||
}
|
||||
|
||||
rule action-class ( )
|
||||
{
|
||||
return compile-action ;
|
||||
}
|
||||
|
||||
rule run ( project name ? : property-set : sources * )
|
||||
rule run ( project name ? : property-set : sources + )
|
||||
{
|
||||
# The two sources are cpp file and PCHEADER, but they
|
||||
# can be passed in any order. Figure out which source
|
||||
# is what.
|
||||
local cpp = $(sources[2]) ;
|
||||
local h = $(sources[1]) ;
|
||||
if [ $(sources[2]).type ] = PCHEADER
|
||||
if ! $(name)
|
||||
{
|
||||
cpp = $(sources[1]) ;
|
||||
h = $(sources[2]) ;
|
||||
# Unless this generator is invoked as the top-most
|
||||
# generator for a main target, fail. This allows using
|
||||
# 'H' type as input type for this generator, while
|
||||
# preventing Boost.Build to try this generator when not
|
||||
# explicitly asked for.
|
||||
#
|
||||
# One bad example is msvc, where pch generator produces
|
||||
# both PCH target and OBJ target, so if there's any
|
||||
# header generated (like by bison, or by msidl), we'd
|
||||
# try to use pch generator to get OBJ from that H, which
|
||||
# is completely wrong. By restricting this generator
|
||||
# only to pch main target, such problem is solved.
|
||||
}
|
||||
|
||||
local r =
|
||||
[ generator.run $(project) $(name) :
|
||||
[
|
||||
property-set.create
|
||||
<pch-source>$(cpp) # mypch.cpp
|
||||
[ $(property-set).raw ]
|
||||
] : $(sources)
|
||||
] ;
|
||||
|
||||
return
|
||||
[ property-set.create
|
||||
<pch-header>$(h) # mypch.h[pp]
|
||||
<pch-file>$(r[2]) # mypch.pch
|
||||
] $(r) ;
|
||||
else
|
||||
{
|
||||
return [ run-pch $(project) $(name) : $(property-set)
|
||||
: $(sources) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# This rule must be overridden by the derived classes.
|
||||
rule run-pch ( project name ? : property-set : sources + )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
# NOTE: requiremetns are empty,
|
||||
# default pch generator can be applied when pch=off
|
||||
generators.register [
|
||||
new dummy-generator pch.default-c-pch-generator : : C_PCH ] ;
|
||||
generators.register [
|
||||
new dummy-generator pch.default-cpp-pch-generator : : CPP_PCH ] ;
|
||||
|
||||
@@ -150,7 +150,7 @@ class install-target-class : basic-target
|
||||
else
|
||||
{
|
||||
local targets = [ generators.construct $(self.project) $(name) :
|
||||
INSTALLED_$(t) : $(new-properties) : $(i) : * ] ;
|
||||
INSTALLED_$(t) : $(new-properties) : $(i) ] ;
|
||||
staged-targets += $(targets[2-]) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ class stlport-target-class : basic-target
|
||||
= [ targets.main-target-requirements
|
||||
[ $(lib-file.props).raw ] <file>$(lib-file[-1])
|
||||
: $(self.project) ] ;
|
||||
return [ generators.construct $(self.project) $(name) : LIB : $(lib-file.requirements) : : LIB ] ;
|
||||
return [ generators.construct $(self.project) $(name) : LIB : $(lib-file.requirements) ] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -155,19 +155,11 @@ rule run-fail ( sources + : args * : input-files * : requirements * : target-nam
|
||||
return [ make-test run-fail : $(sources) : $(requirements) : $(target-name) ] ;
|
||||
}
|
||||
|
||||
# Rule for grouping tests in suites.
|
||||
rule test-suite ( suite-name : tests + )
|
||||
{
|
||||
# In V2, if 'tests' are instances of 'abstract-target', they will be considered
|
||||
# 'inline-targets' and will suffer some adjustments. This will not be compatible
|
||||
# with V1 behaviour, so we get names of 'tests' and use them.
|
||||
local names ;
|
||||
for local t in $(tests)
|
||||
{
|
||||
names += [ $(t).name ] ;
|
||||
}
|
||||
modules.call-in [ CALLER_MODULE ] : alias $(suite-name) : $(names) ;
|
||||
}
|
||||
|
||||
# Use 'test-suite' as synonym for 'alias', for backward compatibility.
|
||||
IMPORT : alias : : test-suite ;
|
||||
|
||||
|
||||
|
||||
# For all main target in 'project-module',
|
||||
# which are typed target with type derived from 'TEST',
|
||||
@@ -442,8 +434,8 @@ actions unit-test
|
||||
$(LAUNCHER) $(>) && $(MAKE_FILE) $(<)
|
||||
}
|
||||
|
||||
IMPORT $(__name__) : compile compile-fail test-suite run run-fail link link-fail
|
||||
: : compile compile-fail test-suite run run-fail link link-fail ;
|
||||
IMPORT $(__name__) : compile compile-fail run run-fail link link-fail
|
||||
: : compile compile-fail run run-fail link link-fail ;
|
||||
|
||||
|
||||
type.register TIME : time ;
|
||||
|
||||
Reference in New Issue
Block a user