mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			683 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			683 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
| <?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.
 | |
|     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 language="jam">
 | |
| exe hello : hello.cpp ;
 | |
| </programlisting>
 | |
| 
 | |
|       Even with this simple setup, you can do some interesting things. First of
 | |
|       all, just invoking <command>b2</command> will build the <filename>hello
 | |
|       </filename> executable by compiling and linking <filename>hello.cpp
 | |
|       </filename>. By default, the debug variant is built. Now, to build the release
 | |
|       variant of <filename>hello</filename>, invoke
 | |
| 
 | |
| <screen>
 | |
| b2 release
 | |
| </screen>
 | |
| 
 | |
|       Note that the 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 language="jam">
 | |
| exe hello2 : hello.cpp ;
 | |
| </programlisting>
 | |
| 
 | |
|       Now let us build both the debug and release variants of our project again:
 | |
| 
 | |
| <screen>
 | |
| b2 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>
 | |
| b2 --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>
 | |
| b2 hello2
 | |
| b2 --clean hello2
 | |
| </screen>
 | |
|     </para>
 | |
|   </section>
 | |
| 
 | |
|   <section id="bbv2.tutorial.properties">
 | |
|     <title>Properties</title>
 | |
| 
 | |
|     <para>
 | |
|       To represent aspects of target configuration such as
 | |
|       debug and release variants, or single- and multi-threaded
 | |
|       builds portably, 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>
 | |
| b2 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>b2</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>
 | |
| b2 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 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 constitutes
 | |
|         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 language="jam">
 | |
| 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>b2</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>
 | |
|         augment) 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 language="jam">
 | |
| 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, 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 language="jam">
 | |
| <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>b2</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 language="jam">
 | |
| 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 building a target <filename>X</filename> that 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 language="jam">
 | |
| lib bar : bar.cpp ;
 | |
| </programlisting>
 | |
| 
 | |
|       then to use this library in <filename>top/app/Jamfile</filename>, we can
 | |
|       write:
 | |
| 
 | |
| <programlisting language="jam">
 | |
| 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>
 | |
| b2 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 language="jam">
 | |
| project
 | |
|     : usage-requirements <include>.
 | |
|     ;
 | |
| 
 | |
| lib foo : foo.cpp ;</programlisting>
 | |
| 
 | |
|       Usage requirements are applied not to the target being declared but to its
 | |
|       dependents. 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 language="jam">
 | |
| 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 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 language="jam">
 | |
| project
 | |
|    : requirements <library>/boost/filesystem//fs
 | |
|    ;</programlisting>
 | |
|     </tip>
 | |
|   </section>
 | |
| 
 | |
|   <section id="bbv2.tutorial.linkage">
 | |
|     <title>Static and shared libraries</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>b2 link=static</programlisting>
 | |
|       or in the library's requirements:
 | |
|       <programlisting language="jam">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 language="jam">
 | |
| exe important : main.cpp helpers/<link>static ;</programlisting>
 | |
| 
 | |
|       No matter what arguments are specified on the <command>b2</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 language="jam">
 | |
| 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">alias</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 language="jam">
 | |
| 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, links <filename>utils
 | |
|         </filename> directly into it. 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 language="jam">
 | |
| lib network : network.cpp
 | |
|     : <emphasis role="bold"><link>shared:<define>NETWORK_LIB_SHARED</emphasis>
 | |
|      <variant>release:<define>EXTRA_FAST
 | |
|     ;</programlisting>
 | |
| 
 | |
|       In the example above, whenever <filename>network</filename> is built with
 | |
|       <code language="jam"><link>shared</code>, <code language="jam"><define>NETWORK_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 language="jam">
 | |
| 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 language="jam"><toolset>gcc</code>
 | |
|       alternative 2, will be selected, and when building with
 | |
|       <code language="jam"><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 language="jam">
 | |
| # 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 language="jam">
 | |
| 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 dependents. If we build the
 | |
|       release and debug versions of <filename>app</filename> it 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 language="jam">
 | |
| 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 language="jam">
 | |
| lib pythonlib : : <name>python22 <search>/opt/lib ;</programlisting>
 | |
| 
 | |
|       And, of course, target alternatives can be used in the usual way:
 | |
| 
 | |
|       <programlisting language="jam">
 | |
| 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:
 | |
| -->
 |