Search code examples
bjamboost-build

Registering command line arguments with help system: Boost-Build


We're using Boost-Build to build our software. To help facilitate this, we've written a library of rules and actions. Boost-Build allows passing in command line arguments and will pass along any argument prefixed with --. Currently, to get a hold of the arguments and check for flags we're doing something like:

import modules ;

local args = [ modules.peek : ARGV ] ;
# or like this
if "--my-flag" in [ modules.peek : ARGV ]

Which works to get and check values. However, developers that use Boost-Build and our jam libraries have no idea that these flags are available and would like to see some help on these flags whenever they run either bjam -h or bjam --help. I see that BB has a help module, but I don't see any way to register arguments with the help system.

Is there a way to register command line flags, complete with short documentation, that the help system will pick up?


Solution

  • In response to my own question, I have added the very feature that I was asking about: https://github.com/boostorg/build/pull/23

    It uses the existing options plugin system. Whenever you want to create a new command-line option create a new module within the options directory. Within that new module, create a variable that holds a value or is empty. Above the variable create a comment. The comment is used as the command-line documentation and the value (if given) is used to describe the default value of that variable.

    Create a process rule within the new module and register your option with the system. This allows importing the option module and getting the value from a single source. This requires that each variable name is prefixed with the name of the module.

    Create a variable named .option-description. Its value is the section separator and its comment is the description of the section.

    For example:

    # within options/cool.jam
    
    # These are the options for the Cool option plugin
    .option-description = Cool Options
    
    # This enables option1
    .option.--cool-option1 ?= ;
    
    # This enables something cool
    .option.--cool-default-option ?= "my default value" ;
    
    rule process (
        command # The option.
        : values * # The values, starting after the "=".
        )
    {
        option.set $(command) : $(values) ;
    }
    

    When running bjam with the --help-options flag, it will output all modules that follow the above patterns within the options directory. It will have an output similar to the following:

    Boost.Build Usage:
    
      b2 [ options... ] targets...
    
      * -a; Build all targets, even if they are current.
      * -fx; Read 'x' as the Jamfile for building instead of searching for the
        Boost.Build system.
      * -jx; Run up to 'x' commands concurrently.
      * -n; Do not execute build commands. Instead print out the commands as they
        would be executed if building.
      * -ox; Output the used build commands to file 'x'.
      * -q; Quit as soon as a build failure is encountered. Without this option
        Boost.Jam will continue building as many targets as it can.
      * -sx=y; Sets a Jam variable 'x' to the value 'y', overriding any value that
        variable would have from the environment.
      * -tx; Rebuild the target 'x', even if it is up-to-date.
      * -v; Display the version of b2.
      * --x; Any option not explicitly handled by Boost.Build remains available to
        build scripts using the 'ARGV' variable.
      * --abbreviate-paths; Use abbreviated paths for targets.
      * --hash; Shorten target paths by using an MD5 hash.
      * -dn; Enables output of diagnostic messages. The debug level 'n' and all
        below it are enabled by this option.
      * -d+n; Enables output of diagnostic messages. Only the output for debug
        level 'n' is enabled.
    
    Debug Levels:
    
      Each debug level shows a different set of information. Usually with higher
      levels producing more verbose information. The following levels are supported:
    
      * 0; Turn off all diagnostic output. Only errors are reported.
      * 1; Show the actions taken for building targets, as they are executed.
      * 2; Show quiet actions and display all action text, as they are executed.
      * 3; Show dependency analysis, and target/source timestamps/paths.
      * 4; Show arguments of shell invocations.
      * 5; Show rule invocations and variable expansions.
      * 6; Show directory/header file/archive scans, and attempts at binding to
        targets.
      * 7; Show variable settings.
      * 8; Show variable fetches, variable expansions, and evaluation of 'if'
        expressions.
      * 9; Show variable manipulation, scanner tokens, and memory usage.
      * 10; Show execution times for rules.
      * 11; Show parsing progress of Jamfiles.
      * 12; Show graph for target dependencies.
      * 13; Show changes in target status (fate).
    
    Cool Options:
        These are the options for the Cool option plugin
    
        * --cool-option1: This enables option1. Default is disabled.
        * --cool-default-option: This enables something cool. "my default value".
    

    Later on in your own Jam code, you can then get a hold of values from the registered options by doing:

    import option ;
    
    option1 = option.get '--cool-option1' ;
    if $(option1) {
        # do_something ;
    }