diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /tools/build/v2/doc/src/tutorial.xml | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'tools/build/v2/doc/src/tutorial.xml')
-rw-r--r-- | tools/build/v2/doc/src/tutorial.xml | 681 |
1 files changed, 681 insertions, 0 deletions
diff --git a/tools/build/v2/doc/src/tutorial.xml b/tools/build/v2/doc/src/tutorial.xml new file mode 100644 index 0000000000..3763471dfe --- /dev/null +++ b/tools/build/v2/doc/src/tutorial.xml @@ -0,0 +1,681 @@ +<?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"> + +<?psgml nofill screen programlisting literallayout?> + +<chapter id="bbv2.tutorial"> + <title>Tutorial</title> + +<!-- You can't launch into this stuff without describing how to configure --> +<!-- Boost.Build... unless of course you think it's likely to work with --> +<!-- no configuration. But even if you do you have to tell people how to --> +<!-- configure their installation in case it doesn't work. --> +<!-- + VP: need also mention the examples which correspond to specific + sections. +--> + + <para> + This section will guide you though the most basic features of Boost.Build + V2. We will start with the “Hello, world” example, learn how + to use libraries, and finish with testing and installing features. + </para> + + <section id="bbv2.tutorial.hello"> + <title>Hello, world</title> + + <para> + The simplest project that Boost.Build can construct is stored in + <filename>example/hello/</filename> directory. The project is described by + a file called <filename>Jamroot</filename> that contains: + +<programlisting> +exe hello : hello.cpp ; +</programlisting> + + Even with this simple setup, you can do some interesting things. First of + all, just invoking <command>bjam</command> will build the <filename>hello + </filename> executable by compiling and linking <filename>hello.cpp + </filename>. By default, debug variant is built. Now, to build the release + variant of <filename>hello</filename>, invoke + +<screen> +bjam release +</screen> + + Note that debug and release variants are created in different directories, + so you can switch between variants or even build multiple variants at + once, without any unnecessary recompilation. Let us extend the example by + adding another line to our project's <filename>Jamroot</filename>: + +<programlisting> +exe hello2 : hello.cpp ; +</programlisting> + + Now let us build both the debug and release variants of our project again: + +<screen> +bjam debug release +</screen> + + Note that two variants of <filename>hello2</filename> are linked. Since we + have already built both variants of <filename>hello</filename>, hello.cpp + will not be recompiled; instead the existing object files will just be + linked into the corresponding variants of <filename>hello2</filename>. Now + let us remove all the built products: + +<screen> +bjam --clean debug release +</screen> + + It is also possible to build or clean specific targets. The following two + commands, respectively, build or clean only the debug version of + <filename>hello2</filename>. + +<screen> +bjam hello2 +bjam --clean hello2 +</screen> + </para> + </section> + + <section id="bbv2.tutorial.properties"> + <title>Properties</title> + + <para> + To portably represent aspects of target configuration such as + debug and release variants, or single- and multi-threaded + builds, Boost.Build uses <firstterm>features</firstterm> with + associated <firstterm>values</firstterm>. For + example, the <code>debug-symbols</code> feature can have a value of <code>on</code> or + <code>off</code>. A <firstterm>property</firstterm> is just a (feature, + value) pair. When a user initiates a build, Boost.Build + automatically translates the requested properties into appropriate + command-line flags for invoking toolset components like compilers + and linkers. + </para> + + <para> + There are many built-in features that can be combined to + produce arbitrary build configurations. The following command + builds the project's <code>release</code> variant with inlining + disabled and debug symbols enabled: +<screen> +bjam release inlining=off debug-symbols=on +</screen> + </para> + + <para> + Properties on the command-line are specified with the syntax: + +<screen> +<replaceable>feature-name</replaceable>=<replaceable>feature-value</replaceable> +</screen> + </para> + + <para> + The <option>release</option> and <option>debug</option> that we have seen + in <command>bjam</command> invocations are just a shorthand way to specify + values of the <varname>variant</varname> feature. For example, the + command above could also have been written this way: + + <screen> +bjam variant=release inlining=off debug-symbols=on + </screen> + </para> + + <para> + <varname>variant</varname> is so commonly-used that it has been given + special status as an <firstterm>implicit</firstterm> feature— + Boost.Build will deduce the its identity just from the name of one of its + values. + </para> + + <para> + A complete description of features can be found in <xref linkend="bbv2.reference.features"/>. + </para> + + <section id="bbv2.tutorial.properties.requirements"> + <title>Build Requests and Target Requirements</title> + + <para> + The set of properties specified on the command line constitute + a <firstterm>build request</firstterm>—a description of + the desired properties for building the requested targets (or, + if no targets were explicitly requested, the project in the + current directory). The <emphasis>actual</emphasis> + properties used for building targets are typically a + combination of the build request and properties derived from + the project's <filename>Jamroot</filename> (and its other + Jamfiles, as described in <xref + linkend="bbv2.tutorial.hierarchy"/>). For example, the + locations of <code>#include</code>d header files are normally + not specified on the command-line, but described in + Jamfiles as <firstterm>target + requirements</firstterm> and automatically combined with the + build request for those targets. Multithread-enabled + compilation is another example of a typical target + requirement. The Jamfile fragment below + illustrates how these requirements might be specified. + </para> + +<programlisting> +exe hello + : hello.cpp + : <include>boost <threading>multi + ; +</programlisting> + + <para> + When <filename>hello</filename> is built, the two requirements specified + above will always be present. If the build request given on the + <command>bjam</command> command-line explictly contradicts a target's + requirements, the target requirements usually override (or, in the case + of “free”” features like + <varname><include></varname>, + <footnote> + <para> + See <xref linkend="bbv2.reference.features.attributes"/> + </para> + </footnote> + augments) the build request. + </para> + + <tip> + <para> + The value of the <varname><include></varname> feature is + relative to the location of <filename>Jamroot</filename> where it is + used. + </para> + </tip> + </section> + + <section id="bbv2.tutorial.properties.project_attributes"> + <title>Project Attributes</title> + + <para> + If we want the same requirements for our other target, <filename>hello2 + </filename>, we could simply duplicate them. However, as projects grow, + that approach leads to a great deal of repeated boilerplate in Jamfiles. + + Fortunately, there's a better way. Each project can specify a set of + <firstterm>attributes</firstterm>, 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 the same requirement for both + <filename>hello</filename> and <filename>hello2</filename>. + </para> + </section> + </section> + + <section id="bbv2.tutorial.hierarchy"> + <title>Project Hierarchies</title> + + <para> + So far we have only considered examples with one project —a. with + one user-written Boost.Jam file, <filename>Jamroot</filename>). A typical + large codebase would be composed of many projects organized into a tree. + The top of the tree is called the <firstterm>project root</firstterm>. + Every subproject is defined by a file called <filename>Jamfile</filename> + in a descendant directory of the project root. The parent project of a + subproject is defined by the nearest <filename>Jamfile</filename> or + <filename>Jamroot</filename> file in an ancestor directory. For example, + in the following directory layout: + +<screen> +top/ + | + +-- Jamroot + | + +-- app/ + | | + | +-- Jamfile + | `-- app.cpp + | + `-- util/ + | + +-- foo/ + . | + . +-- Jamfile + . `-- bar.cpp +</screen> + + the project root is <filename>top/</filename>. The projects in + <filename>top/app/</filename> and <filename>top/util/foo/</filename> are + immediate children of the root project. + + <note> + <para> + When we refer to a “Jamfile,” set in normal + type, we mean a file called either + <filename>Jamfile</filename> or + <filename>Jamroot</filename>. When we need to be more + specific, the filename will be set as + “<filename>Jamfile</filename>” or + “<filename>Jamroot</filename>.” + </para> + </note> + </para> + + <para> + Projects inherit all attributes (such as requirements) + from their parents. Inherited requirements are combined with + any requirements specified by the subproject. + For example, if <filename>top/Jamroot</filename> has + +<programlisting> +<include>/home/ghost/local +</programlisting> + + in its requirements, then all of its subprojects will have it + in their requirements, too. Of course, any project can add + include paths to those specified by its parents. <footnote> + <para>Many + features will be overridden, + rather than added-to, in subprojects. See <xref + linkend="bbv2.reference.features.attributes"/> for more + information</para> + </footnote> + More details can be found in + <xref linkend= "bbv2.overview.projects"/>. + </para> + + <para> + Invoking <command>bjam</command> without explicitly specifying + any targets on the command line builds the project rooted in the + current directory. Building a project does not automatically + cause its subprojects to be built unless the parent project's + Jamfile explicitly requests it. In our example, + <filename>top/Jamroot</filename> might contain: + +<programlisting> +build-project app ; +</programlisting> + + which would cause the project in <filename>top/app/</filename> + to be built whenever the project in <filename>top/</filename> is + built. However, targets in <filename>top/util/foo/</filename> + will be built only if they are needed by targets in + <filename>top/</filename> or <filename>top/app/</filename>. + </para> + </section> + + <section id="bbv2.tutorial.libs"> + <title>Dependent Targets</title> + + <para> + When a building a target <filename>X</filename> depends on first + building another target <filename>Y</filename> (such as a + library that must be linked with <firstterm>X</firstterm>), + <filename>Y</filename> is called a + <firstterm>dependency</firstterm> of <filename>X</filename> and + <filename>X</filename> is termed a + <firstterm>dependent</firstterm> of <filename>Y</filename>. + </para> + + <para>To get a feeling of target dependencies, let's continue the + above example and see how <filename>top/app/Jamfile</filename> can + use libraries from <filename>top/util/foo</filename>. If + <filename>top/util/foo/Jamfile</filename> contains + +<programlisting> +lib bar : bar.cpp ; +</programlisting> + + then to use this library in <filename>top/app/Jamfile</filename>, we can + write: + +<programlisting> +exe app : app.cpp ../util/foo//bar ; +</programlisting> + + While <code>app.cpp</code> refers to a regular source file, + <code>../util/foo//bar</code> is a reference to another target: + a library <filename>bar</filename> declared in the Jamfile at + <filename>../util/foo</filename>. + </para> + + <tip> + <para>Some other build system have special syntax for listing dependent + libraries, for example <varname>LIBS</varname> variable. In Boost.Build, + you just add the library to the list of sources. + </para> + </tip> + + <para>Suppose we build <filename>app</filename> with: + <screen> +bjam app optimization=full define=USE_ASM + </screen> + Which properties will be used to build <code>foo</code>? The answer is + that some features are + <firstterm>propagated</firstterm>—Boost.Build attempts to use + dependencies with the same value of propagated features. The + <varname><optimization></varname> feature is propagated, so both + <filename>app</filename> and <filename>foo</filename> will be compiled + with full optimization. But <varname><define></varname> is not + propagated: its value will be added as-is to the compiler flags for + <filename>a.cpp</filename>, but won't affect <filename>foo</filename>. + </para> + + + <para> + Let's improve this project further. The library probably has some headers + that must be used when compiling <filename>app.cpp</filename>. We could + manually add the necessary <code>#include</code> paths to <filename>app + </filename>'s requirements as values of the <varname><include> + </varname> feature, but then this work will be repeated for all programs + that use <filename>foo</filename>. A better solution is to modify + <filename>util/foo/Jamfile</filename> in this way: + + <programlisting> +project + : usage-requirements <include>. + ; + +lib foo : foo.cpp ;</programlisting> + + Usage requirements are applied not to the target being declared but to its + dependants. In this case, <literal><include>.</literal> will be + applied to all targets that directly depend on <filename>foo</filename>. + </para> + + <para> + Another improvement is using symbolic identifiers to refer to the library, + as opposed to <filename>Jamfile</filename> location. In a large project, a + library can be used by many targets, and if they all use <filename>Jamfile + </filename> location, a change in directory organization entails much + work. The solution is to use project ids—symbolic names not tied to + directory layout. First, we need to assign a project id by adding this + code to <filename>Jamroot</filename>: + </para> + + <programlisting> +use-project /library-example/foo : util/foo ;</programlisting> + + <para> + Second, we modify <filename>app/Jamfile</filename> to use the project id: + <programlisting> +exe app : app.cpp /library-example/foo//bar ;</programlisting> + + The <filename>/library-example/foo//bar</filename> syntax is used to refer + to the target <filename>bar</filename> in the project with id <filename> + /library-example/foo</filename>. We've achieved our goal—if the + library is moved to a different directory, only <filename>Jamroot + </filename> must be modified. Note that project ids are global—two + Jamfiles are not allowed to assign the same project id to different + directories. + </para> + + <tip> + <para>If you want all applications in some project to link to a certain + library, you can avoid having to specify it directly the sources of + every target by using the <varname><library></varname> property. + For example, if <filename>/boost/filesystem//fs</filename> should be + linked to all applications in your project, you can add + <code><library>/boost/filesystem//fs</code> to the project's + requirements, like this: + </para> + + <programlisting> +project + : requirements <library>/boost/filesystem//fs + ;</programlisting> + </tip> + </section> + + <section id="bbv2.tutorial.linkage"> + <title>Static and shared libaries</title> + + <para> + Libraries can be either <emphasis>static</emphasis>, which means they are + included in executable files that 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 create and + use both kinds. + </para> + + <para> + The kind of library produced from a <code>lib</code> target is determined + by the value of the <varname>link</varname> feature. Default value is + <literal>shared</literal>, and to build a static library, the value should + be <literal>static</literal>. You can request a static build either on the + command line: + <programlisting>bjam link=static</programlisting> + or in the library's requirements: + <programlisting>lib l : l.cpp : <link>static ;</programlisting> + </para> + + <para> + We can also use the <varname><link></varname> property to express + linking requirements on a per-target basis. For example, if a particular + executable can be correctly built only with the static version of a + library, we can qualify the executable's <link + linkend="bbv2.reference.targets.references">target reference</link> to the + library as follows: + +<!-- There has been no earlier indication that target references can contain + properties. You can't assume that the reader will recognize that strange + incantation as a target reference, or that she'll know what it means. You + also can't assume that hyperlinks will help the reader, because she may be + working from a printout, as I was. + VP: to be addressed when this section is moved. See comment below. +--> + + <programlisting> +exe important : main.cpp helpers/<link>static ;</programlisting> + + No matter what arguments are specified on the <command>bjam</command> + command line, <filename>important</filename> will only be linked with the + static version of <filename>helpers</filename>. + </para> + + <para> + Specifying properties in target references is especially useful if you use + a library defined in some other project (one you can't change) but you + still want static (or dynamic) linking to that library in all cases. If + that library is used by many targets, you <emphasis>could</emphasis> use + target references everywhere: + + <programlisting> +exe e1 : e1.cpp /other_project//bar/<link>static ; +exe e10 : e10.cpp /other_project//bar/<link>static ;</programlisting> + + but that's far from being convenient. A better approach is to introduce a + level of indirection. Create a local <type>alias</type> target that refers + to the static (or dynamic) version of <filename>foo</filename>: + + <programlisting> +alias foo : /other_project//bar/<link>static ; +exe e1 : e1.cpp foo ; +exe e10 : e10.cpp foo ;</programlisting> + + The <link linkend="bbv2.tasks.alias"><functionname>alias</functionname> + </link> rule is specifically used to rename a reference to a target and + possibly change the properties. + + <!-- You should introduce the alias rule in an earlier section, before + describing how it applies to this specific use-case, and the + foregoing sentence should go there. + VP: we've agreed that this section should be moved further in the + docs, since it's more like advanced reading. When I move it, I'll + make sure 'alias' is already mentioned. + --> + </para> + + <tip> + <para> + When one library uses another, you put the second library in the source + list of the first. For example: + <programlisting> +lib utils : utils.cpp /boost/filesystem//fs ; +lib core : core.cpp utils ; +exe app : app.cpp core ;</programlisting> + This works no matter what kind of linking is used. When <filename>core + </filename> is built as a shared library, it is linked directly into + <filename>utils</filename>. Static libraries can't link to other + libraries, so when <filename>core</filename> is built as a static + library, its dependency on <filename>utils</filename> is passed along to + <filename>core</filename>'s dependents, causing <filename>app</filename> + to be linked with both <filename>core</filename> and <filename>utils + </filename>. + </para> + </tip> + + <note> + <para> + (Note for non-UNIX system). Typically, shared libraries must be + installed to a directory in the dynamic linker's search path. Otherwise, + applications that use shared libraries can't be started. On Windows, the + dynamic linker's search path is given by the <envar>PATH</envar> + environment variable. This restriction is lifted when you use + Boost.Build testing facilities—the <envar>PATH</envar> variable + will be automatically adjusted before running the executable. + <!-- Need ref here to 'testing facilities' --> + </para> + </note> + </section> + + <section id="bbv2.tutorial.conditions"> + <title>Conditions and alternatives</title> + + <para> + Sometimes, particular relationships need to be maintained among a target's + build properties. For example, you might want to set specific <code> + #define</code> when a library is built as shared, or when a target's + <code>release</code> variant is built. This can be achieved using + <firstterm>conditional requirements</firstterm>. + + <programlisting> +lib network : network.cpp + : <emphasis role="bold"><link>shared:<define>NEWORK_LIB_SHARED</emphasis> + <variant>release:<define>EXTRA_FAST + ;</programlisting> + + In the example above, whenever <filename>network</filename> is built with + <code><link>shared</code>, <code><define>NEWORK_LIB_SHARED + </code> will be in its properties, too. Also, whenever its release variant + is built, <code><define>EXTRA_FAST</code> will appear in its + properties. + </para> + + <para> + Sometimes the ways a target is built are so different that describing them + using conditional requirements would be hard. For example, imagine that a + library actually uses different source files depending on the toolset used + to build it. We can express this situation using <firstterm>target + alternatives</firstterm>: + <programlisting> +lib demangler : dummy_demangler.cpp ; # alternative 1 +lib demangler : demangler_gcc.cpp : <toolset>gcc ; # alternative 2 +lib demangler : demangler_msvc.cpp : <toolset>msvc ; # alternative 3</programlisting> + When building <filename>demangler</filename>, Boost.Build will compare + requirements for each alternative with build properties to find the best + match. For example, when building with <code><toolset>gcc</code> + alternative 2, will be selected, and when building with + <code><toolset>msvc</code> alternative 3 will be selected. In all + other cases, the most generic alternative 1 will be built. + </para> + </section> + + <section id="bbv2.tutorial.prebuilt"> + <title>Prebuilt targets</title> + + <para> + To link to libraries whose build instructions aren't given in a Jamfile, + you need to create <code>lib</code> targets with an appropriate + <varname>file</varname> property. Target alternatives can be used to + associate multiple library files with a single conceptual target. For + example: + <programlisting> +# util/lib2/Jamfile +lib lib2 + : + : <file>lib2_release.a <variant>release + ; + +lib lib2 + : + : <file>lib2_debug.a <variant>debug + ;</programlisting> + + This example defines two alternatives for <filename>lib2</filename>, and + for each one names a prebuilt file. Naturally, there are no sources. + Instead, the <varname><file></varname> feature is used to specify + the file name. + </para> + + <para> + Once a prebuilt target has been declared, it can be used just like any + other target: + + <programlisting> +exe app : app.cpp ../util/lib2//lib2 ;</programlisting> + + As with any target, the alternative selected depends on the properties + propagated from <filename>lib2</filename>'s dependants. If we build the + release and debug versions of <filename>app</filename> will be linked + with <filename>lib2_release.a</filename> and <filename>lib2_debug.a + </filename>, respectively. + </para> + + <para> + System libraries—those that are automatically found by the toolset + by searching through some set of predetermined paths—should be + declared almost like regular ones: + + <programlisting> +lib pythonlib : : <name>python22 ;</programlisting> + + We again don't specify any sources, but give a <varname>name</varname> + that should be passed to the compiler. If the gcc toolset were used to + link an executable target to <filename>pythonlib</filename>, + <option>-lpython22</option> would appear in the command line (other + compilers may use different options). + </para> + + <para> + We can also specify where the toolset should look for the library: + + <programlisting> +lib pythonlib : : <name>python22 <search>/opt/lib ;</programlisting> + + And, of course, target alternatives can be used in the usual way: + + <programlisting> +lib pythonlib : : <name>python22 <variant>release ; +lib pythonlib : : <name>python22_d <variant>debug ;</programlisting> + </para> + + <para> + A more advanced use of prebuilt targets is described in <xref linkend= + "bbv2.recipies.site-config"/>. + </para> + </section> +</chapter> + +<!-- + Local Variables: + mode: nxml + sgml-indent-data:t + sgml-parent-document:("userman.xml" "chapter") + sgml-set-face: t + sgml-omittag:nil + sgml-shorttag:nil + sgml-namecase-general:t + sgml-general-insert-case:lower + sgml-minimize-attributes:nil + sgml-always-quote-attributes:t + sgml-indent-step:2 + sgml-exposed-tags:nil + sgml-local-catalogs:nil + sgml-local-ecat-files:nil + End: +--> |