Chapter 10. Controlling a Build From the Command Line

SCons provides a number of ways for you as the writer of the SConscript files to give you (and your users) the ability to control the build execution. The arguments that can be specified on the command line are broken down into three types:

Options

Command-line options always begin with one or two - (hyphen) characters. SCons provides ways for you to examine and set options values from within your SConscript files, as well as the ability to define your own custom options. See Section 10.1, “Command-Line Options”, below.

Variables

Any command-line argument containing an = (equal sign) is considered a variable setting with the form variable=value. SCons provides direct access to all of the command-line variable settings, the ability to apply command-line variable settings to construction environments, and functions for configuring specific types of variables (Boolean values, path names, etc.) with automatic validation of the specified values. See Section 10.2, “Command-Line variable=value Build Variables”, below.

Targets

Any command-line argument that is not an option or a variable setting (does not begin with a hyphen and does not contain an equal sign) is considered a target that the 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. An SCons command-line option always begins with one or two hyphen (-) characters.

10.1.1. Not Having to Specify Command-Line Options Each Time: the SCONSFLAGS Environment Variable

You may find yourself using the same 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

SCons provides the GetOption function to get the values set by the various command-line options.

One use case for GetOption is to check whether or not the -h or --help option has been specified. Normally, SCons does not print its help text until after it has read all of the SConscript files, because it's possible that help text has been added by some subsidiary SConscript file deep in the source tree hierarchy. 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 the GetOption function to load the subsidiary SConscript files only if the -h or --help option has not been specified like this:

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

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. 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 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 from 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, regardless of whether or not the NUM_CPU environment variable is set:

% 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 is not currently supported for options added with AddOption.

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

String for GetOption and SetOptionCommand-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_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

SCons also allows you to define your own command-line options with the AddOption function. The AddOption function takes the same arguments as the add_option method from the standard Python library module optparse. [2]

Once you add a custom command-line option with the AddOption function, the value of the option (if any) is immediately available using the standard 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 is not currently supported for options added with AddOption.

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

Option-arguments separated from long options by whitespace, rather than by an =, cannot be correctly resolved by SCons. While --input=ARG is clearly opt followed by arg, for --input ARG it is not possible to tell without instructions whether ARG is an argument belonging to the input option or a positional argument. SCons treats positional arguments as either command-line build options or command-line targets 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. Since AddOption calls, which provide the processing instructions to resolve any ambiguity, happen in an SConscript, SCons does not know in time for options added this way, and unexpected things happen, such as option-arguments assigned as targets and/or exceptions due to missing option-arguments.

As a result, this usage style should be avoided when invoking scons. For single-argument options, use the --input=ARG form on the command line. For multiple-argument options (nargs greater than one), set nargs to one in AddOption calls 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.