Package definition

A package is defined in a file called [package].sconsider. The packagename is extracted from the filename and exported when calling the file as SConscript. Renaming a package therefore is nothing more than renaming the file. To refer to the package's name inside the .sconsider file use Import('*') and you get the variable packagename.

Available options

targetType

'targetType': 'ProgramTest',

Usually the name of a builder but actually any callable which is defined in the target's build environment. We defined some wrapper functions around SCons's default builders to ease the most used build configurations.

LibraryShared (wrapper around SharedLibrary), builds a shared library with sourceFiles and installs it in lib/[platform], uses lazylinking
Program default builder, creates an executable with sourceFiles
ProgramTest or ProgramApp if usedTarget slot is defined, its target will be looked up in the registry, otherwise an executable will be built using sourceFiles. Finally a shell script gets wrapped around the target to execute it. The target installs in [tests or apps]/[package]/bin/[platform] the script in [tests or apps]/[package]/scripts/[platform]
PrecompiledLibraryInstallBuilder uses sourceFiles and libVersion to find a precompiled library and installs it in lib/[platform]
PrecompiledBinaryInstallBuilder uses sourceFiles to find a precompiled binary and installs it in bin/[platform]
PrecompiledBinary same as PrecompiledBinaryInstallBuilder but installs in globals/[package]/bin/[platform]
others values which are not names of a callable cause no builds but all other tasks like copyFiles are still done

linkDependencies, requires

'linkDependencies': ['CoastWDBase', 'testfwWDBase'],
'requires'        : [SConsider.generateFulltargetname(packagename,'TestLib')],

To create dependencies between targets:

linkDependencies targets (e.g. libraries, or 'include-only' targets) to which the current target needs to link (if a linkable target exists), injects defines from public.appendUnique and include directories from public.includeSubdir
requires targets which need to be built before the current target is created

If linkDependencies refers to a package the main target package.package is linked but the dependency is still created to the package alias.

Side note: SCons differs between Requires() and Depends(). While Requires() just guarantees that a the required target is built before the current target, Depends() additionally causes a rebuild of the current target if the depended target changed. There is no such difference between linkDependencies and requires, both use Depends() in the background.

usedTarget

'targetType': 'ProgramApp',  # or 'ProgramTest',
'usedTarget': 'coastd.coastd',

Is used to copy an executable target to the current package's install directory and create a script to execute it. Therefore the current package's configuration is used to execute the target.

sourceFiles

'sourceFiles': SConsider.listFiles(['*.cpp']),

A list of files to use as source for the chosen builder (see targetType). Usually collected with a glob expression.
Use listFiles() as shown in the example, findFiles() is deprecated.

copyFiles

'copyFiles': [
    (SConsider.findFiles(['.'], ['.any', '.txt', '.tst']), S_IRUSR | S_IRGRP | S_IROTH, {'FQDN': 'somehost.example.com'} ),
    (SConsider.findFiles(['config'], ['.sh']), S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR),
],

Copies a list of files to the packages's install directory. copyFiles expects a list of tuples. While the first tuple entry is the file list the second entry is the bitset the files are chmoded to.

An optional third entry in a tuple is used to search and replace values in the copied files. Key/value pairs in the supplied dict are used to search the file for ##key## and replace all matches with the corresponding value. Using a callable as value allows dynamic replacements:

searchReplace = {
    'DIREXTENDBASEDIR': lambda env: os.path.join(env['BASEOUTDIR'].Dir(env['RELTARGETDIR']).abspath, 'makedirextendtest', 'test'),
    'TMPDIR': lambda env: 'c:/temp' if str(env['PLATFORM']) == 'cygwin' else '/tmp',
    'ROOTFS': lambda env: 'c:/' if str(env['PLATFORM']) == 'cygwin' else '/',
}

To allow location dependent configuration, a file is overridden if a corresponding file was found in envconfigdir/[package]/... (see command line option --env-cfg).

lazylinking

'lazylinking': True,

Is used exclusively with 'targetType': 'LibraryShared'. False tells the linker to only succeed if all external references can be resolved.

appendUnique, public.appendUnique

'appendUnique': { 'CPPDEFINES' : ['ACTIONS_IMPL'] },
'public': {
    'appendUnique': {
        'LIBS' : ['pthread'],
        'CPPDEFINES' : ['_POSIX_THREADS'],
    }
}
appendUnique Adds defines uniqueified to the build environment of the current target
public.appendUnique Adds defines uniqueified to the build environment of depending targets

includeSubdir, public.includeSubdir, public.includes

'includeSubdir': '',
'public' : {
    'includes'     : SConsider.findFiles(['include'], ['.h']),
    'includeSubdir': 'include',
}

There are two entries (includeSubdir, public.includeSubdir) to define the include directories where SCons's source scanner searches for header files. The default value is the current package's directory (emtpy string) for both.

includeSubdir private header files, valid in the current target's build environment only
public.includeSubdir public header files, path will be exported to the build environment of depending targets
public.includes a list of files which will be copied to includes/[package] (uses public.stripSubdir), added to global includes alias
public.stripSubdir strips public.includeSubdir when copying include files (default: True)

Example: The file [packagedir]/include/example.h is copied to includes/[package]/example.h if stripSubdirs: True or otherwise to includes/[package]/include/example.h

runConfig

def setUp(target, source, env):
    pass

def tearDown(target, source, env):
    pass

...

'runConfig': {
    'type'    : 'test'
    'setUp'   : setUp,
    'tearDown': tearDown,
},

SConsider allows to run an executable target right after the build (see command line option --run):

runConfig.type possible values: 'run', 'test', the latter one runs runConfig.setUp and runConfig.tearDown before resp. after the target
runConfig.setUp a Python callable which will be executed before the target
runConfig.tearDown a Python callable which will be executed after the target

runConfig.type defaults to 'test' if used with targetType: 'ProgramTest' or 'run' if used with targetType: 'ProgramApp'. A runConfig with type: 'test' is added to the global tests alias.

To skip the execution of a target (probably because of errors in setting up a backend):
  • raise SConsider.SkipTest(message)
Or to fail the build:
  • return a value which doesn't evaluate to False
  • raise SCons.Errors.BuildError(errstr, node, executor, action)

public.execEnv

'public': {
    'execEnv' : {
        'LANG'  : 'C',
    },
},

A target is always executed in its execution environment. public.execEnv is used to inject environment variables into depending targets' execution environments.

Example:

buildSettings = {
    packagename : {
        ...
        'requires'         : [packagename + '.config'],
    }
    'config': {
        'copyFiles'        : [(SConsider.listFiles(['config/*','charsets/*','locales/*'], recursive=True), S_IRUSR|S_IRGRP|S_IROTH)],
        'appendUnique'     : { 'RELTARGETDIR' : os.path.join('globals', packagename) },
        'public': {
            'execEnv' : {
                'SYBASE': os.path.join('$BASEOUTDIR', '$RELTARGETDIR'),
                'LANG'  : 'C',
            },
        },
},

This is a stripped down version of sybase.sconsider. Another target will most likely have a linkDependency to 'sybase.sybase', which requires 'sybase.config'. The target 'sybase.config' copies a list of files (Sybase needs config, charsets and locals to be around) recursively to globals/[package]. Usually RELTARGETDIR is set correctly according to the chosen targetType but because we have no targetType (nothing needs to be built) we have to set RELTARGETDIR manually. We then inject the location of Sybase's directories as variable 'SYBASE' to the depending target's execution environment (the build environment variables $BASEOUTDIR and $RELTARGETDIR will be resolved through SCons in the context of the target they are defined in).