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