summaryrefslogtreecommitdiff
path: root/tools/build/v2/doc/src/tutorial.xml
blob: 3763471dfe538fd676bfa417b5da2fbaad830d74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
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 &#x201C;Hello, world&#x201D; 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&#x2014;
      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>&#x2014;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
    : &lt;include&gt;boost &lt;threading&gt;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 &#x201C;free&rdquo;&#x201D; features like
        <varname>&lt;include&gt;</varname>,
        <footnote>
          <para>
             See <xref linkend="bbv2.reference.features.attributes"/>
          </para>
        </footnote>
        augments) the build request.
      </para>

      <tip>
        <para>
          The value of the <varname>&lt;include&gt;</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 &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;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 &#x2014;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 &#x201C;Jamfile,&#x201D; 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
          &#x201C;<filename>Jamfile</filename>&#x201D; or
          &#x201C;<filename>Jamroot</filename>.&#x201D;
        </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>
&lt;include&gt;/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>&#x2014;Boost.Build attempts to use
    dependencies with the same value of propagated features. The
    <varname>&lt;optimization&gt;</varname> feature is propagated, so both
    <filename>app</filename> and <filename>foo</filename> will be compiled
    with full optimization. But <varname>&lt;define&gt;</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>&lt;include&gt;
      </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 &lt;include&gt;.
    ;

lib foo : foo.cpp ;</programlisting>

      Usage requirements are applied not to the target being declared but to its
      dependants. In this case, <literal>&lt;include&gt;.</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&#x2014;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&#x2014;if the
      library is moved to a different directory, only <filename>Jamroot
      </filename> must be modified. Note that project ids are global&#x2014;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>&lt;library&gt;</varname> property.
        For example, if <filename>/boost/filesystem//fs</filename> should be
        linked to all applications in your project, you can add
        <code>&lt;library&gt;/boost/filesystem//fs</code> to the project's
        requirements, like this:
      </para>

      <programlisting>
project
   : requirements &lt;library&gt;/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 : &lt;link&gt;static ;</programlisting>
    </para>

    <para>
      We can also use the <varname>&lt;link&gt;</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/&lt;link&gt;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/&lt;link&gt;static ;
exe e10 : e10.cpp /other_project//bar/&lt;link&gt;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/&lt;link&gt;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&#x2014;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">&lt;link&gt;shared:&lt;define&gt;NEWORK_LIB_SHARED</emphasis>
     &lt;variant&gt;release:&lt;define&gt;EXTRA_FAST
    ;</programlisting>

      In the example above, whenever <filename>network</filename> is built with
      <code>&lt;link&gt;shared</code>, <code>&lt;define&gt;NEWORK_LIB_SHARED
      </code> will be in its properties, too. Also, whenever its release variant
      is built, <code>&lt;define&gt;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 : &lt;toolset&gt;gcc ;   # alternative 2
lib demangler : demangler_msvc.cpp : &lt;toolset&gt;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>&lt;toolset&gt;gcc</code>
      alternative 2, will be selected, and when building with
      <code>&lt;toolset&gt;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
    :
    : &lt;file&gt;lib2_release.a &lt;variant&gt;release
    ;

lib lib2
    :
    : &lt;file&gt;lib2_debug.a &lt;variant&gt;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>&lt;file&gt;</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&#x2014;those that are automatically found by the toolset
      by searching through some set of predetermined paths&#x2014;should be
      declared almost like regular ones:

      <programlisting>
lib pythonlib : : &lt;name&gt;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 : : &lt;name&gt;python22 &lt;search&gt;/opt/lib ;</programlisting>

      And, of course, target alternatives can be used in the usual way:

      <programlisting>
lib pythonlib : : &lt;name&gt;python22 &lt;variant&gt;release ;
lib pythonlib : : &lt;name&gt;python22_d &lt;variant&gt;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:
-->