7.3. Controlling the Execution Environment for Issued Commands
Prev | Chapter 7. Environments | Next

## 7.3. Controlling the Execution Environment for Issued Commands

When SCons builds a target file, it does not execute the commands with the external environment that you used to execute SCons. Instead, it builds an execution environment from the values stored in the `$ENV` construction variable and uses that for executing commands.

The most important ramification of this behavior is that the `PATH` environment variable, which controls where the operating system will look for commands and utilities, will almost certainly not be the same as in the external environment from which you called SCons. This means that SCons might not necessarily find all of the tools that you can successfully execute from the command line.

The default value of the `PATH` environment variable on a POSIX system is `/usr/local/bin:/opt/bin:/bin:/usr/bin:/snap/bin`. The default value of the `PATH` environment variable on a Windows system comes from the Windows registry value for the command interpreter. If you want to execute any commands--compilers, linkers, etc.--that are not in these default locations, you need to set the `PATH` value in the `$ENV` dictionary in your construction environment.

The simplest way to do this is to initialize explicitly the value when you create the construction environment; this is one way to do that:

    path = ['/usr/local/bin', '/bin', '/usr/bin']
    env = Environment(ENV={'PATH': path})

Assigning a dictionary to the `$ENV` construction variable in this way completely resets the execution environment, so that the only variable that will be set when external commands are executed will be the `PATH` value. If you want to use the rest of the values in `$ENV` and only set the value of `PATH`, you can assign a value only to that variable:

    env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin']

Note that SCons does allow you to define the directories in the `PATH` in a string with paths separated by the pathname separator character for your system (`':'` on POSIX systems, `';'` on Windows).

    env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'

But doing so makes your `SConscript` file less portable, since it will be correct only for the system type that matches the separator. You can use the Python `os.pathsep` for for greater portability - don't worry too much if this Python syntax doesn't make sense since there are other ways available:

    import os
    env['ENV']['PATH'] = os.pathsep.join(['/usr/local/bin', '/bin', '/usr/bin'])

### 7.3.1. Propagating `PATH` From the External Environment

You may want to propagate the external environment `PATH` to the execution environment for commands. You do this by initializing the `PATH` variable with the `PATH` value from the `os.environ` dictionary, which is Python's way of letting you get at the external environment:

    import os
    env = Environment(ENV={'PATH': os.environ['PATH']})

Alternatively, you may find it easier to just propagate the entire external environment to the execution environment for commands. This is simpler to code than explicity selecting the `PATH` value:

    import os
    env = Environment(ENV=os.environ.copy())

Either of these will guarantee that SCons will be able to execute any command that you can execute from the command line. The drawback is that the build can behave differently if it's run by people with different `PATH` values in their environment--for example, if both the `/bin` and `/usr/local/bin` directories have different cc commands, then which one will be used to compile programs will depend on which directory is listed first in the user's `PATH` variable.

### 7.3.2. Adding to `PATH` Values in the Execution Environment

One of the most common requirements for manipulating a variable in the execution environment is to add one or more custom directories to a path search variable like `PATH` on Linux or POSIX systems, or `%PATH%` on Windows, so that a locally-installed compiler or other utility can be found when SCons tries to execute it to update a target. SCons provides `env.PrependENVPath` and `env.AppendENVPath` functions to make adding things to execution variables convenient. You call these functions by specifying the variable to which you want the value added, and then value itself. So to add some `/usr/local` directories to the `$PATH` and `$LIB` variables, you might:

    env = Environment(ENV=os.environ.copy())
    env.PrependENVPath('PATH', '/usr/local/bin')
    env.AppendENVPath('LIB', '/usr/local/lib')

Note that the added values are strings, and if you want to add multiple directories to a variable like `$PATH`, you must include the path separator character in the string (`:` on Linux or POSIX, `;` on Windows, or use `os.pathsep` for portability).

Prev | Up | Next
7.2. Construction Environments | Home | 7.4. Using the toolpath for external Tools