Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/doc/html/bbv2/extender.html @ 46

Last change on this file since 46 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 35.4 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4<title>Extender Manual</title>
5<link rel="stylesheet" href="../boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
7<link rel="start" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
8<link rel="up" href="../bbv2.html" title="Chapter 25. Boost.Build V2 User Manual">
9<link rel="prev" href="tasks.html" title="Common tasks">
10<link rel="next" href="reference.html" title="Detailed reference">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%">
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
15<td align="center"><a href="../../../index.htm">Home</a></td>
16<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="../../../people/people.htm">People</a></td>
18<td align="center"><a href="../../../more/faq.htm">FAQ</a></td>
19<td align="center"><a href="../../../more/index.htm">More</a></td>
20</table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="tasks.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../bbv2.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../images/next.png" alt="Next"></a>
24</div>
25<div class="section" lang="en">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="bbv2.extender"></a>Extender Manual</h2></div></div></div>
28<div class="toc"><dl>
29<dt><span class="section"><a href="extender.html#bbv2.extender.intro">Introduction</a></span></dt>
30<dt><span class="section"><a href="extender.html#bbv2.extending.targets">Target types</a></span></dt>
31<dt><span class="section"><a href="extender.html#bbv2.extending.tools">Tools and generators</a></span></dt>
32<dt><span class="section"><a href="extender.html#bbv2.extending.features">Features</a></span></dt>
33<dt><span class="section"><a href="extender.html#bbv2.extending.rules">Main target rules</a></span></dt>
34<dt><span class="section"><a href="extender.html#bbv2.extending.toolset_modules">Toolset modules</a></span></dt>
35</dl></div>
36<div class="section" lang="en">
37<div class="titlepage"><div><div><h3 class="title">
38<a name="bbv2.extender.intro"></a>Introduction</h3></div></div></div>
39<p>This document explains how to extend Boost.Build to accomodate
40  your local requirements. Let's start with a simple but
41  realistic example.</p>
42<p>Say you're writing an application that generates C++ code. If
43  you ever did this, you know that it's not nice. Embedding large
44  portions of C++ code in string literals is very awkward. A much
45  better solution is:</p>
46<div class="orderedlist"><ol type="1">
47<li>
48        Write the template of the code to be generated, leaving
49    placeholders at the points that will change
50      </li>
51<li>
52        Access the template in your application and replace
53    placeholders with appropriate text.
54      </li>
55<li>Write the result.</li>
56</ol></div>
57<p>It's quite easy to achieve. You write special verbatim files
58  that are just C++, except that the very first line of the file
59  contains the name of a variable that should be generated. A simple tool
60  is created that takes a verbatim file and creates a cpp file with
61  a single <code class="computeroutput">char*</code> variable whose name is taken from the first line
62  of the verbatim file and whose value is the file's properly quoted content.</p>
63<p>Let's see what Boost.Build can do.</p>
64<p>First off, Boost.Build has no idea about "verbatim files". So,
65  you must register a new target type. The following code does
66  it:</p>
67<pre class="programlisting">
68import type ;
69type.register VERBATIM : vrb ;
70</pre>
71<p>The first parameter to
72  <code class="computeroutput">type.register</code> gives the name of the
73  declared type. By convention, it's uppercase. The second parameter
74  is the suffix for files of this type. So, if Boost.Build sees
75  <code class="filename">code.vrb</code> in a list of sources, it knows that it's of type
76  <code class="computeroutput">VERBATIM</code>.</p>
77<p>Next, you tell Boost.Build that the verbatim files can be
78  transformed into C++ files in one build step.  A
79  <em class="firstterm">generator</em> is a template for a build step that
80  transforms targets of one type (or set of types) into another.  Our
81  generator will be called <code class="computeroutput">verbatim.inline-file</code>; it
82  transforms <code class="computeroutput">VERBATIM</code> files into <code class="computeroutput">CPP</code> files:
83
84</p>
85<pre class="programlisting">
86import generators ;
87generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
88</pre>
89<p>
90  </p>
91<p>Lastly, you have to inform Boost.Build about the shell
92  commands used to make that transformation.  That's done with an
93  <code class="computeroutput">actions</code> declaration.
94
95</p>
96<pre class="programlisting">
97actions inline-file
98{
99    "./inline-file.py" $(&lt;) $(&gt;)
100}
101</pre>
102<p>
103
104
105
106
107</p>
108<p>Now, we're ready to tie it all together. Put all the code
109  above in file <code class="filename">verbatim.jam</code>, add <code class="computeroutput">import verbatim ;</code> 
110  to <code class="filename">project-root.jam</code>, and it's possible to write
111  the following in Jamfile:</p>
112<pre class="programlisting">
113exe codegen : codegen.cpp class_template.verbatim usage.verbatim ;
114</pre>
115<p>
116The verbatim files will be automatically converted into C++
117and linked it.
118  </p>
119<p>In the subsequent sections, we will extend this example, and review
120        all the mechanisms in detail. The complete code is available in <code class="filename">example/customization</code>
121        directory.
122      </p>
123</div>
124<div class="section" lang="en">
125<div class="titlepage"><div><div><h3 class="title">
126<a name="bbv2.extending.targets"></a>Target types</h3></div></div></div>
127<div class="toc"><dl><dt><span class="section"><a href="extender.html#bbv2.extending.scanners">Scanners</a></span></dt></dl></div>
128<p>The first thing we did in the <a href="extender.html#bbv2.extender.intro" title="Introduction">intruduction</a> was declaring a
129      new target type:
130</p>
131<pre class="programlisting">
132import type ;
133type.register VERBATIM : verbatim ;
134</pre>
135<p>
136        The type is the most important property of a target. Boost.Build can
137        automatically generate necessary build actions only because you
138        specify the desired type (using the different main target rules), and
139        because Boost.Build can guess the type of sources from their
140        extensions.       
141      </p>
142<p>The first two parameters for the <code class="computeroutput">type.register</code> rule
143        are the name of new type and the list of extensions associated with
144        it. A file with an extension from the list will have the given target
145        type. In the case where a target of the declared type is generated
146        from other sources, the first specified extension will be used.
147      </p>
148<p>Sometimes you want to change the suffix used for generated targets
149      depending on build properties, such as toolset. For example, some compiler
150      uses extension <code class="literal">elf</code> for executable files. You can use the
151      <code class="computeroutput">type.set-generated-target-suffix</code> rule:
152</p>
153<pre class="programlisting">
154type.set-generated-target-suffix EXE : &lt;toolset&gt;elf : elf ;
155</pre>
156<p>
157    </p>
158<p>A new target type can be inherited from an existing one.
159</p>
160<pre class="programlisting">
161type.register PLUGIN : : SHARED_LIB ;
162</pre>
163<p>
164      The above code defines a new type derived from
165      <code class="computeroutput">SHARED_LIB</code>. Initially, the new type inherits all the
166      properties of the base type - in particular generators and suffix.
167      Typically, you'll change the new type in some way. For example, using
168      <code class="computeroutput">type.set-generated-target-suffix</code> you can set the suffix for
169      the new type. Or you can write special a generator for the new type. For
170      example, it can generate additional metainformation for the plugin.
171      In either way, the <code class="computeroutput">PLUGIN</code> type can be used whenever
172      <code class="computeroutput">SHARED_LIB</code> can. For example, you can directly link plugins
173      to an application.
174    </p>
175<p>A type can be defined as "main", in which case Boost.Build will
176      automatically declare a main target rule for building targets of that
177      type. More details can be found <a href="extender.html#bbv2.extending.rules.main-type">later</a>.
178    </p>
179<div class="section" lang="en">
180<div class="titlepage"><div><div><h4 class="title">
181<a name="bbv2.extending.scanners"></a>Scanners</h4></div></div></div>
182<p>
183          Sometimes, a file can refer to other files via some include
184          mechanism. To make Boost.Build track dependencies to the included
185          files, you need to provide a scanner. The primary limitation is that
186          only one scanner can be assigned to a target type.
187        </p>
188<p>First, we need to declare a new class for the scanner:
189</p>
190<pre class="programlisting">
191class verbatim-scanner : common-scanner
192{
193    rule pattern ( )
194    {
195        return "//###include[ ]*\"([^\"]*)\"" ;
196    }
197}
198</pre>
199<p>         
200          All the complex logic is in the <code class="computeroutput">common-scanner</code>
201          class, and you only need to override the method that returns
202          the regular expression to be used for scanning. The
203          parentheses in the regular expression indicate which part
204          of the string is the name of the included file.  Only the
205          first parenthesized group in the regular expression will be
206          recognized; if you can't express everything you want that
207          way, you can return multiple regular expressions, each of
208          which contains a parenthesized group to be matched.
209        </p>
210<p>After that, we need to register our scanner class:
211</p>
212<pre class="programlisting">
213scanner.register verbatim-scanner : include ;
214</pre>
215<p>
216            The value of the second parameter, in this case
217            <code class="computeroutput">include</code>, specifies the properties that contain the list
218            of paths that should be searched for the included files.
219         </p>
220<p>Finally, we assign the new scanner to the <code class="computeroutput">VERBATIM</code>
221        target type:
222</p>
223<pre class="programlisting">
224type.set-scanner VERBATIM : verbatim-scanner ;
225</pre>
226<p>
227          That's enough for scanning include dependencies.
228        </p>
229</div>
230</div>
231<div class="section" lang="en">
232<div class="titlepage"><div><div><h3 class="title">
233<a name="bbv2.extending.tools"></a>Tools and generators</h3></div></div></div>
234<p>
235        This section will describe how Boost.Build can be extended to support
236        new tools.
237      </p>
238<p>For each additional tool, a Boost.Build object called generator
239        must be created. That object has specific types of targets that it
240        accepts and produces. Using that information, Boost.Build is able
241        to automatically invoke the generator. For example, if you declare a
242        generator that takes a target of the type <code class="literal">D</code> and
243        produces a target of the type <code class="literal">OBJ</code>, when placing a
244        file with extention <code class="literal">.d</code> in a list of sources will
245        cause Boost.Build to invoke your generator, and then to link the
246        resulting object file into an application. (Of course, this requires
247        that you specify that the <code class="literal">.d</code> extension corresponds
248        to the <code class="literal">D</code> type.)
249      </p>
250<p>Each generator should be an instance of a class derived from the
251        <code class="computeroutput">generator</code> class. In the simplest case, you don't need to
252        create a derived class, but simply create an instance of the
253        <code class="computeroutput">generator</code> class. Let's review the example we've seen in the
254        <a href="extender.html#bbv2.extender.intro" title="Introduction">introduction</a>.
255       
256</p>
257<pre class="programlisting">
258import generators ;
259generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
260actions inline-file
261{
262    "./inline-file.py" $(&lt;) $(&gt;)
263}
264</pre>
265<p>
266      </p>
267<p>We declare a standard generator, specifying its id, the source type
268        and the target type. When invoked, the generator will create a target
269        of type <code class="literal">CPP</code> with a source target of
270        type <code class="literal">VERBATIM</code> as the only source. But what command
271        will be used to actually generate the file? In bjam, actions are
272        specified using named "actions" blocks and the name of the action
273        block should be specified when creating targets. By convention,
274        generators use the same name of the action block as their own id. So,
275        in above example, the "inline-file" actions block will be used to
276        convert the source into the target.
277      </p>
278<p>
279        There are two primary kinds of generators: standard and composing,
280        which are registered with the
281        <code class="computeroutput">generators.register-standard</code> and the
282        <code class="computeroutput">generators.register-composing</code> rules, respectively. For
283        example:
284</p>
285<pre class="programlisting">
286generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
287generators.register-composing mex.mex : CPP LIB : MEX ;
288</pre>
289<p>
290        Standard generators take a <span class="emphasis"><em>single</em></span> source of type
291        <code class="computeroutput">VERBATIM</code> and produces a result. The second generator
292        takes any number of sources, which can have either the
293        <code class="computeroutput">CPP</code> or the <code class="computeroutput">LIB</code> type. Composing generators
294        are typically used for generating top-level target type. For example,
295        the first generator invoked when building an <code class="computeroutput">exe</code> target
296        is a composing generator corresponding to the proper linker.
297      </p>
298<p>You should also know about two specific functions for registering
299        generators: <code class="computeroutput">generators.register-c-compiler</code> and
300        <code class="computeroutput">generators.register-linker</code>. The first sets up header
301        dependecy scanning for C files, and the seconds handles various
302        complexities like searched libraries. For that reason, you should always
303        use those functions when adding support for compilers and linkers.
304      </p>
305<p>(Need a note about UNIX)</p>
306<h4>
307<a name="id2124421"></a>Custom generator classes</h4>
308<p>The standard generators allows you to specify source and target
309        types, an action, and a set of flags. If you need anything more complex,
310       
311        you need to create a new generator class with your own logic. Then,
312        you have to create an instance of that class and register it. Here's
313        an example how you can create your own generator class:
314</p>
315<pre class="programlisting">
316class custom-generator : generator
317{
318    rule __init__ ( * : * )
319    {
320        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
321    }
322
323}
324
325generators.register
326  [ new custom-generator verbatim.inline-file : VERBATIM : CPP ] ;
327</pre>
328<p>
329        This generator will work exactly like the
330        <code class="computeroutput">verbatim.inline-file</code> generator we've defined above, but
331        it's possible to customize the behaviour by overriding methods of the
332        <code class="computeroutput">generator</code> class.
333      </p>
334<p>There are two methods of interest. The <code class="computeroutput">run</code> method is
335        responsible for the overall process - it takes a number of source targets,
336        converts them to the right types, and creates the result. The
337        <code class="computeroutput">generated-targets</code> method is called when all sources are
338        converted to the right types to actually create the result.
339      </p>
340<p>The <code class="computeroutput">generated-target</code> 
341      method can be overridden
342      when you want to add additional properties to the generated
343      targets or use additional sources. For a real-life example,
344      suppose you have a program analysis tool that should be given a
345      name of executable and the list of all sources. Naturally, you
346      don't want to list all source files manually. Here's how the
347      <code class="computeroutput">generated-targets</code> method can find the list of
348      sources automatically:
349</p>
350<pre class="programlisting">
351class itrace-generator : generator {
352....
353    rule generated-targets ( sources + : property-set : project name ? )
354    {
355        local leaves ;
356        local temp = [ virtual-target.traverse $(sources[1]) : : include-sources ] ;
357        for local t in $(temp)
358        {
359            if ! [ $(t).action ]
360            {
361                leaves += $(t) ;
362            }
363        }
364        return [ generator.generated-targets $(sources) $(leafs)
365          : $(property-set) : $(project) $(name) ] ;
366    }
367}
368generators.register [ new itrace-generator nm.itrace : EXE : ITRACE ] ;
369</pre>
370<p>
371        The <code class="computeroutput">generated-targets</code> method will be called with a single
372        source target of type <code class="literal">EXE</code>. The call to
373        <code class="computeroutput">virtual-target.traverse</code> will return all targets the
374        executable depends on, and we further find files that are not
375        produced from anything.
376        The found targets are added to the sources.
377      </p>
378<p>The <code class="computeroutput">run</code> method can be overriden to completely
379        customize the way the generator works. In particular, the conversion of
380        sources to the desired types can be completely customized. Here's
381        another real example. Tests for the Boost Python library usually
382        consist of two parts: a Python program and a C++ file. The C++ file is
383        compiled to Python extension that is loaded by the Python
384        program. But in the likely case that both files have the same name,
385        the created Python extension must be renamed. Otherwise, the Python
386        program will import itself, not the extension. Here's how it can be
387        done:
388</p>
389<pre class="programlisting">
390rule run ( project name ? : property-set : sources * )
391{       
392    local python ;
393    for local s in $(sources)
394    {
395        if [ $(s).type ] = PY
396        {
397            python = $(s) ;
398        }
399    }
400   
401    local libs ;
402    for local s in $(sources)
403    {
404        if [ type.is-derived [ $(s).type ] LIB ]
405        {
406            libs += $(s) ;
407        }
408    }
409   
410    local new-sources ;
411    for local s in $(sources)
412    {
413        if [ type.is-derived [ $(s).type ] CPP ]
414        {
415            local name = [ $(s).name ] ;    # get the target's basename
416            if $(name) = [ $(python).name ]
417            {
418                name = $(name)_ext ;        # rename the target
419            }                               
420            new-sources += [ generators.construct $(project) $(name) :
421              PYTHON_EXTENSION : $(property-set) : $(s) $(libs) ] ;
422        }
423    }
424       
425    result = [ construct-result $(python) $(new-sources) : $(project) $(name)
426                 : $(property-set) ] ;       
427}   
428</pre>
429<p>       
430       
431
432        First, we separate all source into python files, libraries and C++
433        sources. For each C++ source we create a separate Python extension by
434        calling <code class="computeroutput">generators.construct</code> and passing the C++ source
435        and the libraries. At this point, we also change the extension's name,
436        if necessary.       
437      </p>
438</div>
439<div class="section" lang="en">
440<div class="titlepage"><div><div><h3 class="title">
441<a name="bbv2.extending.features"></a>Features</h3></div></div></div>
442<p>
443        Often, we need to control the options passed the invoked tools. This
444        is done with features. Consider an example:
445</p>
446<pre class="programlisting">
447# Declare a new free feature
448import feature : feature ;
449feature verbatim-options : : free ;
450
451# Cause the value of the 'verbatim-options' feature to be
452# available as 'OPTIONS' variable inside verbatim.inline-file
453import toolset : flags ;
454flags verbatim.inline-file OPTIONS &lt;verbatim-options&gt; ;
455
456# Use the "OPTIONS" variable
457actions inline-file
458{
459    "./inline-file.py" $(OPTIONS) $(&lt;) $(&gt;)
460}
461</pre>
462<p>
463        We first define a new feature. Then, the <code class="computeroutput">flags</code> invocation
464        says that whenever verbatin.inline-file action is run, the value of
465        the <code class="computeroutput">verbatim-options</code> feature will be added to the
466        <code class="computeroutput">OPTIONS</code> variable, and can be used inside the action body.
467        You'd need to consult online help (--help) to find all the features of
468        the <code class="computeroutput">toolset.flags</code> rule.
469       
470      </p>
471<p>
472      Although you can define any set of features and interpret their values
473      in any way, Boost.Build suggests the following coding standard for
474      designing features.
475    </p>
476<p>Most features should have a fixed set of values that is portable
477      (tool neutral) across the class of tools they are designed to work
478      with. The user does not have to adjust the values for a exact tool.  For
479      example, <code class="computeroutput">&lt;optimization&gt;speed</code> has the same meaning for
480      all C++ compilers and the user does not have to worry about the exact
481      options passed to the compiler's command line.
482    </p>
483<p>
484      Besides such portable features there are special 'raw' features that
485      allow the user to pass any value to the command line parameters for a
486      particular tool, if so desired. For example, the
487      <code class="computeroutput">&lt;cxxflags&gt;</code> feature allows you to pass any command line
488      options to a C++ compiler. The <code class="computeroutput">&lt;include&gt;</code> feature
489      allows you to pass any string preceded by <code class="computeroutput">-I</code> and the interpretation
490      is tool-specific.  (See <a href="faq.html#bbv2.faq.external" title="Can I get output of external program as a variable in a Jamfile?
491    ">the section called &#8220;Can I get output of external program as a variable in a Jamfile?
492    &#8221;</a> for an example of very smart usage of that
493      feature).  Of course one should always strive to use portable
494      features, but these are still be provided as a backdoor just to make
495      sure Boost.Build does not take away any control from the user.
496    </p>
497<p>
498      Using portable features is a good idea because:
499      </p>
500<div class="itemizedlist"><ul type="disc">
501<li><p>When a portable feature is given a fixed set of
502          values, you can build your project with two different
503          settings of the feature and Boost.Build will automatically
504          use two different directories for generated files.
505          Boost.Build does not try to separate targets built with
506          different raw options.
507           
508          </p></li>
509<li><p>Unlike with &#8220;raw&#8221; features, you don't need to use
510          specific command-line flags in your Jamfile, and it will be
511          more likely to work with other tools.
512          </p></li>
513</ul></div>
514<p>
515    </p>
516<h4>
517<a name="id2124699"></a>Steps for adding a feauture</h4>
518<p>Adding a feature requires three steps:
519
520        </p>
521<div class="orderedlist"><ol type="1">
522<li>
523<p>Declaring a feature. For that, the "feature.feature"
524              rule is used. You have to decide on the set of <a href="reference.html#bbv2.reference.features.attributes" title="Feature Attributes">feature
525              attributes</a>:
526
527              </p>
528<div class="itemizedlist"><ul type="disc">
529<li><p>if a feature has several values and
530                    significantly affects the build, make it &#8220;propagated,&#8221; so that the
531                    whole project is built with the same value by
532                    default</p></li>
533<li><p>if a feature does not have a fixed
534                list of values, it must be &#8220;free.&#8221;  For example, the
535                <code class="computeroutput">include</code> feature is a free
536                feature.</p></li>
537<li><p>if a feature is used to refer to a
538                path relative to the Jamfile, it must be a &#8220;path&#8221;
539                feature.  <code class="computeroutput">include</code> is also a path
540                feature.</p></li>
541<li><p>if feature is used to refer to some target, it
542                must be a &#8220;dependency&#8221; feature. </p></li>
543</ul></div>
544<p>
545              </p>
546</li>
547<li><p>Representing the feature value in a
548          target-specific variable. Build actions are command
549          templates modified by Boost.Jam variable expansions.  The
550          <code class="computeroutput">toolset.flags</code> rule sets a target-specific
551          variable to the value of a feature.</p></li>
552<li><p>Using the variable. The variable set in step 2 can
553              be used in a build action to form command parameters or
554              files.</p></li>
555</ol></div>
556<p>
557      </p>
558<h4>
559<a name="id2124805"></a>Another example</h4>
560<p>Here's another example.
561        Let's see how we can make a feature that refers to a target. For example,
562        when linking dynamic libraries on windows, one sometimes needs to specify
563        "DEF file", telling what functions should be exported. It would be nice to
564        use this file like this:
565</p>
566<pre class="programlisting">
567        lib a : a.cpp : &lt;def-file&gt;a.def ;
568</pre>
569<p>
570
571        Actually, this feature is already supported, but anyway...
572       
573      </p>
574<div class="orderedlist"><ol type="1">
575<li>
576<p>Since the feature refers to a target, it must be "dependency".
577</p>
578<pre class="programlisting">
579feature def-file : : free dependency ;
580</pre>
581<p>
582            </p>
583</li>
584<li>
585<p>One of the toolsets that cares about
586       
587        DEF files is msvc. The following line should be added to it.
588       
589
590</p>
591<pre class="programlisting">
592flags msvc.link DEF_FILE &lt;def-file&gt; ;
593</pre>
594<p>
595           
596            </p>
597</li>
598<li>
599<p>Since the DEF_FILE variable is not used by the
600msvc.link action,
601
602we need to modify it to be:
603
604</p>
605<pre class="programlisting">
606actions link bind DEF_FILE
607{
608    $(.LD) .... /DEF:$(DEF_FILE) ....
609}
610</pre>
611<p>
612            </p>
613<p> Note the <code class="computeroutput">bind DEF_FILE</code> part. It tells
614          bjam to translate the internal target name in
615          <code class="varname">DEF_FILE</code> to a corresponding filename in
616          the <code class="computeroutput">link</code> action.  Without it the expansion of
617          <code class="computeroutput">$(DEF_FILE)</code> would be a strange symbol that is
618          not likely to make sense for the linker.
619          </p>
620<p>
621            We are almost done, but we should stop for a small workaround. Add the following
622            code to msvc.jam
623
624</p>
625<pre class="programlisting">
626rule link
627{
628    DEPENDS $(&lt;) : [ on $(&lt;) return $(DEF_FILE) ] ;
629}
630</pre>
631<p>
632
633
634            This is needed to accomodate some bug in bjam, which hopefully
635            will be fixed one day.
636           
637</p>
638</li>
639</ol></div>
640<h4>
641<a name="id2124917"></a>Variants and composite features.</h4>
642<p>Sometimes you want to create a shortcut for some set of
643        features. For example, <code class="computeroutput">release</code> is a value of
644        <code class="computeroutput">&lt;variant&gt;</code> and is a shortcut for a set of features.
645      </p>
646<p>It is possible to define your own build variants. For example:
647</p>
648<pre class="programlisting">
649variant crazy : &lt;optimization&gt;speed &lt;inlining&gt;off
650                &lt;debug-symbols&gt;on &lt;profiling&gt;on ;
651</pre>
652<p>
653        will define a new variant with the specified set of properties. You
654        can also extend an existing variant:
655</p>
656<pre class="programlisting">
657variant super_release : release : &lt;define&gt;USE_ASM ;
658</pre>
659<p>
660        In this case, <code class="computeroutput">super_release</code> will expand to all properties
661        specified by <code class="computeroutput">release</code>, and the additional one you've specified.
662      </p>
663<p>You are not restricted to using the <code class="computeroutput">variant</code> feature
664      only.
665     
666      Here's example that defines a brand new feature:
667</p>
668<pre class="programlisting">
669feature parallelism : mpi fake none : composite link-incompatible ;
670feature.compose &lt;parallelism&gt;mpi : &lt;library&gt;/mpi//mpi/&lt;parallelism&gt;none ;
671feature.compose &lt;parallelism&gt;fake : &lt;library&gt;/mpi//fake/&lt;parallelism&gt;none ;
672</pre>
673<p>
674
675        This will allow you to specify the value of feature
676        <code class="computeroutput">parallelism</code>, which will expand to link to the necessary
677        library.
678      </p>
679</div>
680<div class="section" lang="en">
681<div class="titlepage"><div><div><h3 class="title">
682<a name="bbv2.extending.rules"></a>Main target rules</h3></div></div></div>
683<p>
684      A main target rule (e.g &#8220;<code class="computeroutput">exe</code>&#8221;
685      Or &#8220;<code class="computeroutput">lib</code>&#8221;) creates a top-level target. It's quite likely that you'll want to declare your own and
686      there are two ways to do that.
687     
688    </p>
689<p><a name="bbv2.extending.rules.main-type"></a>The first way applies when
690
691      your target rule should just produce a target of specific type. In that case, a
692      rule is already defined for you! When you define a new type, Boost.Build
693      automatically defines a corresponding rule. The name of the rule is
694      obtained from the name of the type, by downcasing all letters and
695      replacing underscores with dashes.
696     
697      For example, if you create a module
698      <code class="filename">obfuscate.jam</code> containing:
699
700</p>
701<pre class="programlisting">
702import type ;
703type.register OBFUSCATED_CPP  : ocpp ;
704
705import generators ;
706generators.register-standard obfuscate.file : CPP : OBFUSCATED_CPP ;
707</pre>
708<p>
709      and import that module, you'll be able to use the rule "obfuscated-cpp"
710      in Jamfiles, which will convert source to the OBFUSCATED_CPP type.
711    </p>
712<p>The second way is to write a wrapper rule that calls
713      any of the existing rules. For example, suppose you have only one library per
714      directory and want all cpp files in the directory to be compiled into that library. You
715      can achieve this effect with:
716</p>
717<pre class="programlisting">
718lib codegen : [ glob *.cpp ] ;
719</pre>
720<p>
721      but if you want to make it even simpler, you could add the following
722      definition to the <code class="filename">project-root.jam</code> file:
723</p>
724<pre class="programlisting">
725rule glib ( name : extra-sources * : requirements * )
726{
727    lib $(name) : [ glob *.cpp ] $(extra-sources) : $(requirements) ;
728}
729</pre>
730<p>
731which would allow you to reduce the Jamfile to
732</p>
733<pre class="programlisting">
734glib codegen ;
735</pre>
736<p>
737    </p>
738<p>
739      Note that because you can associate a custom generator with a target
740      type, the logic of building can be rather compiler.
741     
742      For example, the
743      <code class="computeroutput">boostbook</code> module declares a target type
744      <code class="computeroutput">BOOSTBOOK_MAIN</code> and a custom generator for that
745      type. You can use that as example if your main target rule is
746      non-trivial.
747    </p>
748</div>
749<div class="section" lang="en">
750<div class="titlepage"><div><div><h3 class="title">
751<a name="bbv2.extending.toolset_modules"></a>Toolset modules</h3></div></div></div>
752<p>If your extensions will be used only on one project, they can be
753      placed in a separate <code class="filename">.jam</code> file that will be
754      imported by your <code class="filename">project-root.jam</code>. If the
755      extensions will be used on many projects, users will thank you for
756      a finishing touch.
757    </p>
758<p>The <code class="computeroutput">using</code> rule provides a standard mechanism
759    for loading and configuring extensions.  To make it work, your module
760   
761    should provide an <code class="computeroutput">init</code> rule. The rule will be called
762    with the same parameters that were passed to the
763    <code class="computeroutput">using</code> rule. The set of allowed parameters is
764    determined by you. For example, you can allow the user to specify
765    paths, tool versions, and other options.
766   
767    </p>
768<p>Here are some guidelines that help to make Boost.Build more
769      consistent:
770      </p>
771<div class="itemizedlist"><ul type="disc">
772<li><p>The <code class="computeroutput">init</code> rule should never fail. Even if
773          the user provided an incorrect path, you should emit a warning and go
774          on. Configuration may be shared between different machines, and
775          wrong values on one machine can be OK on another.
776         
777          </p></li>
778<li>
779<p>Prefer specifying the command to be executed
780        to specifying the tool's installation path. First of all, this
781        gives more control: it's possible to specify
782</p>
783<pre class="programlisting">
784/usr/bin/g++-snapshot
785time g++
786
787</pre>
788<p>
789            as the command. Second, while some tools have a logical
790            "installation root", it's better if the user doesn't have to remember whether
791            a specific tool requires a full command or a path.
792           
793          </p>
794</li>
795<li>
796<p>Check for multiple initialization. A user can try to
797            initialize the module several times. You need to check for this
798            and decide what to do. Typically, unless you support several
799            versions of a tool, duplicate initialization is a user error.
800           
801            If the
802            tool's version can be specified during initialization, make sure the
803            version is either always specified, or never specified (in which
804            case the tool is initialied only once). For example, if you allow:
805</p>
806<pre class="programlisting">
807using yfc ;
808using yfc : 3.3 ;
809using yfc : 3.4 ;
810</pre>
811<p>
812            Then it's not clear if the first initialization corresponds to
813            version 3.3 of the tool, version 3.4 of the tool, or some other
814            version. This can lead to building twice with the same version.
815           
816            </p>
817</li>
818<li>
819<p>If possible, <code class="computeroutput">init</code> must be callable
820          with no parameters. In which case, it should try to autodetect all
821          the necessary information, for example, by looking for a tool in
822          <code class="envar">PATH</code> or in common installation locations. Often this
823          is possible and allows the user to simply write:
824</p>
825<pre class="programlisting">
826using yfc ;
827</pre>
828<p>
829          </p>
830</li>
831<li><p>Consider using facilities in the
832          <code class="computeroutput">tools/common</code> module. You can take a look at how
833          <code class="computeroutput">tools/gcc.jam</code> uses that module in the <code class="computeroutput">init</code> rule.
834          </p></li>
835</ul></div>
836<p>
837    </p>
838</div>
839</div>
840<table width="100%"><tr>
841<td align="left"></td>
842<td align="right"><small></small></td>
843</tr></table>
844<hr>
845<div class="spirit-nav">
846<a accesskey="p" href="tasks.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../bbv2.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../images/next.png" alt="Next"></a>
847</div>
848</body>
849</html>
Note: See TracBrowser for help on using the repository browser.