Introduction

SCons is an advanced software construction tool for programming languages like C++, C, Java and many more. SCons and all project configurations and build process scripts are implemented in Python which allows a high level of flexibility and extensibility. The central configuration file SConstruct (e.g. the SCons equivalent of a Makefile) is used to define the dependency tree. Tracking dependencies is after all the key task of SCons, since the build process visits each node in the constructed tree and decides if the node has to be built/rebuilt according to its dependencies.

Around SCons we have built a bunch of tools called SConsider. SConsider provides a hierarchical package system. A package is specified in a file called [package].sconsider (which is actually a SConscript in SCons terms) which contains a number of targets defined in a Python dict. Such a target can depend on/require another target without knowing where and how this target is defined (even if the other target is defined later in the same package). Starting from SConstruct's directory SConsider first searches recursively for *.sconsider files. Because executing a SConscript takes some time SConsider loads only packages which are involved in the build.

A basic package definition

Let's hop in and examine a first simple package definition (CoastFoundation.sconsider):

import SConsider                                                     # 1
Import('*')                                                          # 2

buildSettings = {
    packagename : {                                                  # 3
        'linkDependencies' : ['loki', 'boost'],                      # 4
        'sourceFiles'      : SConsider.listFiles(['*.cpp']),         # 5
        'targetType'       : 'LibraryShared',                        # 6
        'appendUnique'     : { 'CPPDEFINES' : ['FOUNDATION_IMPL'] }, # 7
        'public' : {
            'includes'     : SConsider.listFiles(['*.h','*.hpp']),   # 8
    }
}

SConsider.createTargets(packagename, buildSettings)                  # 9
  1. Imports the SConsider module and allows to use its functions.
  2. The calling script exports some variables which are now imported, e.g. packagename which was deduced from the filename.
  3. The main target has to be named after the package by definition.
  4. We link to the main targets (shared libraries) of the packages loki and boost.
  5. List of source files, collected using a glob pattern. Since we are in a SConscript all file and directory names are relative to its directory.
  6. With those sources we build a shared library.
  7. Add defines to the build environment.
  8. Public headers which are copied to the release directory.
  9. Create the targets using the definition noted above (dependencies are loaded recursively), calling this function is a must.

See Package definition for all possible options.

A first simple build

Now we are going to build what we've defined:

$ scons -u -j 4 CoastFoundation
  • -u: With this option it doesn't matter from which directory SCons is called because it searches upwards until it finds a SConstruct file.
  • -j 4: Allow 4 jobs at once, SCons determines using the dependency tree which build artifacts can be parallelized.
  • CoastFoundation: The build target, starting from this target the dependency tree is constructed.

Side note: CoastFoundation is a package which is actually something what SCons calls an Alias and all the package's targets are added to that Alias as dependency.

See Command line options for more options

Global aliases

Defined are the following aliases which are available as build targets:
  • tests
  • all
  • includes

Using the tests alias for example it's possible to build and run all tests:

$ scons -u -j 4 tests --run-force

Decide what to build

The most straight forward way to build something is defining a target (or an alias) explicitly:

$ scons CoastFoundation

The options -u, --up, --search-up, -U and -D force SCons to climb up the directory tree and search for the SConstruct file to execute. To make sense in SConsider's context these options had to be slightly adjusted. Call scons --help to see the native definitions.

-u, --up, --search-up

Load all sconsider files in or below current working directory and load sconsider files outside the current working directory if they are a dependency. If no target is given explicitly: Build all loaded packages (because our default targets are aliases which are not part of the filesystem and are therefore built anyway).

-U

Load sconsider files in the current working directory and load sconsider files outside the current working directory if they are a dependency. If no target is given explicitly: Build all loaded packages (because our default targets are aliases which are not part of the filesystem and are therefore built anyway). In contrast to -u, --up, --search-up packages defined below the current directory are not loaded automatically.

-D

Load all sconsider files. If no target is given explicitly: Build all packages (all default targets) no matter where they are defined and no matter in which directory SCons was launched.

Other stuff