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