Re-organized boostbook files:
* Moved XML sources to src * Added reference.css from Reece Dunn to html dir * Added images from boost/doc/html so that local builds look ok [SVN r22175]
@ -1,3 +1,3 @@
|
||||
project tools/build/v2/doc ;
|
||||
|
||||
boostbook userman : userman.xml ;
|
||||
boostbook userman : src/userman.xml ;
|
||||
|
BIN
v2/doc/html/images/blank.png
Normal file
After Width: | Height: | Size: 374 B |
BIN
v2/doc/html/images/caution.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
v2/doc/html/images/draft.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
v2/doc/html/images/home.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
v2/doc/html/images/important.png
Normal file
After Width: | Height: | Size: 722 B |
BIN
v2/doc/html/images/next.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
v2/doc/html/images/note.png
Normal file
After Width: | Height: | Size: 490 B |
BIN
v2/doc/html/images/prev.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
v2/doc/html/images/tip.png
Normal file
After Width: | Height: | Size: 449 B |
BIN
v2/doc/html/images/toc-blank.png
Normal file
After Width: | Height: | Size: 318 B |
BIN
v2/doc/html/images/toc-minus.png
Normal file
After Width: | Height: | Size: 259 B |
BIN
v2/doc/html/images/toc-plus.png
Normal file
After Width: | Height: | Size: 264 B |
BIN
v2/doc/html/images/up.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
v2/doc/html/images/warning.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
76
v2/doc/html/reference.css
Normal file
@ -0,0 +1,76 @@
|
||||
th
|
||||
{
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title
|
||||
{
|
||||
font-weight: bold;
|
||||
font-size: 2pc;
|
||||
font-family: Times New Roman;
|
||||
margin-bottom: 1pc;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toc
|
||||
{
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
margin-bottom: 0pc;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.programlisting
|
||||
{
|
||||
margin-left: 3pc;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.computeroutput
|
||||
{
|
||||
font-family: Lucida Console;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.table
|
||||
{
|
||||
text-align: center;
|
||||
margin-bottom: 1pc;
|
||||
}
|
||||
|
||||
@media screen
|
||||
{
|
||||
a{ color: blue; }
|
||||
|
||||
th, .title
|
||||
{
|
||||
background-color: lightskyblue;
|
||||
}
|
||||
|
||||
.section-title
|
||||
{
|
||||
background-color: #EEE;
|
||||
}
|
||||
|
||||
.programlisting
|
||||
{
|
||||
background-color: #EED;
|
||||
border: 0.1em ridge cyan;
|
||||
padding: 1pc;
|
||||
}
|
||||
|
||||
.toc
|
||||
{
|
||||
border: 0.2em ridge lightcoral;
|
||||
padding: 0.5pc;
|
||||
background-color: #DDD;
|
||||
}
|
||||
}
|
||||
|
||||
@media print
|
||||
{
|
||||
a{ color: black; }
|
||||
}
|
||||
|
||||
|
831
v2/doc/src/advanced.xml
Normal file
@ -0,0 +1,831 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<chapter id="bbv2.advanced">
|
||||
<title>Advanced</title>
|
||||
|
||||
<para>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 <link linkend=
|
||||
"bbv2.reference.init.options.help">help option</link>).</para>
|
||||
|
||||
<section id="bbv2.advanced.overview">
|
||||
<title>Overview</title>
|
||||
|
||||
<para>The most fundemental entity in Boost.Build is <emphasis>main
|
||||
target</emphasis>. 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.</para>
|
||||
|
||||
<para>Main targets are grouped in <emphasis>projects</emphasis>. Their main
|
||||
purpose is organization: related targets placed in one project,
|
||||
can then be built together, or share some definitions.</para>
|
||||
|
||||
<para>Main targets and projects are created as the result of reading
|
||||
one or several Jamfiles. Each Jamfile is a file written in
|
||||
Boost.Jam interpreted language, and typically contains calls to
|
||||
functions provided by Boost.Build, which create main targets of
|
||||
needed type, declare project attributes and access other
|
||||
projects. The full list of functions provided by Boost.Build is
|
||||
described <link linkend="bbv2.advanced.builtins">below</link>.
|
||||
Of course, user can create his own functions, or it can directly
|
||||
access Boost.Build internals from Jamfile, if builtin facilities are
|
||||
not sufficient.</para>
|
||||
|
||||
<para>Each main target, or project can be built in a number of ways,
|
||||
say with optimization or without. We'll call such entities
|
||||
"metatargets". To make Boost.Build produce any real targets, user
|
||||
issues <link linkend="bbv2.reference.buildreq">build request</link>,
|
||||
which specifies metatargets to be built, and properties to be
|
||||
used.</para>
|
||||
|
||||
<para>The <emphasis>properties</emphasis> are just (name,value) pairs that
|
||||
describe various aspects of constructed objects, for example:</para>
|
||||
<programlisting>
|
||||
<optimization>full <inlining>off
|
||||
</programlisting>
|
||||
|
||||
<para>Given the built request, Boost.Build figures out the targets
|
||||
needed for requested metatargets with requested properties, how
|
||||
they can be created, and whether exising files can be reused. It
|
||||
finally issues command to create needed files, automatically
|
||||
converting properties into appropricate command line options.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.roadmap">
|
||||
<title>Your first project and roadmap</title>
|
||||
|
||||
<para>Creating your first project requires three steps:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><simpara>Create an empty file called "Jamfile"</simpara></listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Create an empty file called "project-root.jam"
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Either set your <envar>BOOST_BUILD_PATH</envar> environment
|
||||
variant to Boost.Build root, or create a "boost-build.jam" file
|
||||
with the following content:
|
||||
|
||||
<programlisting>
|
||||
boost-build /path/to/boost.build ;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>After that, you can run the "bjam" command in the directory
|
||||
where you've created the files. Surely, it won't do anything, but
|
||||
it will run without error, at least. Your next steps might
|
||||
be:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
Adding new main targets to the "Jamfile" file. The basic
|
||||
syntax for declaring a main target is described <link linkend=
|
||||
"bbv2.advanced.targets">below</link>, and all builtin functions for
|
||||
declaring main targets are <link linkend=
|
||||
"bbv2.advanced.builtins.targets">listed</link>.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Creating subprojects. Create a directory, put new Jamfile
|
||||
there, and move some main targets to that Jamfile, or declare
|
||||
new ones. The <link linkend="bbv2.advanced.projects">projects
|
||||
reference</link> will help with this part.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Customizing Boost.Build for your needs. You might have
|
||||
additional tools you want to run, or just want different
|
||||
extension for some file. The <ulink url=
|
||||
"doc/extending.html">extender manual</ulink> is waiting for
|
||||
you.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.targets">
|
||||
<title>Main targets</title>
|
||||
|
||||
<para id="bbv2.advanced.targets.main">
|
||||
<emphasis>Main target</emphasis> is a user-defined named
|
||||
entity which can be build, for example a named executable file.
|
||||
Declaring a main target is usually done using one of <link linkend=
|
||||
"bbv2.advanced.builtins.targets">main target functions</link>.
|
||||
The user can also declare <ulink url=
|
||||
"doc/extending.html#main_target_rules">custom main target
|
||||
function</ulink>.</para>
|
||||
|
||||
<para>Most main targets rules in Boost.Build use similiar
|
||||
syntax:</para>
|
||||
|
||||
<programlisting>
|
||||
function-name main-target-name
|
||||
: sources
|
||||
: requirements
|
||||
: default-build
|
||||
: usage-requirements
|
||||
;
|
||||
</programlisting>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
"main-target-name" is the name used to request the target
|
||||
on command line and to use it from other main targets. Main
|
||||
target name may contain alphanumeric characters and symbols '-'
|
||||
and '_';
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
"sources" is the list of source files and other main
|
||||
targets that must be combined. If source file is specified
|
||||
using relative path, it's considered to be relative to the
|
||||
source directory of the project where the path is used. See the
|
||||
<link linkend=
|
||||
"bbv2.advanced.projects.attributes.projectrule">project</link> rule
|
||||
for information how to change source directory.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
"requirements" is the list of properties that must always
|
||||
be present when this main target is built.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
"default-build" is the list of properties that will be used
|
||||
unless some other value of the same feature is already
|
||||
specified.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
"usage-requirements" is the list of properties that will be
|
||||
propagated to all main targets that use this one, i.e. to all
|
||||
dependedents.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Some main target rules have shorter list of parameters, and
|
||||
you should consult their documentation for details.</para>
|
||||
|
||||
<para>Building of the same main target can differ greatly from
|
||||
platform to platform. For example, you might have different list
|
||||
of sources for different compilers. Therefore it is possible to
|
||||
invoke main target rules several times for a single main target.
|
||||
For example:</para>
|
||||
|
||||
<programlisting>
|
||||
exe a : a_gcc.cpp : <toolset>gcc ;
|
||||
exe a : a.cpp ;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Each call to the 'exe' rule defines a new <emphasis>main target
|
||||
alternative</emphasis> for the main target <literal>a</literal>.
|
||||
In this case, the first alternative will be used for the
|
||||
<command>gcc</command> toolset, while the second alternative will
|
||||
be used in other cases. See <link linkend=
|
||||
"bbv2.reference.buildprocess.alternatives">below</link> for
|
||||
details.
|
||||
</para>
|
||||
|
||||
<para>Sometime a main target is really needed only by some other
|
||||
main target. E.g. a rule that declared test-suite uses a main
|
||||
target that represent test, but those main targets are rarely
|
||||
needed by themself.</para>
|
||||
|
||||
<para>It possible to declare target inline, i.e. the "sources"
|
||||
parameter may include call to other main rules. For example:</para>
|
||||
|
||||
<programlisting>
|
||||
exe hello : hello.cpp
|
||||
[ obj helpers : helpers.cpp : <optimization>off ] ;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Will cause "helpers.cpp" to be always compiled without
|
||||
optimization. It's possible to request main targets declared
|
||||
inline, but since they are considered local, they are renamed to
|
||||
"parent-main-target_name..main-target-name". In the example above,
|
||||
to build only helpers, one should run "bjam hello..helpers".
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.projects">
|
||||
<title>Projects</title>
|
||||
|
||||
<para>Boost.Build considers every software it build as organized
|
||||
into <emphasis>projects</emphasis> — modules which declare targets.
|
||||
Projects are organized in a hierarchical structure, so each
|
||||
project may have a single parent project and a number of
|
||||
subprojects.</para>
|
||||
|
||||
<para>Most often, projects are created as result of loading
|
||||
<emphasis>Jamfile</emphasis> — files which are specially meant to
|
||||
describe projects. Boost.Build will implicitly load Jamfile in
|
||||
the invocation directory, and all Jamfiles referred by the first
|
||||
one, creating the hierarchy of projects.</para>
|
||||
|
||||
<para>The exact name of file that describes project is configurable.
|
||||
By default, it's <literal>Jamfile</literal>, but can be changed by setting
|
||||
global variables <literal>JAMFILE</literal>, for example in
|
||||
<literal>boost-build.jam</literal> file. The value of the variable is a
|
||||
list of regex patterns that are used when searching for Jamfile
|
||||
in a directory.</para>
|
||||
|
||||
<para>Every Boost.Build modules can decide to act as project and be
|
||||
able to declare targets. For example, the
|
||||
<filename>site-config.jam</filename> module can declare libraries
|
||||
available on a given host, as described <ulink url=
|
||||
"doc/recipes.html#site_config_targets">here</ulink>.</para>
|
||||
|
||||
<para>There are three things that can be put in Jamfile:
|
||||
declarations of main targets, calls to a number of predefined
|
||||
rules, and arbitrary user code. The predefined rules are listed
|
||||
below:</para>
|
||||
|
||||
<table>
|
||||
<title/>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Rule</entry>
|
||||
|
||||
<entry>Semantic</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><link linkend=
|
||||
"bbv2.advanced.projects.attributes.projectrule">project</link>
|
||||
</entry>
|
||||
|
||||
<entry>Define project attributes.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend=
|
||||
"bbv2.advanced.projects.relationships.useprojectrule">use-project</link></entry>
|
||||
|
||||
<entry>Make another project known.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend=
|
||||
"bbv2.advanced.projects.relationships.buildprojectrule">build-project</link></entry>
|
||||
|
||||
<entry>Build another project when this one is built.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend=
|
||||
"bbv2.reference.buildprocess.explict">explicit</link></entry>
|
||||
|
||||
<entry>States that the target should be built only by explicit
|
||||
request.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>glob</entry>
|
||||
|
||||
<entry>Takes a list of wildcards, and returns the list of files
|
||||
which match any of the wildcards.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>Each project is also associated with <emphasis>project root</emphasis>.
|
||||
That's a root for a tree of projects, which specifies some global
|
||||
properties.</para>
|
||||
|
||||
<section id="bbv2.advanced.projects.root">
|
||||
<title>Project root</title>
|
||||
|
||||
<para>
|
||||
Project root for a projects is the nearest parent directory
|
||||
which contains a file called
|
||||
<filename>project-root.jam</filename>. That file defines
|
||||
certain properties which apply to all projects under project
|
||||
root. It can:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
configure toolsets, via call to <literal>toolset.using</literal>
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
refer to other projects, via the <literal>use-project</literal>
|
||||
rule
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
declare constants, via the <literal>constant</literal> and
|
||||
<literal>path-constant</literal> rules.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>To facilitate declaration of simple projects, Jamfile and
|
||||
project-root can be merged together. To achieve this effect, the
|
||||
project root file should call the <literal>project</literal> rule. The
|
||||
semantic is precisely the same as if the call was made in
|
||||
Jamfile, except that project-root.jam will start serve as
|
||||
Jamfile. The Jamfile in the directory of project-root.jam will be
|
||||
ignored, and project-root.jam will be able to declare main
|
||||
targets as usual.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.projects.attributes">
|
||||
<title>Project attributes</title>
|
||||
|
||||
<para>For each project, there are several attributes.</para>
|
||||
|
||||
<para><emphasis>Project id</emphasis> is a short way to denote a project, as
|
||||
opposed to the Jamfile's pathname. It is a hierarchical path,
|
||||
unrelated to filesystem, such as "boost/thread". <link linkend=
|
||||
"bbv2.advanced.ids">Target references</link> make use of project ids to
|
||||
specify a target.</para>
|
||||
|
||||
<para><emphasis>Source location</emphasis> specifies the directory where sources
|
||||
for the project are located.</para>
|
||||
|
||||
<para><emphasis>Project requirements</emphasis> are requirements that apply to
|
||||
all the targets in the projects as well as all subprojects.</para>
|
||||
|
||||
<para><emphasis>Default build</emphasis> is the build request that should be
|
||||
used when no build request is specified explicitly.</para>
|
||||
|
||||
<para id="bbv2.advanced.projects.attributes.projectrule">
|
||||
The default values for those attributes are
|
||||
given in the table below. In order to affect them, Jamfile may
|
||||
call the <literal>project</literal> rule. The rule has this
|
||||
syntax:</para>
|
||||
|
||||
<programlisting>
|
||||
project id : <attributes> ;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Here, attributes is a sequence of (attribute-name,
|
||||
attribute-value) pairs. The list of attribute names along with its
|
||||
handling is also shown in the table below. For example, it it
|
||||
possible to write:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
project tennis
|
||||
: requirements <threading>multi
|
||||
: default-build release
|
||||
;
|
||||
</programlisting>
|
||||
|
||||
<table>
|
||||
<title/>
|
||||
<tgroup cols="4">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Attribute</entry>
|
||||
|
||||
<entry>Name for the 'project' rule</entry>
|
||||
|
||||
<entry>Default value</entry>
|
||||
|
||||
<entry>Handling by the 'project' rule</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<row>
|
||||
<entry>Project id</entry>
|
||||
|
||||
<entry>none</entry>
|
||||
|
||||
<entry>none</entry>
|
||||
|
||||
<entry>Assigned from the first parameter of the 'project' rule.
|
||||
It is assumed to denote absolute project id.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>Source location</entry>
|
||||
|
||||
<entry><literal>source-location</literal></entry>
|
||||
|
||||
<entry>The location of jamfile for the project</entry>
|
||||
|
||||
<entry>Sets to the passed value</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>Requirements</entry>
|
||||
|
||||
<entry><literal>requirements</literal></entry>
|
||||
|
||||
<entry>The parent's requirements</entry>
|
||||
|
||||
<entry>The parent's requirements are refined with the passed
|
||||
requirement and the result is used as the project
|
||||
requirements.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>Default build</entry>
|
||||
|
||||
<entry><literal>default-build</literal></entry>
|
||||
|
||||
<entry>none</entry>
|
||||
|
||||
<entry>Sets to the passed value</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>Build directory</entry>
|
||||
|
||||
<entry><literal>build-dir</literal></entry>
|
||||
|
||||
<entry>If parent has a build dir set, the value of it, joined
|
||||
with the relative path from parent to the current project.
|
||||
Otherwise, empty</entry>
|
||||
|
||||
<entry>Sets to the passed value, interpreted as relative to the
|
||||
project's location.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.projects.relationships">
|
||||
<title>Project relationship</title>
|
||||
|
||||
<para>There are three kinds of project relationships.</para>
|
||||
|
||||
<para>First is parent-child. This relationship is established
|
||||
implicitly: parent directories of a project are searched, and the
|
||||
first found Jamfile is assumed to define the parent project. The
|
||||
parent-child relationship affects only attribute values for the
|
||||
child project.</para>
|
||||
|
||||
<para id="bbv2.advanced.projects.relationships.buildprojectrule">
|
||||
Second is build relationship. Some
|
||||
project may request to recursively build other projects. Those
|
||||
project need not be child projects. The <literal>build-project</literal>
|
||||
rule is used for that:</para>
|
||||
<programlisting>
|
||||
build-project src ;
|
||||
</programlisting>
|
||||
|
||||
<para id="bbv2.advanced.projects.relationships.useprojectrule">
|
||||
The third kind is the 'use'
|
||||
relationship. In means that one project uses targets from
|
||||
another. It is possible to just refer to target in other projects
|
||||
using target id. However, if target id uses project id, it is
|
||||
required that the project id is known. The
|
||||
<literal>use-project</literal>
|
||||
rule is employed to guarantee that.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
use-project ( id : location )
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
It loads the project at the specified location, which makes
|
||||
its project id available in the project which invokes the rule. It
|
||||
is required that the <literal>id</literal> parameter passed to the
|
||||
<literal>use-project</literal> rule be equal to the id that the loaded
|
||||
project declared. At this moment, the <literal>id</literal> paremeter
|
||||
should be absolute project id.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.ids">
|
||||
<title>Target identifiers and references</title>
|
||||
|
||||
<para><emphasis>Target identifier</emphasis> is used to denote a
|
||||
target. The syntax is:</para>
|
||||
|
||||
<programlisting>
|
||||
target-id -> (project-id | target-name | file-name )
|
||||
| (project-id | directory-name) "//" target-name
|
||||
project-id -> path
|
||||
target-name -> path
|
||||
file-name -> path
|
||||
directory-name -> path
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
This grammar allows some elements to be recognized as either
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
project id (at this point, all project ids start with slash).
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
name of target declared in current Jamfile (note that target
|
||||
names may include slash).
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
a regular file, denoted by absolute name or name relative to
|
||||
project's sources location.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
To determine the real meaning a check is made if project-id
|
||||
by the specified name exists, and then if main target of that
|
||||
name exists. For example, valid target ids might be:
|
||||
|
||||
<screen>
|
||||
a -- target in current project
|
||||
lib/b.cpp -- regular file
|
||||
/boost/thread -- project "/boost/thread"
|
||||
/home/ghost/build/lr_library//parser -- target in specific project
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
<para><emphasis role="bold">Rationale:</emphasis>Target is separated from project by special
|
||||
separator (not just slash), because:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
It emphasises that projects and targets are different things.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
It allows to have main target names with slashes.
|
||||
|
||||
<!-- The motivation for which is:
|
||||
|
||||
So, to summarize:
|
||||
|
||||
1. The project which extract tarfile may extract all possible kinds
|
||||
of targets, and it's reasonable to use them directly from other
|
||||
project.
|
||||
|
||||
2. The rule for unpacking tar is inplemented in terms of
|
||||
"patch-file", for maintainability, and therefore, must use main
|
||||
target name which contains slashes?
|
||||
|
||||
3. Using sub-Jamfile in "foo" to declare extracted file "foo/b" is
|
||||
not an option, because you should not change existing tree
|
||||
|
||||
That makes good rationale for why main target must contain names.
|
||||
-->
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para id="bbv2.advanced.targets.references">
|
||||
<emphasis>Target reference</emphasis> is used to
|
||||
specify a source target, and may additionally specify desired
|
||||
properties for that target. It has this syntax:</para>
|
||||
|
||||
<programlisting>
|
||||
target-reference -> target-id [ "/" requested-properties ]
|
||||
requested-properties -> property-path
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
For example,
|
||||
|
||||
<programlisting>
|
||||
exe compiler : compiler.cpp libs/cmdline/<optimization>space ;
|
||||
</programlisting>
|
||||
|
||||
would cause the version of <literal>cmdline</literal> library,
|
||||
optimized for space, to be linked in even if the
|
||||
<literal>compiler</literal> executable is build with optimization for
|
||||
speed.
|
||||
</para>
|
||||
</section>
|
||||
<section id="bbv2.advanced.builtins">
|
||||
<title>Builtin facilities</title>
|
||||
|
||||
<section id="bbv2.advanced.builtins.targets">
|
||||
<title>Main targets</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>exe</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Creates a regular executable file. Sources must be either
|
||||
object files or libraries, and sources of different types
|
||||
will be converted to accepted types automatically.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>lib</literal></term>
|
||||
|
||||
<listitem>
|
||||
<para>Creates a library file. Depending on the value of
|
||||
<link> feature the library will be either static or
|
||||
shared. Like with "exe", sources will be converted either to
|
||||
objects or libraries.</para>
|
||||
|
||||
<para>The handling of libraries in sources depends on whether
|
||||
linking is static or shared. For shared linking, libraries
|
||||
will be linked in. For static linking the library sources
|
||||
will not be linked in, since it's not possible, and will be
|
||||
passed on. Other main target which depend on this one will
|
||||
see those libraries and link to it. Therefore, putting
|
||||
library in sources of other library works in all cases.</para>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><literal>alias</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Builds all the source targets and returns them unmodified.
|
||||
Please run "bjam --help alias" for more details.
|
||||
</simpara>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><literal>stage</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Copies a number of targets to a single directory. The
|
||||
primary purpose is installing binaries. Please run "bjam --help
|
||||
stage" for more details.
|
||||
</simpara>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><literal>unit-test</literal> (from module "testing")</term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Creates an executable file and runs it. Build won't succeed
|
||||
unless the executable runs successfully. The rule is usefull
|
||||
for creating test program which should be rerun whenever any
|
||||
dependency changes. <!-- make? -->
|
||||
</simpara>
|
||||
</listitem></varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="bbv2.advanced.builtins.features">
|
||||
<title>Features</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>variant</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
The feature which combines several low-level features in
|
||||
order to make building most common variants simple.
|
||||
</simpara>
|
||||
|
||||
<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><emphasis role="bold">Rationale:</emphasis> Runtime debugging is on in debug build
|
||||
so suit expectations of people used various IDEs. It's
|
||||
assumed other folks don't have any specific expectation in
|
||||
this point.</para>
|
||||
</listitem></varlistentry>
|
||||
|
||||
<varlistentry><term><literal>link</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Feature which 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>library</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
For exe and lib main targets, the <library>X feature
|
||||
is equvivalent to putting X in the list of sources. The feature
|
||||
is sometimes more convenient: you can put <library>X in
|
||||
the requirements for a project and it will be linked to all
|
||||
executables.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>use</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Causes the target referenced by the value of this feature
|
||||
to be constructed and adds it's usage requirements to build
|
||||
properties. The constructed targets are not used in any other
|
||||
way. The primary use case is when you use some library and want
|
||||
it's usage requirements (such as include paths) to be applied,
|
||||
but don't want to link to the library.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>dll-path</literal></term>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Specify a path where dynamic libraries should be found at
|
||||
where executable or shared library is run. This feature
|
||||
directly affects binaries with the gcc compiler, allowing them
|
||||
to pick specific libraries, and ignoring all environment
|
||||
settings. On other toolsets, the binary still requires proper
|
||||
environment settings to be run. However, Boost.Build tools
|
||||
which run executables will notice dll-path settings and create
|
||||
this environment automatically.
|
||||
</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>off</literal>, <literal>on</literal> When this
|
||||
property is on, usage requirements for each library will
|
||||
include additional dll-path propertry, with the path the the
|
||||
generated library file. This allows to run executables
|
||||
without placing all the dependent libraries to a single
|
||||
location.</para>
|
||||
</listitem></varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
434
v2/doc/src/architecture.xml
Normal file
@ -0,0 +1,434 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE appendix PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<appendix id="bbv2.arch">
|
||||
<title>Boost.Build v2 architecture</title>
|
||||
|
||||
<sidebar>
|
||||
<para>This document is work-in progress. Don't expect much from it
|
||||
yet.</para>
|
||||
</sidebar>
|
||||
|
||||
<section id="bbv2.arch.targets">
|
||||
<title>Targets</title>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
<para>File targets, on the contary, are associated with concrete
|
||||
files. Dependency graphs for abstract targets with specific
|
||||
properties are constructed from file targets. User has no was to
|
||||
create file targets, however it can specify rules that detect
|
||||
file type for sources, and also rules for transforming between
|
||||
file targets of different types. That information is used in
|
||||
constructing dependency graph, as desribed in the "next section".
|
||||
[ link? ] <emphasis role="bold">Note:</emphasis>File targets are not
|
||||
the same as targets in Jam sense; the latter are created from
|
||||
file targets at the latest possible moment. <emphasis role="bold">Note:</emphasis>"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.</para>
|
||||
|
||||
<section id="bbv2.arch.depends">
|
||||
<title>Dependency scanning</title>
|
||||
|
||||
<para>Dependency scanning is the process of finding implicit
|
||||
dependencies, like "#include" statements in C++. The requirements
|
||||
for right dependency scanning mechanism are:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
Support for different scanning algorithms. C++ and XML have
|
||||
quite different syntax for includes and rules for looking up
|
||||
included files.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Ability to scan the same file several times. For example,
|
||||
single C++ file can be compiled with different include
|
||||
paths.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Proper detection of dependencies on generated files.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Proper detection of dependencies from generated file.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<section>
|
||||
<title>Support for different scanning algorithms</title>
|
||||
|
||||
<para>Different scanning algorithm are encapsulated by objects
|
||||
called "scanners". Please see the documentation for "scanner"
|
||||
module for more details.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Ability to scan the same file several times</title>
|
||||
|
||||
<para>As said above, it's possible to compile a C++ file twice, with
|
||||
different include paths. Therefore, include dependencies for
|
||||
those compilations can be different. The problem is that bjam
|
||||
does not allow several scans of the same target.</para>
|
||||
|
||||
<para>The solution in Boost.Build is straigtforward. When a virtual
|
||||
target is converted to bjam target (via
|
||||
<literal>virtual-target.actualize</literal> method), we specify the scanner
|
||||
object to be used. The actualize method will create different
|
||||
bjam targets for different scanners.</para>
|
||||
|
||||
<para>All targets with specific scanner are made dependent on target
|
||||
without scanner, which target is always created. This is done in
|
||||
case the target is updated. The updating action will be
|
||||
associated with target without scanner, but if sources for that
|
||||
action are touched, all targets — with scanner and without
|
||||
should be considered outdated.</para>
|
||||
|
||||
<para>For example, assume that "a.cpp" is compiled by two compilers
|
||||
with different include path. It's also copied into some install
|
||||
location. In turn, it's produced from "a.verbatim". The
|
||||
dependency graph will look like:</para>
|
||||
|
||||
<programlisting>
|
||||
a.o (<toolset>gcc) <--(compile)-- a.cpp (scanner1) ----+
|
||||
a.o (<toolset>msvc) <--(compile)-- a.cpp (scanner2) ----|
|
||||
a.cpp (installed copy) <--(copy) ----------------------- a.cpp (no scanner)
|
||||
^
|
||||
|
|
||||
a.verbose --------------------------------+
|
||||
</programlisting>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
<title>Proper detection of dependencies on generated files.</title>
|
||||
|
||||
<para>This requirement breaks down to the following ones.</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
If when compiling "a.cpp" there's include of "a.h", the
|
||||
"dir" directory is in include path, and a target called "a.h"
|
||||
will be generated to "dir", then bjam should discover the
|
||||
include, and create "a.h" before compiling "a.cpp".
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Since almost always Boost.Build generates targets to a
|
||||
"bin" directory, it should be supported as well. I.e. in the
|
||||
scanario above, Jamfile in "dir" might create a main target,
|
||||
which generates "a.h". The file will be generated to "dir/bin"
|
||||
directory, but we still have to recornize the dependency.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>The first requirement means that when determining what "a.h"
|
||||
means, when found in "a.cpp", we have to iterate over all
|
||||
directories in include paths, checking for each one:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
If there's file "a.h" in that directory, or
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
If there's a target called "a.h", which will be generated
|
||||
to that directory.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>Classic Jam has built-in facilities for point (1) above, but
|
||||
that's not enough. It's hard to implement the right semantic
|
||||
without builtin support. For example, we could try to check if
|
||||
there's targer called "a.h" somewhere in dependency graph, and
|
||||
add a dependency to it. The problem is that without search in
|
||||
include path, the semantic may be incorrect. For example, one can
|
||||
have an action which generated some "dummy" header, for system
|
||||
which don't have the native one. Naturally, we don't want to
|
||||
depend on that generated header on platforms where native one is
|
||||
included.</para>
|
||||
|
||||
<para>There are two design choices for builtin support. Suppose we
|
||||
have files a.cpp and b.cpp, and each one includes header.h,
|
||||
generated by some action. Dependency graph created by classic jam
|
||||
would look like:</para>
|
||||
|
||||
<programlisting>
|
||||
a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
|
||||
|
||||
|
||||
<d2>header.h --------> header.y
|
||||
[generated in d2]
|
||||
|
||||
b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4]
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
In this case, Jam thinks all header.h target are not
|
||||
realated. The right dependency graph might be:
|
||||
|
||||
<programlisting>
|
||||
a.cpp ----
|
||||
\
|
||||
\
|
||||
>----> <d2>header.h --------> header.y
|
||||
/ [generated in d2]
|
||||
/
|
||||
b.cpp ----
|
||||
</programlisting>
|
||||
|
||||
or
|
||||
|
||||
<programlisting>
|
||||
a.cpp -----> <scanner1>header.h [search path: d1, d2, d3]
|
||||
|
|
||||
(includes)
|
||||
V
|
||||
<d2>header.h --------> header.y
|
||||
[generated in d2]
|
||||
^
|
||||
(includes)
|
||||
|
|
||||
b.cpp -----> <scanner2>header.h [ search path: d1, d2, d4]
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The first alternative was used for some time. The problem
|
||||
however is: what include paths should be used when scanning
|
||||
header.h? The second alternative was suggested by Matt Armstrong.
|
||||
It has similiar effect: add targets which depend on
|
||||
<scanner1>header.h will also depend on <d2>header.h.
|
||||
But now we have two different target with two different scanners,
|
||||
and those targets can be scanned independently. The problem of
|
||||
first alternative is avoided, so the second alternative is
|
||||
implemented now.
|
||||
</para>
|
||||
|
||||
<para>The second sub-requirements is that targets generated to "bin"
|
||||
directory are handled as well. Boost.Build implements
|
||||
semi-automatic approach. When compiling C++ files the process
|
||||
is:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
The main target to which compiled file belongs is found.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
All other main targets that the found one depends on are
|
||||
found. Those include main target which are used as sources, or
|
||||
present as values of "dependency" features.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
All directories where files belonging to those main target
|
||||
will be generated are added to the include path.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>After this is done, dependencies are found by the approach
|
||||
explained previously.</para>
|
||||
|
||||
<para>Note that if a target uses generated headers from other main
|
||||
target, that main target should be explicitly specified as
|
||||
dependency property. It would be better to lift this requirement,
|
||||
but it seems not very problematic in practice.</para>
|
||||
|
||||
<para>For target types other than C++, adding of include paths must
|
||||
be implemented anew.</para>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
<title>Proper detection of dependencies from generated files</title>
|
||||
|
||||
<para>Suppose file "a.cpp" includes "a.h" and both are generated by
|
||||
some action. Note that classic jam has two stages. In first stage
|
||||
dependency graph graph is build and actions which should be run
|
||||
are determined. In second stage the actions are executed.
|
||||
Initially, neither file exists, so the include is not found. As
|
||||
the result, jam might attempt to compile a.cpp before creating
|
||||
a.h, and compilation will fail.</para>
|
||||
|
||||
<para>The solution in Boost.Jam is to perform additional dependency
|
||||
scans after targets are updated. This break separation between
|
||||
build stages in jam — which some people consider a good
|
||||
thing — but I'm not aware of any better solution.</para>
|
||||
|
||||
<para>In order to understand the rest of this section, you better
|
||||
read some details about jam dependency scanning, available
|
||||
<ulink url=
|
||||
"http://public.perforce.com:8080/@md=d&cd=//public/jam/src/&ra=s&c=kVu@//2614?ac=10">
|
||||
at this link</ulink>.</para>
|
||||
|
||||
<para>Whenever a target is updated, Boost.Jam rescans it for
|
||||
includes. Consider this graph, created before any actions are
|
||||
run.</para>
|
||||
|
||||
<programlisting>
|
||||
A -------> C ----> C.pro
|
||||
/
|
||||
B --/ C-includes ---> D
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Both A and B have dependency on C and C-includes (the latter
|
||||
dependency is not shown). Say during building we've tried to create
|
||||
A, then tried to create C and successfully created C.
|
||||
</para>
|
||||
|
||||
<para>In that case, the set of includes in C might well have
|
||||
changed. We do not bother to detect precisely which includes were
|
||||
added or removed. Instead we create another internal node
|
||||
C-includes-2. Then we determine what actions should be run to
|
||||
update the target. In fact this mean that we perform logic of
|
||||
first stage while already executing stage.</para>
|
||||
|
||||
<para>After actions for C-includes-2 are determined, we add
|
||||
C-includes-2 to the list of A's dependents, and stage 2 proceeds
|
||||
as usual. Unfortunately, we can't do the same with target B,
|
||||
since when it's not visited, C target does not know B depends on
|
||||
it. So, we add a flag to C which tells and it was rescanned. When
|
||||
visiting B target, the flag is notices and C-includes-2 will be
|
||||
added to the list of B's dependencies.</para>
|
||||
|
||||
<para>Note also that internal nodes are sometimes updated too.
|
||||
Consider this dependency graph:</para>
|
||||
|
||||
<programlisting>
|
||||
a.o ---> a.cpp
|
||||
a.cpp-includes --> a.h (scanned)
|
||||
a.h-includes ------> a.h (generated)
|
||||
|
|
||||
|
|
||||
a.pro <-------------------------------------------+
|
||||
</programlisting>
|
||||
|
||||
<para>Here, out handling of generated headers come into play. Say
|
||||
that a.h exists but is out of date with respect to "a.pro", then
|
||||
"a.h (generated)" and "a.h-includes" will be marking for
|
||||
updating, but "a.h (scanned)" won't be marked. We have to rescan
|
||||
"a.h" file after it's created, but since "a.h (generated)" has no
|
||||
scanner associated with it, it's only possible to rescan "a.h"
|
||||
after "a.h-includes" target was updated.</para>
|
||||
|
||||
<para>Tbe above consideration lead to decision that we'll rescan a
|
||||
target whenever it's updated, no matter if this target is
|
||||
internal or not.</para>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
The remainder of this document is not indended to be read at
|
||||
all. This will be rearranged in future.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<section>
|
||||
<title>File targets</title>
|
||||
|
||||
<para>
|
||||
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
|
||||
<literal>virtual-target</literal> module.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Types</title>
|
||||
|
||||
<para>A file target can be given a file, which determines
|
||||
what transformations can be applied to the file. The
|
||||
<literal>type.register</literal> rule declares new types. File type can
|
||||
also be assigned a scanner, which is used to find implicit
|
||||
dependencies. See "dependency scanning" [ link? ] below.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Target paths</title>
|
||||
|
||||
<para>To distinguish targets build with different properties, they
|
||||
are put in different directories. Rules for determining target
|
||||
paths are given below:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
All targets are placed under directory corresponding to the
|
||||
project where they are defined.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Each non free, non incidental property cause an additional
|
||||
element to be added to the target path. That element has the
|
||||
form <literal><feature-name>-<feature-value></literal> for
|
||||
ordinary features and <literal><feature-value></literal> for
|
||||
implicit ones. [Note about composite features].
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
If the set of free, non incidental properties is different
|
||||
from the set of free, non incidental properties for the project
|
||||
in which the main target that uses the target is defined, a
|
||||
part of the form <literal>main_target-<name></literal> is added to
|
||||
the target path. <emphasis role="bold">Note:</emphasis>It would be nice to completely
|
||||
track free features also, but this appears to be complex and
|
||||
not extremely needed.
|
||||
</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>For example, we might have these paths:</para>
|
||||
|
||||
<programlisting>
|
||||
debug/optimization-off
|
||||
debug/main-target-a
|
||||
</programlisting>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</appendix>
|
||||
|
9
v2/doc/src/catalog.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE catalog
|
||||
PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
|
||||
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
|
||||
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
|
||||
<rewriteURI uriStartString="http://www.boost.org/tools/boostbook/dtd/" rewritePrefix="file:///home/ccurrie/src/boost/tools/boostbook/dtd//"/>
|
||||
<rewriteURI uriStartString="http://docbook.sourceforge.net/release/xsl/current/" rewritePrefix="file:///shared/ccurrie/share/sgml/docbook/docbook-xsl-1.64.1/"/>
|
||||
<rewriteURI uriStartString="http://www.oasis-open.org/docbook/xml/4.2/" rewritePrefix="file:///shared/ccurrie/share/sgml/docbook/docbook-dtd-4.2/"/>
|
||||
</catalog>
|
128
v2/doc/src/extending.xml
Normal file
@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE appendix PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<appendix id="bbv2.extender">
|
||||
<title>Extender Manual</title>
|
||||
|
||||
<section id="bbv2.extender.intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>This document explains how to extend Boost.Build to accomodate
|
||||
your local requirements. Let's start with quite simple, but
|
||||
realistic example.</para>
|
||||
|
||||
<para>Say you're writing an application which generates C++ code. If
|
||||
you ever did this, you know that it's not nice. Embedding large
|
||||
portions of C++ code in string literals is very awkward. A much
|
||||
better solution is:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
Write the template of the code to be generated, leaving
|
||||
placeholders at the points which will change
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Access the template in your application and replace
|
||||
placeholders with appropriate text.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>Write the result.</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>It's quite easy to archive. You write special verbatim files,
|
||||
which are just C++, except that the very first line of the file
|
||||
gives a name of variable that should be generated. A simple tool
|
||||
is created which takes verbatim file and creates a cpp file with
|
||||
a single char* variable, which name is taken from the first line
|
||||
of verbatim file, and which value is properly quoted content of
|
||||
the verbatim file.</para>
|
||||
|
||||
<para>Let's see what Boost.Build can do.</para>
|
||||
|
||||
<para>First off, Boost.Build has no idea about "verbatim files". So,
|
||||
you must register a new type. The following code does it:</para>
|
||||
|
||||
<programlisting>
|
||||
import type ;
|
||||
type.register VERBATIM : verbatim ;
|
||||
</programlisting>
|
||||
|
||||
<para>The first parameter to 'type.register' gives the name of
|
||||
declared type. By convention, it's uppercase. The second
|
||||
parameter is suffix for this type. So, if Boost.Build sees
|
||||
"code.verbatim" in the list of sources, it knows that it's of
|
||||
type <literal>VERBATIM</literal>.</para>
|
||||
|
||||
<para>Lastly, you need a tool to convert verbatim files to C++. Say
|
||||
you've sketched such a tool in Python. Then, you have to inform
|
||||
Boost.Build about the tool. The Boost.Build concept which
|
||||
represents a tool is <emphasis>generator</emphasis>.</para>
|
||||
|
||||
<para>First, you say that generator 'inline-file' is able to convert
|
||||
VERBATIM type into C++:</para>
|
||||
|
||||
<programlisting>
|
||||
import generators ;
|
||||
generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
|
||||
</programlisting>
|
||||
|
||||
<para>Second, you must specify the commands to be run to actually
|
||||
perform convertion:</para>
|
||||
|
||||
<programlisting>
|
||||
actions inline-file
|
||||
{
|
||||
"./inline-file.py" $(<) $(>)
|
||||
}
|
||||
</programlisting>
|
||||
<!-- We use verbatim.inline-file in one place and just inline-file in
|
||||
another. Is this confusing for user?
|
||||
-->
|
||||
|
||||
<para>Now, we're ready to tie it all together. Put all the code
|
||||
above in file "verbatim.jam", add "import verbatim ;" to
|
||||
"project-root.jam", and it's possible to write the following in
|
||||
Jamfile:</para>
|
||||
|
||||
<programlisting>
|
||||
exe codegen : codegen.cpp class_template.verbatim usage.verbatim ;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
The verbatim files will be automatically converted into C++
|
||||
and linked it.
|
||||
</para>
|
||||
|
||||
<para>The complete code is available in <ulink url=
|
||||
"../../example/customization">example/customization</ulink>
|
||||
directory.</para>
|
||||
|
||||
</section>
|
||||
<section id="bbv2.extending.targets">
|
||||
<title>Target types</title>
|
||||
<para/>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.extending.tools">
|
||||
<title>Tools</title>
|
||||
<para/>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.extending.rules">
|
||||
<title>Main target rules</title>
|
||||
<para/>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.extending.scanners">
|
||||
<title>Scanners</title>
|
||||
<para/>
|
||||
</section>
|
||||
</appendix>
|
82
v2/doc/src/faq.xml
Normal file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<chapter id="bbv2.faq">
|
||||
<title>Frequently Asked Questions</title>
|
||||
|
||||
<section>
|
||||
<title>
|
||||
I'm getting "Duplicate name of actual target" error. What
|
||||
does it mean?
|
||||
</title>
|
||||
|
||||
<para>
|
||||
The most likely case is that you're trying to
|
||||
compile the same file twice, with almost the same,
|
||||
but differing properties. For example:
|
||||
|
||||
<programlisting>
|
||||
exe a : a.cpp : <include>/usr/local/include ;
|
||||
exe b : a.cpp ;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The above snippet requires two different compilations
|
||||
of 'a.cpp', which differ only in 'include' property.
|
||||
Since the 'include' property is free, Boost.Build
|
||||
can't generate two ojects files into different directories.
|
||||
On the other hand, it's dangerous to compile the file only
|
||||
once -- maybe you really want to compile with different
|
||||
includes.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To solve this issue, you need to decide if file should
|
||||
be compiled once or twice.</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Two compile file only once, make sure that properties
|
||||
are the same:
|
||||
|
||||
<programlisting>
|
||||
exe a : a.cpp : <include>/usr/local/include ;
|
||||
exe b : a.cpp : <include>/usr/local/include ;
|
||||
</programlisting></para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
If changing the properties is not desirable, for example
|
||||
if 'a' and 'b' target have other sources which need
|
||||
specific properties, separate 'a.cpp' into it's own target:
|
||||
|
||||
<programlisting>
|
||||
obj a_obj : a.cpp : <include>/usr/local/include ;
|
||||
exe a : a_obj ;
|
||||
</programlisting></para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
To compile file twice, you can make the object file local
|
||||
to the main target:
|
||||
|
||||
<programlisting>
|
||||
exe a : [ obj a_obj : a.cpp ] : <include>/usr/local/include ;
|
||||
exe b : [ obj a_obj : a.cpp ] ;
|
||||
</programlisting></para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
A good question is why Boost.Build can't use some of the above
|
||||
approaches automatically. The problem is that such magic would
|
||||
require additional implementation complexities and would only
|
||||
help in half of the cases, while in other half we'd be silently
|
||||
doing the wrong thing. It's simpler and safe to ask user to
|
||||
clarify his intention in such cases.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
33
v2/doc/src/howto.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<chapter id="bbv2.howto">
|
||||
<title>How to use this document</title>
|
||||
|
||||
<para>
|
||||
If you've just found out about Boost.Build V2 and want to know
|
||||
if it will work for you, start with <xref linkend=
|
||||
"bbv2.tutorial" />. You can continue with the <xref
|
||||
linkend="bbv2.advanced" />. When you're ready to try Boost.Build
|
||||
in practice, go to <xref linkend="bbv2.installation"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you are about to use Boost.Build on your project, or already
|
||||
using it and have a problem, look at <xref linkend=
|
||||
"bbv2.advanced"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you're trying to build a project which uses Boost.Build,
|
||||
look at <xref linkend="bbv2.installation"/> and then read about
|
||||
<xref linkend="bbv2.reference.commandline"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, if nothing applies to you, write to our mailing list,
|
||||
telling what information you'd like to know.
|
||||
</para>
|
||||
|
||||
</chapter>
|
111
v2/doc/src/install.xml
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<chapter id="bbv2.installation">
|
||||
<title>Installation</title>
|
||||
|
||||
<para>
|
||||
Assuming you're installing Boost.Build from released source
|
||||
distribution, the following steps are needed. All paths are
|
||||
given relatively to Boost.Build root directory, which is the
|
||||
directory with the document you are reading.
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
Go to "jam_src" directory and build Boost.Jam. Two convenient
|
||||
scripts are provided, "build.sh" (for Unix systems) and
|
||||
"build.bat" (for Windows). Run the appropriate one and
|
||||
Boost.Jam will be built to directory
|
||||
<filename>bin.{platform_name}.</filename>. The <ulink url=
|
||||
"../jam_src/index.html">Boost.Jam documentation</ulink> has
|
||||
more details in case you need them.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Place the Boost.Jam binary, called "bjam" or "bjam.exe",
|
||||
somewhere in your <envar>PATH</envar>. Go to the root
|
||||
directory of Boost.Build and run "bjam --version". You should
|
||||
get
|
||||
|
||||
<screen>Boost.Build V2 (Milestone N)</screen>
|
||||
|
||||
(where N is the version you've downloaded).
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
Configure toolsets to use. Open the
|
||||
<filename>user-config.jam</filename> file and follow
|
||||
instructions there to specify what compiles/libraries you
|
||||
have and where they are located.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<simpara>
|
||||
You should now be able to go to
|
||||
<filename>example/hello</filename>, and run
|
||||
<command>bjam</command> there. A simple application will be
|
||||
built. You can also play with other projects in
|
||||
<filename>example</filename>.
|
||||
<!-- This part should not go into intoduction docs, but we need to
|
||||
place it somewhere.
|
||||
|
||||
<para>It is slighly better way is to copy
|
||||
<filename>new/user-config.jam</filename> into one of the locations
|
||||
where it can be found (given in <link linkend=
|
||||
"bbv2.reference.init.config">this table</link>). This prevent you
|
||||
from accidentally overwriting your config when updating.</para>
|
||||
|
||||
-->
|
||||
</simpara>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
If you use Boost distribution, or Boost CVS, the Boost.Build
|
||||
root is located at <filename>$boost_root/tools/build/v2</filename>
|
||||
and the installation steps are the same. However, don't skip
|
||||
the bjam rebuilding step, even if you have a previous version.
|
||||
CVS version of Boost.Build requires CVS version of Boost.Jam.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When starting a new project which uses Boost.Build, you need
|
||||
to make sure that build system can be found. There are two
|
||||
ways.
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>
|
||||
Set enviromnetal variable <envar>BOOST_BUILD_PATH</envar>
|
||||
to the absolute path to Boost.Build installation directory.
|
||||
</simpara>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Create, at the top of your project, a file called
|
||||
<filename>boost-build.jam</filename>, with a single line:
|
||||
|
||||
<programlisting>
|
||||
boost-build /path/to/boost.build ;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>If you're trying to use Boost.Build V2 on Boost itself, please
|
||||
note that when building Boost, V1 is used by default. You'd have
|
||||
to add <option>--v2</option> command line option to all "bjam"
|
||||
invocations.</para>
|
||||
|
||||
</chapter>
|
35
v2/doc/src/recipes.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE appendix PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<appendix id="bbv2.recipies">
|
||||
<title>Boost Build System V2 recipes</title>
|
||||
|
||||
<section id="bbv2.recipies.site-config">
|
||||
<title>Targets in site-config.jam</title>
|
||||
|
||||
<para>It is desirable to declare standard libraries available on a
|
||||
given system. Putting target declaration in Jamfile is not really
|
||||
good, since locations of the libraries can vary. The solution is
|
||||
to put the following to site-config.jam.</para>
|
||||
|
||||
<programlisting>
|
||||
import project ;
|
||||
project.initialize $(__name__) ;
|
||||
project site-config ;
|
||||
lib zlib : : <name>z ;
|
||||
</programlisting>
|
||||
|
||||
<para>The second line allows this module to act as project. The
|
||||
third line gives id to this project — it really has no location
|
||||
and cannot be used otherwise. The fourth line just declares a
|
||||
target. Now, one can write
|
||||
|
||||
<programlisting>
|
||||
exe hello : hello.cpp /site-config//zlib ;
|
||||
</programlisting>
|
||||
|
||||
in any Jamfile.</para>
|
||||
|
||||
</section>
|
||||
</appendix>
|
1037
v2/doc/src/reference.xml
Normal file
516
v2/doc/src/tutorial.xml
Normal file
@ -0,0 +1,516 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<chapter id="bbv2.tutorial">
|
||||
<title>Tutorial</title>
|
||||
|
||||
<section id="bbv2.tutorial.hello">
|
||||
<title>Hello, world</title>
|
||||
|
||||
<para>The simplest project that Boost.Build can construct is
|
||||
stored in example/hello directory. The targets are declared in
|
||||
a file called <filename>Jamfile</filename>, which contains the
|
||||
following:
|
||||
|
||||
<programlisting>
|
||||
exe hello : hello.cpp ;
|
||||
</programlisting>
|
||||
|
||||
Even with this simple setup, you can do some interesting
|
||||
things. First of all, running "bjam" would build binary "hello"
|
||||
from hello.cpp, in debug version. After that, you can run
|
||||
|
||||
<screen>
|
||||
bjam release
|
||||
</screen>
|
||||
|
||||
which would create release version of the 'hello' binary.
|
||||
Note that debug and release version would be created in different
|
||||
directories, so if you want to switch from debug to release
|
||||
version and back, no recompilation is needed. Let's extend the
|
||||
example by adding another line to Jamfile:
|
||||
|
||||
<programlisting>
|
||||
exe hello2 : hello.cpp ;
|
||||
</programlisting>
|
||||
|
||||
You can now rebuild both debug and release versions:
|
||||
|
||||
<screen>
|
||||
bjam debug release
|
||||
</screen>
|
||||
|
||||
You'll see that two versions of "hello2" binary are linked.
|
||||
Of course, hello.cpp won't be recompiled. Now you decide to remove
|
||||
all build products. You do that with the following command
|
||||
|
||||
<screen>
|
||||
bjam --clean debug release
|
||||
</screen>
|
||||
|
||||
It's also possible to create or clean only specific targets.
|
||||
Both following commands are legal and create or clean only files
|
||||
that belonging the the named binary:
|
||||
|
||||
<screen>
|
||||
bjam hello2
|
||||
bjam --clean hello2
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
<section id="bbv2.tutorial.properties">
|
||||
<title>Properties</title>
|
||||
|
||||
<para>Boost.Build attempts to allow building different variants of
|
||||
projects, e.g. for debugging and release, or in single and
|
||||
multithreaded mode. In order to stay portable, it uses the
|
||||
concept of <emphasis>features</emphasis>, which is abstract aspect of
|
||||
build configuration. <emphasis>Property</emphasis> is just a (feature,
|
||||
value) pair. For example, there's a feature "debug-symbols", which can
|
||||
have a value of "on" or "off". When users asks to build project is a
|
||||
particual value, Boost.Build will automatically find the
|
||||
appropriate flags to the used compiler.</para>
|
||||
|
||||
<para>The "release" and "debug" in bjam invocation that we've seen
|
||||
are just are short form of specifying values of feature
|
||||
"variant". There is a lot of builtin features, and it's possible
|
||||
to write something like:</para>
|
||||
|
||||
<screen>
|
||||
bjam release inlining=off debug-symbols=on
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
The first command line element specified the value of feature
|
||||
"variant". The feature is very common and is therefore special
|
||||
— it's possible to specify only value. Another feature,
|
||||
"inlining" is not special, and you should use
|
||||
|
||||
<screen>
|
||||
feature-name=feature-value
|
||||
</screen>
|
||||
|
||||
syntax for it. Complete description of features can be found
|
||||
<link linkend="bbv2.reference.features">here</link>. The set of
|
||||
properties specified in the command line constitute
|
||||
<emphasis>build request</emphasis> — the desired properties
|
||||
for requested targets, or for the project in the current
|
||||
directory. The actual set of properties used for building is
|
||||
often different. For example, when compiling a program you need
|
||||
some include paths. It's not reasonable to ask the user to specify
|
||||
those paths with each bjam invocation, so must be specified in
|
||||
Jamfile and added to the build request. For another example,
|
||||
certain application can only be linked in multithreaded mode. To
|
||||
support such situations, every target is allowed to specify
|
||||
<emphasis>requirements</emphasis> -- properties that are required
|
||||
to its building. Consider this example:
|
||||
|
||||
<programlisting>
|
||||
exe hello
|
||||
: hello.cpp
|
||||
: <include>/home/ghost/Work/boost <threading>multi
|
||||
</programlisting>
|
||||
|
||||
In this case, when hello is build, the two specified properties will
|
||||
always be present. This leads to a question: what if user explictly
|
||||
requested single-threading. The answer is that requirement can
|
||||
affect build properties only to a certain degree: the requested and
|
||||
actual properties must be link-compatible. See <xref linkend=
|
||||
"bbv2.reference.variants.compat"/> below. If they are not link
|
||||
compatible, the bulding of the target is skipped. Previously, we've
|
||||
added "hello2" target. Seems like we have to specify the same
|
||||
requirements for it, which results in duplication. But there's a
|
||||
better way. Each project (i.e. each Jamfile), can specify a set of
|
||||
attributes, including requirements:
|
||||
|
||||
<programlisting>
|
||||
project
|
||||
: requirements <include>/home/ghost/Work/boost <threading>multi
|
||||
;
|
||||
|
||||
exe hello : hello.cpp ;
|
||||
exe hello2 : hello.cpp ;
|
||||
</programlisting>
|
||||
|
||||
The effect would be as if we specified this requirement for
|
||||
both "hello" and "hello2".
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.tutorial.hierarchy">
|
||||
<title>Project hierarchy</title>
|
||||
|
||||
<para>So far we only considered examples with one project (i.e. with
|
||||
one Jamfile). Typically, you'd have a lot of projects organized
|
||||
into a tree. At the top of the tree there's <emphasis>project
|
||||
root</emphasis>. This is a directory which contains, besides Jamfile, a
|
||||
file called "project-root.jam". Each other Jamfile has a single
|
||||
parent, which is the Jamfile in the nearest parent directory. For
|
||||
example, in the following directory layout:</para>
|
||||
|
||||
<screen>
|
||||
[top]
|
||||
|
|
||||
|-- Jamfile
|
||||
|-- project-root.jam
|
||||
|
|
||||
|-- src
|
||||
| |
|
||||
| |-- Jamfile
|
||||
| \-- app.cpp
|
||||
|
|
||||
\-- lib
|
||||
|
|
||||
|-- lib1
|
||||
| |
|
||||
| |-- Jamfile
|
||||
|-- lib1.cpp
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
project root is at top. Both src/Jamfile and lib/lib1/Jamfile
|
||||
have [top]/Jamfile as parent project. Projects inherit all
|
||||
attributes (such as requirements) from their parents. When the same
|
||||
attributes are specified in the project, they are combined with
|
||||
inherited ones. For example, if [top]/Jamfile has
|
||||
|
||||
<programlisting>
|
||||
<include>/home/ghost/local
|
||||
</programlisting>
|
||||
|
||||
in requirements, then all other projects will have that in
|
||||
their requirements too. Of course, any project can add additional
|
||||
includes. More details can be found in the section on <link linkend=
|
||||
"bbv2.advanced.projects">projects</link>. Projects are not automatically
|
||||
built when
|
||||
their parents are built. You should specify this explicitly. In our
|
||||
example, [top]/Jamfile might contain:
|
||||
|
||||
<programlisting>
|
||||
build-project src ;
|
||||
</programlisting>
|
||||
|
||||
It will cause project in src to be built whenever project in
|
||||
[top] is built. However, targets in lib/lib1 will be built only if
|
||||
required. For example, there may be 10 targets, and two of them are
|
||||
used by targets in src/Jamfile. Then, only those two targets will
|
||||
be built.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.tutorial.libs">
|
||||
<title>Using libraries</title>
|
||||
|
||||
<para>Let's continue the above example and see how src/Jamfile
|
||||
can use libraries from
|
||||
lib/lib1. (TODO: need to make this section consistent with
|
||||
"examples-v2/libraries". Assume lib/lib1/Jamfile contains:
|
||||
|
||||
<programlisting>
|
||||
lib lib1 : lib1.cpp ;
|
||||
</programlisting>
|
||||
|
||||
Then, to use this library in src/Jamfile, we can write:
|
||||
|
||||
<programlisting>
|
||||
exe app : app.cpp ../lib/lib1//lib1 ;
|
||||
</programlisting>
|
||||
|
||||
While "app.cpp" is a regular source file, "../lib/lib1//lib1"
|
||||
is a reference to another target, here, library "lib1" declared in
|
||||
Jamfile at "../lib/lib1". When linking the "app" binary, the needed
|
||||
version of the library will be built and linked in. But what is
|
||||
meant by "needed"? For example, we can request to build "app" with
|
||||
properties
|
||||
|
||||
<programlisting>
|
||||
<optimization>full <cxxflags>-w-8080
|
||||
</programlisting>
|
||||
|
||||
Which properties must be used for "lib1"? The answer is that
|
||||
some properties are <emphasis>propagated</emphasis> — Boost.Build attemps
|
||||
to use dependencies with the same value of propagated features. The
|
||||
<optimization> feature is propagated, so both "app" and
|
||||
"lib1" will be compiled with full optimization. But
|
||||
<cxxflags> feature is not propagated: its value will be added
|
||||
as-is to compiler flags for "a.cpp", but won't affect "lib1". There
|
||||
is still a couple of problems. First, the library probably has some
|
||||
headers which must be used when compiling "app.cpp". We could use
|
||||
requirements on "app" to add those includes, but then this work
|
||||
will be repeated for all programs which use "lib1". A better
|
||||
solution is to modify lib/lib1/Jamfilie in this way:
|
||||
|
||||
<programlisting>
|
||||
project
|
||||
: usage-requirements <include>.
|
||||
;
|
||||
|
||||
lib lib1 : lib1.cpp ;
|
||||
</programlisting>
|
||||
|
||||
Usage requirements are requirements which are applied to
|
||||
dependents. In this case, <include> will be applied to all
|
||||
targets which use "lib1" — i.e. targets which have "lib1"
|
||||
either in sources or in dependency properties. You'd need to
|
||||
specify usage requirements only once, and programs which use "lib1"
|
||||
don't have to care about include paths any longer. Or course, the
|
||||
path will be interpreted relatively to "lib/lib1" and will be
|
||||
adjusted according to the <command>bjam</command>s invocation
|
||||
directory. For
|
||||
example, if building from project root, the final compiler's
|
||||
command line will contain <option>-Ilib/lib1</option>.
|
||||
</para>
|
||||
|
||||
<para>The second problem is that we hardcode the path to library's
|
||||
Jamfile. Imagine it's hardcoded in 20 different places and we
|
||||
change the directory layout. The solution is to use project ids
|
||||
— symbolic names, not tied to directory layout. First, we
|
||||
assign a project id to Jamfile in lib/lib1:</para>
|
||||
|
||||
<programlisting>
|
||||
project lib1
|
||||
: usage-requirements <include>.
|
||||
;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Second, we use the project id to refer to the library in
|
||||
src/Jamfile:
|
||||
|
||||
<programlisting>
|
||||
exe app : app.cpp /lib1//lib1 ;
|
||||
</programlisting>
|
||||
|
||||
The "/lib1//lib1" syntax is used to refer to target "lib1" in
|
||||
project with global id "/lib1" (the slash is used to specify global
|
||||
id). This way, users of "lib1" do not depend on its location, only
|
||||
on id, which is supposedly stable. The only thing left, it to make
|
||||
sure that src/Jamfile knows the project id that it uses. We add to
|
||||
[top]/Jamfile the following line:
|
||||
|
||||
<programlisting>
|
||||
use-project /lib1 : lib/lib1 ;
|
||||
</programlisting>
|
||||
|
||||
Now, all projects can refer to "lib1" using the symbolic
|
||||
name. If the library is moved somewhere, only a single line in the
|
||||
top-level Jamfile should be changed.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.tutorial.depends">
|
||||
<title>Library dependencies</title>
|
||||
|
||||
<para>The previous example was simple. Often, there are long chains
|
||||
of dependencies between libraries. The main application is a thin
|
||||
wrapper on top of library with core logic, which uses library of
|
||||
utility functions, which uses boost filesystem library.
|
||||
Expressing these dependencies is straightforward:</para>
|
||||
|
||||
<programlisting>
|
||||
lib utils : utils.cpp /boost/filesystem//fs ;
|
||||
lib core : core.cpp utils ;
|
||||
exe app : app.cpp core ;
|
||||
</programlisting>
|
||||
|
||||
<para>So, what's the reason to even mention this case? First,
|
||||
because it's a bit more complex that it seems. When using shared
|
||||
linking, libraries are build just as written, and everything will
|
||||
work. However, what happens with static linking? It's not
|
||||
possible to include another library in static library.
|
||||
Boost.Build solves this problem by returning back library targets
|
||||
which appear as sources for static libraries. In this case, if
|
||||
everything is built statically, the "app" target will link not
|
||||
only "core" library, but also "utils" and
|
||||
"/boost/filesystem//fs".</para>
|
||||
|
||||
<para>So, the net result is that the above code will work for both
|
||||
static linking and for shared linking.</para>
|
||||
|
||||
<para>Sometimes, you want all applications in some project to link
|
||||
to a certain library. Putting the library in sources of all
|
||||
targets is possible, but verbose. You can do better by using
|
||||
<library> property. For example, if "/boost/filesystem//fs"
|
||||
should be linked to all applications in your project, you can add
|
||||
<library>/boost/filesystem//fs to requirements of the
|
||||
project, like this:</para>
|
||||
|
||||
<programlisting>
|
||||
project
|
||||
: requirements <library>/boost/filesystem//fs
|
||||
;
|
||||
</programlisting>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.tutorial.linkage">
|
||||
<title>Static and shared libaries</title>
|
||||
|
||||
<para>While the
|
||||
previous section explained how to create and use libraries, it
|
||||
omitted one important detail. Libraries can be either
|
||||
<emphasis>static</emphasis>, which means they are included in executable
|
||||
files which use them, or <emphasis>shared</emphasis> (a.k.a.
|
||||
<emphasis>dynamic</emphasis>), which are only referred to from executables,
|
||||
and must be available at run time. Boost.Build can work with both
|
||||
types. By default, all libraries are shared. This is much more
|
||||
efficient in build time and space. But the need to install all
|
||||
libraries to some location is not always convenient, especially
|
||||
for debug builds. Also, if the installed shared library changes,
|
||||
all application which use it might start to behave differently.
|
||||
</para>
|
||||
|
||||
<para>Static libraries do not suffer from these problems, but
|
||||
considerably increase the size of application. Before describing
|
||||
static libraries, it's reasonable to give another, quite simple
|
||||
approach. If your project is built with
|
||||
<hardcode-dll-paths>true property, then the application
|
||||
will include the full paths for all shared libraries, eliminating
|
||||
the above problems. Unfortunately, you no longer can move shared
|
||||
library to a different location, which makes this option suitable
|
||||
only for debug builds. Further, only gcc compiler supports this
|
||||
option.</para>
|
||||
|
||||
<para>Building a library statically is easy. You'd need to change
|
||||
the value of <link> feature from it's deafault value
|
||||
<literal>shared</literal>, to <literal>static</literal>. So, to build everything as
|
||||
static libraries, you'd say</para>
|
||||
|
||||
<screen>
|
||||
bjam link=static
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
on the command line. The linking mode can be fine-tuned on
|
||||
per-target basis.
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Suppose your library can be only build statically. This is
|
||||
easily achieved using requirements:
|
||||
|
||||
<programlisting>
|
||||
lib l : l.cpp : <link>static ;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
What if library can be both static and shared, but when
|
||||
using it in specific executable, you want it static?
|
||||
<link linkend="bbv2.advanced.targets.references">Target
|
||||
references</link> are here to help:
|
||||
|
||||
<programlisting>
|
||||
exe important : main.cpp helpers/<link>static ;
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
What if the library is defined in some other project, which
|
||||
you cannot change. But still, you want static linking to that
|
||||
library in all cases. You can use target references everywhere:
|
||||
|
||||
<programlisting>
|
||||
exe e1 : e1.cpp /other_project//lib1/<link>static ;
|
||||
exe e10 : e10.cpp /other_project//lib1/<link>static ;
|
||||
</programlisting>
|
||||
|
||||
but that's far from being convenient. Another way is to
|
||||
introduce a level of indirection: create a local target, which will
|
||||
refer to static version of <filename>lib1</filename>. Here's the
|
||||
solution:
|
||||
|
||||
<programlisting>
|
||||
alias lib1 : /other_project//lib1/<link>static ;
|
||||
exe e1 : e1.cpp lib1 ;
|
||||
exe e10 : e10.cpp lib1 ;
|
||||
</programlisting>
|
||||
|
||||
(Note, that the "alias" target type is not yet implemented,
|
||||
but it's quite simple to do. I bet it's waiting for you to do it
|
||||
;-))
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="bbv2.tutorial.prebuilt">
|
||||
<title>Prebuilt targets</title>
|
||||
|
||||
<para>
|
||||
We've just learned how to use libraries which are created by
|
||||
Boost.Build. But some libraries are not. At the same time, those
|
||||
libraries can have different versions (release and debug, for
|
||||
example), that we
|
||||
should select depending on build properties. Prebuilt targets
|
||||
provide a mechanism for that. Jamfile in lib/lib2 can contain:
|
||||
|
||||
<programlisting>
|
||||
lib lib2
|
||||
:
|
||||
: <file>lib2_release.a <variant>release
|
||||
;
|
||||
|
||||
lib lib2
|
||||
:
|
||||
: <file>lib2_debug.a <variant>debug
|
||||
;
|
||||
</programlisting>
|
||||
|
||||
This defines two alternatives for target "lib2", and for each
|
||||
one names a prebuilt file. Naturally, there are no sources.
|
||||
Instead, the <file> feature is used to specify the file name.
|
||||
Which alternative is selected depends on properties of dependents.
|
||||
If "app" binary should use "lib2", we can write:
|
||||
|
||||
<programlisting>
|
||||
exe app : app.cpp /lib/lib1//lib2 ../lib/lib2//lib2 ;
|
||||
</programlisting>
|
||||
|
||||
If we build release version of "app", then it will be linked
|
||||
with "lib2_release.a", and debug version will use "lib2_debug.a".
|
||||
Another important kind of prebuilt targets are system libraries
|
||||
— more specifically, libraries which are automatically found
|
||||
by the compiler. E.g. gcc uses "-l" switch for that. Such libraries
|
||||
should be declared almost like regular ones:
|
||||
|
||||
<programlisting>
|
||||
lib zlib : : <name>z ;
|
||||
</programlisting>
|
||||
|
||||
We again don't specify any sources, but give a name which
|
||||
should be passed to the compiler. In this example, and for gcc
|
||||
compiler, the "-lz" option will be added. Paths where library
|
||||
should be searched can also be specified:
|
||||
|
||||
<programlisting>
|
||||
lib zlib : : <name>z <search>/opt/lib ;
|
||||
</programlisting>
|
||||
|
||||
And, of course, two variants can be used:
|
||||
|
||||
<programlisting>
|
||||
lib zlib : : <name>z <variant>release ;
|
||||
lib zlib : : <name>z_d <variant>debug ;
|
||||
</programlisting>
|
||||
|
||||
Of course, you'll probably never in your life need debug
|
||||
version of zlib, but for other libraries this is quite reasonable.
|
||||
</para>
|
||||
|
||||
<para>More advanced use of prebuilt target is descibed in <ulink
|
||||
url="doc/recipes.html#site_config_targets">recipes</ulink>.</para>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
23
v2/doc/src/userman.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE part 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"
|
||||
id="bbv2" last-revision="$Date$">
|
||||
|
||||
<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="reference.xml"/>
|
||||
<xi:include href="faq.xml"/>
|
||||
|
||||
<!-- Appendicies -->
|
||||
<xi:include href="extending.xml"/>
|
||||
<xi:include href="recipes.xml"/>
|
||||
<xi:include href="architecture.xml"/>
|
||||
|
||||
</part>
|