Chapter 10. Controlling a Build From the Command Line
Prev |  | Next

## Chapter 10. Controlling a Build From the Command Line

Software builds are rarely completely static, so SCons gives you a number of ways to help control build execution via instructions on the command line. The arguments that can be specified on the command line are broken down into three types:

Options

  Command-line arguments that begin with a `-` (hyphen) characters are called options. SCons provides ways for you to examine and act on options and their values, as well as the ability to define custom options for your project. See Section 10.1, “Command-Line Options”, below.

Variables

  Command-line arguments containing an `=` (equal sign) character are called build variables (or just variables). SCons provides direct access to all of the build variable settings from the command line, as well as a higher-level interface that lets you define known build variables, including defining types, default values, help text, and automatic validation, as well as applying those to a construction environment. See Section 10.2, “Command-Line `variable`=`value` Build Variables”, below.

Targets

  Command-line arguments that are neither options nor build variables (that is, do not begin with a hyphen and do not contain an equal sign) are considered targets that you are telling SCons to build. SCons provides access to the list of specified targets, as well as ways to set the default list of targets from within the `SConscript` files. See Section 10.3, “Command-Line Targets”, below.

## 10.1. Command-Line Options

SCons has many command-line options that control its behavior. A command-line option always begins with one or two hyphen (`-`) characters. The SCons manual page contains the description of the current options (see https://scons.org/doc/production/HTML/scons-man.html).

### 10.1.1. How To Avoid Typing Command-Line Options Each Time: the `SCONSFLAGS` Environment Variable

You may find yourself using certain command-line options every time you run SCons. For example, you might find it saves time to specify `-j 2` to have SCons run up to two build commands in parallel. To avoid having to type `-j 2` by hand every time, you can set the external environment variable `SCONSFLAGS` to a string containing `-j 2`, as well as any other command-line options that you want SCons to always use. `SCONSFLAGS` is an exception to the usual rule that SCons itself avoids looking at environment variables from the shell you are running.

If, for example, you are using a POSIX shell such as bash or zsh and you always want SCons to use the `-Q` option, you can set the `SCONSFLAGS` environment as follows:

    % scons
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
        ... [build output] ...
    scons: done building targets.
    % export SCONSFLAGS="-Q"
    % scons
        ... [build output] ...

For csh-style shells on POSIX systems you can set the `SCONSFLAGS` environment variable as follows:

    $ setenv SCONSFLAGS "-Q"

For the Windows command shell (cmd) you can set the `SCONSFLAGS` environment variable as follows:

    C:\Users\foo> set SCONSFLAGS="-Q"

To set `SCONSFLAGS` more permanently you can add the setting to the shell's startup file on POSIX systems, and on Windows you can use the `System Properties` control panel applet to select `Environment Variables` and set it there.

### 10.1.2. Getting Values Set by Command-Line Options: the `GetOption` Function

The `GetOption` function lets you query the values set by the various command-line options.

One use case for `GetOption` is to check the operation mode in order to bypass some steps, for example, checking whether the `-h` (or `--help`) option was given. Normally, SCons does not print its help text until after it has read all of the SConscript files, since any SConscript can make additions to the help text. Of course, reading all of the SConscript files takes extra time. If you know that your configuration does not define any additional help text in subsidiary SConscript files, you can speed up displaying the command-line help by using a `GetOption` query as a guard for whether to load the subsidiary SConscript files:

    if not GetOption('help'):
        SConscript('src/SConscript', export='env')

The same technique can be used to special-case the clean (`GetOption('clean')`) and no-execute (`GetOption('no_exec')`) modes.

In general, the string that you pass to the `GetOption` function to fetch the value of a command-line option setting is the same as the "most common" long option name (beginning with two hyphen characters), although there are some exceptions. The list of SCons command-line options and the `GetOption` strings for fetching them, are available in the Section 10.1.4, “Strings for Getting or Setting Values of SCons Command-Line Options” section, below.

`GetOption` can be used to retrieve the values of options defined by calls to `AddOption`. A `GetOption` call must appear after the `AddOption` call for that option (unlike the defining of build targets, this is a case where "order matters" in SCons). If the `AddOption` call supplied a `dest` keyword argument, a string with that name is what to pass as the argument to `GetOption`, otherwise it is a (possibly modified) version of the first long option name - see `AddOption`.

### 10.1.3. Setting Values of Command-Line Options: the `SetOption` Function

You can also set the values of certain (but not all) SCons command-line options from within the `SConscript` files by using the `SetOption` function. The strings that you use to set the values of SCons command-line options are available in the Section 10.1.4, “Strings for Getting or Setting Values of SCons Command-Line Options” section, below.

One use of the `SetOption` function is to specify a value for the `-j` or `--jobs` option, so that you get the improved performance of a parallel build without having to specify the option by hand. A complicating factor is that a good value for the `-j` option is somewhat system-dependent. One rough guideline is that the more processors your system has, the higher you want to set the `-j` value, in order to take advantage of the number of CPUs.

For example, suppose the administrators of your development systems have standardized on setting a `NUM_CPU` environment variable to the number of processors on each system. A little bit of Python code to access the environment variable and the `SetOption` function provides the right level of flexibility:

    import os

    num_cpu = int(os.environ.get('NUM_CPU', 2))
    SetOption('num_jobs', num_cpu)
    print("running with -j %s" % GetOption('num_jobs'))

The above snippet of code sets the value of the `--jobs` option to the value specified in the `NUM_CPU` environment variable. (This is one of the exception cases where the string is spelled differently from the command-line option. The string for fetching or setting the `--jobs` value is `num_jobs` for historical reasons.) The code in this example prints the `num_jobs` value for illustrative purposes. It uses a default value of `2` to provide some minimal parallelism even on single-processor systems:

    % scons -Q
    running with -j 2
    scons: `.' is up to date.

But if the `NUM_CPU` environment variable is set, then use that for the default number of jobs:

    % export NUM_CPU="4"
    % scons -Q
    running with -j 4
    scons: `.' is up to date.

But any explicit `-j` or `--jobs` value you specify on the command line is used first, whether the `NUM_CPU` environment variable is set or not:

    % scons -Q -j 7
    running with -j 7
    scons: `.' is up to date.
    % export NUM_CPU="4"
    % scons -Q -j 3
    running with -j 3
    scons: `.' is up to date.

### 10.1.4. Strings for Getting or Setting Values of SCons Command-Line Options

The strings that you can pass to the `GetOption` and `SetOption` functions usually correspond to the first long-form option name (that is, name beginning with two hyphen characters: `--`), after replacing any remaining hyphen characters with underscores.

`SetOption` works for options added with `AddOption`, but only if they were created with `settable=True` in the call to `AddOption` (only available in SCons 4.8.0 and later).

The full list of strings and the variables they correspond to is as follows:

String for `GetOption` and `SetOption` | Command-Line Option(s)
--- | ---
`cache_debug` | `--cache-debug`
`cache_disable` | `--cache-disable`
`cache_force` | `--cache-force`
`cache_show` | `--cache-show`
`clean` | `-c`, `--clean`, `--remove`
`config` | `--config`
`directory` | `-C`, `--directory`
`diskcheck` | `--diskcheck`
`duplicate` | `--duplicate`
`file` | `-f`, `--file`, `--makefile` , `--sconstruct`
`help` | `-h`, `--help`
`ignore_errors` | `--ignore-errors`
`implicit_cache` | `--implicit-cache`
`implicit_deps_changed` | `--implicit-deps-changed`
`implicit_deps_unchanged` | `--implicit-deps-unchanged`
`interactive` | `--interact`, `--interactive`
`keep_going` | `-k`, `--keep-going`
`max_drift` | `--max-drift`
`no_exec` | `-n`, `--no-exec`, `--just-print`, `--dry-run`, `--recon`
`no_progress` | `-Q`
`no_site_dir` | `--no-site-dir`
`num_jobs` | `-j`, `--jobs`
`profile_file` | `--profile`
`question` | `-q`, `--question`
`random` | `--random`
`repository` | `-Y`, `--repository`, `--srcdir`
`silent` | `-s`, `--silent`, `--quiet`
`site_dir` | `--site-dir`
`stack_size` | `--stack-size`
`taskmastertrace_file` | `--taskmastertrace`
`warn` | `--warn` `--warning`

### 10.1.5. Adding Custom Command-Line Options: the `AddOption` Function

You can also define your own command-line options for the project with the `AddOption` function. The `AddOption` function takes the same arguments as the `add_option` method from the Python standard library module `optparse` [2] (see https://docs.python.org/3/library/optparse.html).

Once you add a custom command-line option with the `AddOption` function, the value of the option (if any) is immediately available using the `GetOption` function. The argument to `GetOption` must be the name of the variable which holds the option. If the `dest` keyword argument to `AddOption` is specified, the value is the variable name. given. If not given, it is the name (without the leading hyphens) of the first long option name given to `AddOption` after replacing any remaining hyphen characters with underscores, since hyphens are not legal in Python identifier names.

`SetOption` works for options added with `AddOption`, but only if they were created with `settable=True` in the call to `AddOption` (only available in SCons 4.8.0 and later).

One useful example of using this functionality is to provide a `--prefix` to help describe where to install files:

    AddOption(
        '--prefix',
        dest='prefix',
        type='string',
        nargs=1,
        action='store',
        metavar='DIR',
        help='installation prefix',
    )

    env = Environment(PREFIX=GetOption('prefix'))

    installed_foo = env.Install('$PREFIX/usr/bin', 'foo.in')
    Default(installed_foo)

The above code uses the `GetOption` function to set the `$PREFIX` construction variable to a value you specify with a command-line option of `--prefix`. Because `$PREFIX` expands to a null string if it's not initialized, running SCons without the option of `--prefix` installs the file in the `/usr/bin/` directory:

    % scons -Q -n
    Install file: "foo.in" as "/usr/bin/foo.in"

But specifying `--prefix=/tmp/install` on the command line causes the file to be installed in the `/tmp/install/usr/bin/` directory:

    % scons -Q -n --prefix=/tmp/install
    Install file: "foo.in" as "/tmp/install/usr/bin/foo.in"

### Note

The `optparse` parser which SCons uses allows option-arguments to follow their options after either an `=` or space separator, however the latter form does not work well in SCons for added options and should be avoided. SCons does not place an ordering constraint on the types of command-line arguments, so while `--input=ARG` is unambiguous, for `--input ARG` it is not possible to tell without instructions whether `ARG` is an argument belonging to the `input` option or a standalone word. SCons considers words on the command line which do not begin with hyphen as either command-line build variables or command-line targets, both of which are made available for use in an `SConscript` (see the immediately following sections for details). Thus, they must be collected before `SConscript` processing takes place. `AddOption` calls do provide the necessary instructions to resolve the ambiguity, but as they appear in `SConscript` files, SCons does not have the information early enough, and unexpected things may happen, such as option-arguments appearing in the list of targets, and processing exceptions due to missing option-arguments.

As a result, this usage style should be avoided when invoking scons. For single-argument options, tell your users to use the `--input=ARG` form on the command line. For multiple-argument options (`nargs` value greater than one), set `nargs` to one in the `AddOption` call and either: combine the option-arguments into one word with a separator, and parse the result in your own code (see the built-in `--debug` option, which allows specifying multiple arguments as a single comma-separated word, for an example of such usage); or allow the option to be specified multiple times by setting `action='append'`. Both methods can be supported at the same time.

[2] The `AddOption` function is, in fact, implemented using a subclass of `optparse.OptionParser`.

Prev |  | Next
9.4. Printing Detailed Build Status: the `GetBuildFailures` Function | Home | 10.2. Command-Line `variable`=`value` Build Variables