Sharing Environments (and Other Variables) Between SConscript Files

SCons User Guide 0.98.0
Prev | Chapter 14. Hierarchical Builds | Next

# 14.5. Sharing Environments (and Other Variables) Between `SConscript` Files

In the previous example, each of the subsidiary `SConscript` files created its own construction environment by calling `Environment` separately. This obviously works fine, but if each program must be built with the same construction variables, it's cumbersome and error-prone to initialize separate construction environments in the same way over and over in each subsidiary `SConscript` file.

SCons supports the ability to export variables from a parent `SConscript` file to its subsidiary `SConscript` files, which allows you to share common initialized values throughout your build hierarchy.

## 14.5.1. Exporting Variables

There are two ways to export a variable, such as a construction environment, from an `SConscript` file, so that it may be used by other `SConscript` files. First, you can call the `Export` function with a list of variables, or a string of white-space separated variable names. Each call to `Export` adds one or more variables to a global list of variables that are available for import by other `SConscript` files.

            env = Environment()
            Export('env')

You may export more than one variable name at a time:

            env = Environment()
            debug = ARGUMENTS['debug']
            Export('env', 'debug')

Because white space is not legal in Python variable names, the `Export` function will even automatically split a string into separate names for you:

            Export('env debug')

Second, you can specify a list of variables to export as a second argument to the `SConscript` function call:

            SConscript('src/SConscript', 'env')

Or as the `exports` keyword argument:

            SConscript('src/SConscript', exports='env')

These calls export the specified variables to only the listed `SConscript` files. You may, however, specify more than one `SConscript` file in a list:

            SConscript(['src1/SConscript',
                        'src2/SConscript'], exports='env')

This is functionally equivalent to calling the `SConscript` function multiple times with the same `exports` argument, one per `SConscript` file.

## 14.5.2. Importing Variables

Once a variable has been exported from a calling `SConscript` file, it may be used in other `SConscript` files by calling the `Import` function:

            Import('env')
            env.Program('prog', ['prog.c'])

The `Import` call makes the `env` construction environment available to the `SConscript` file, after which the variable can be used to build programs, libraries, etc.

Like the `Export` function, the `Import` function can be used with multiple variable names:

            Import('env', 'debug')
            env = env.Clone(DEBUG = debug)
            env.Program('prog', ['prog.c'])

And the `Import` function will similarly split a string along white-space into separate variable names:

            Import('env debug')
            env = env.Clone(DEBUG = debug)
            env.Program('prog', ['prog.c'])

Lastly, as a special case, you may import all of the variables that have been exported by supplying an asterisk to the `Import` function:

            Import('*')
            env = env.Clone(DEBUG = debug)
            env.Program('prog', ['prog.c'])

If you're dealing with a lot of `SConscript` files, this can be a lot simpler than keeping arbitrary lists of imported variables in each file.

## 14.5.3. Returning Values From an `SConscript` File

Sometimes, you would like to be able to use information from a subsidiary `SConscript` file in some way. For example, suppose that you want to create one library from source files scattered throughout a number of subsidiary `SConscript` files. You can do this by using the `Return` function to return values from the subsidiary `SConscript` files to the calling file.

If, for example, we have two subdirectories foo and bar that should each contribute a source file to a Library, what we'd like to be able to do is collect the object files from the subsidiary `SConscript` calls like this:

              env = Environment()
              Export('env')
              objs = []
              for subdir in ['foo', 'bar']:
                  o = SConscript('%s/SConscript' % subdir)
                  objs.append(o)
              env.Library('prog', objs)

We can do this by using the `Return` function in the `foo/SConscript` file like this:

              Import('env')
              obj = env.Object('foo.c')
              Return('obj')

(The corresponding `bar/SConscript` file should be pretty obvious.) Then when we run SCons, the object files from the subsidiary subdirectories are all correctly archived in the desired library:

            % scons -Q
            cc -o bar/bar.o -c bar/bar.c
            cc -o foo/foo.o -c foo/foo.c
            ar rc libprog.a foo/foo.o bar/bar.o
            ranlib libprog.a

Prev | Home | Next
Absolute Path Names | Up | Separating Source and Build Directories