From 140d836e9cd54fb67b969fd82ef7ed19ba574d40 Mon Sep 17 00:00:00 2001 From: Luca Falavigna Date: Sat, 26 Apr 2014 15:11:58 +0200 Subject: Imported Upstream version 2.3.1 --- doc/man/scons.xml | 7101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 7101 insertions(+) create mode 100644 doc/man/scons.xml (limited to 'doc/man/scons.xml') diff --git a/doc/man/scons.xml b/doc/man/scons.xml new file mode 100644 index 0000000..d9bd74d --- /dev/null +++ b/doc/man/scons.xml @@ -0,0 +1,7101 @@ + + + +%version; + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + SCons &buildversion; + MAN page + + + Steven + Knight + + + Steven Knight + + 2004, 2005, 2006, 2007, 2008, 2009, 2010 + + + 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Steven Knight + + + version &buildversion; + + + + + + SCons &buildversion; + MAN page + + + + +SCONS +1 +March 2014 + + +scons +a software construction tool + + + + + scons + options + name=val + targets + + + + +DESCRIPTION +The +scons +utility builds software (or other files) by determining which +component pieces must be rebuilt and executing the necessary commands to +rebuild them. + +By default, +scons +searches for a file named +SConstruct, +Sconstruct, +or +sconstruct +(in that order) in the current directory and reads its +configuration from the first file found. +An alternate file name may be +specified via the + +option. + +The +SConstruct +file can specify subsidiary +configuration files using the +SConscript() +function. +By convention, +these subsidiary files are named +SConscript, +although any name may be used. +(Because of this naming convention, +the term "SConscript files" +is sometimes used to refer +generically to all +scons +configuration files, +regardless of actual file name.) + +The configuration files +specify the target files to be built, and +(optionally) the rules to build those targets. Reasonable default +rules exist for building common software components (executable +programs, object files, libraries), so that for most software +projects, only the target and input files need be specified. + +Before reading the +SConstruct +file, +scons +looks for a directory named +site_scons +in various system directories (see below) and the directory containing the +SConstruct +file; for each of those dirs which exists, +site_scons +is prepended to sys.path, +the file +site_scons/site_init.py, +is evaluated if it exists, +and the directory +site_scons/site_tools +is prepended to the default toolpath if it exists. +See the + +and + +options for more details. + +scons +reads and executes the SConscript files as Python scripts, +so you may use normal Python scripting capabilities +(such as flow control, data manipulation, and imported Python libraries) +to handle complicated build situations. +scons, +however, reads and executes all of the SConscript files +before +it begins building any targets. +To make this obvious, +scons +prints the following messages about what it is doing: + + +$ scons foo.out +scons: Reading SConscript files ... +scons: done reading SConscript files. +scons: Building targets ... +cp foo.in foo.out +scons: done building targets. +$ + + +The status messages +(everything except the line that reads "cp foo.in foo.out") +may be suppressed using the + +option. + +scons +does not automatically propagate +the external environment used to execute +scons +to the commands used to build target files. +This is so that builds will be guaranteed +repeatable regardless of the environment +variables set at the time +scons +is invoked. +This also means that if the compiler or other commands +that you want to use to build your target files +are not in standard system locations, +scons +will not find them unless +you explicitly set the PATH +to include those locations. +Whenever you create an +scons +construction environment, +you can propagate the value of PATH +from your external environment as follows: + + +import os +env = Environment(ENV = {'PATH' : os.environ['PATH']}) + + +Similarly, if the commands use external environment variables +like $PATH, $HOME, $JAVA_HOME, $LANG, $SHELL, $TERM, etc., +these variables can also be explicitly propagated: + + +import os +env = Environment(ENV = {'PATH' : os.environ['PATH'], + 'HOME' : os.environ['HOME']}) + + +Or you may explicitly propagate the invoking user's +complete external environment: + + +import os +env = Environment(ENV = os.environ) + + +This comes at the expense of making your build +dependent on the user's environment being set correctly, +but it may be more convenient for many configurations. + +scons +can scan known input files automatically for dependency +information (for example, #include statements +in C or C++ files) and will rebuild dependent files appropriately +whenever any "included" input file changes. +scons +supports the +ability to define new scanners for unknown input file types. + +scons +knows how to fetch files automatically from +SCCS or RCS subdirectories +using SCCS, RCS or BitKeeper. + +scons +is normally executed in a top-level directory containing a +SConstruct +file, optionally specifying +as command-line arguments +the target file or files to be built. + +By default, the command + + +scons + + +will build all target files in or below the current directory. +Explicit default targets +(to be built when no targets are specified on the command line) +may be defined the SConscript file(s) +using the +Default() +function, described below. + +Even when +Default() +targets are specified in the SConscript file(s), +all target files in or below the current directory +may be built by explicitly specifying +the current directory (.) +as a command-line target: + + +scons . + + +Building all target files, +including any files outside of the current directory, +may be specified by supplying a command-line target +of the root directory (on POSIX systems): + + +scons / + + +or the path name(s) of the volume(s) in which all the targets +should be built (on Windows systems): + + +scons C:\ D:\ + + +To build only specific targets, +supply them as command-line arguments: + + +scons foo bar + + +in which case only the specified targets will be built +(along with any derived files on which they depend). + +Specifying "cleanup" targets in SConscript files is not usually necessary. +The + +flag removes all files +necessary to build the specified target: + + +scons -c . + + +to remove all target files, or: + + +scons -c build export + + +to remove target files under build and export. +Additional files or directories to remove can be specified using the +Clean() +function. +Conversely, targets that would normally be removed by the + +invocation +can be prevented from being removed by using the +NoClean() +function. + +A subset of a hierarchical tree may be built by +remaining at the top-level directory (where the +SConstruct +file lives) and specifying the subdirectory as the target to be +built: + + +scons src/subdir + + +or by changing directory and invoking scons with the + +option, which traverses up the directory +hierarchy until it finds the +SConstruct +file, and then builds +targets relatively to the current subdirectory: + + +cd src/subdir +scons -u . + + +scons +supports building multiple targets in parallel via a + +option that takes, as its argument, the number +of simultaneous tasks that may be spawned: + + +scons -j 4 + + +builds four targets in parallel, for example. + +scons +can maintain a cache of target (derived) files that can +be shared between multiple builds. When caching is enabled in a +SConscript file, any target files built by +scons +will be copied +to the cache. If an up-to-date target file is found in the cache, it +will be retrieved from the cache instead of being rebuilt locally. +Caching behavior may be disabled and controlled in other ways by the +, +, +, +and + +command-line options. The + +option is useful to prevent multiple builds +from trying to update the cache simultaneously. + +Values of variables to be passed to the SConscript file(s) +may be specified on the command line: + + +scons debug=1 . + + +These variables are available in SConscript files +through the ARGUMENTS dictionary, +and can be used in the SConscript file(s) to modify +the build in any way: + + +if ARGUMENTS.get('debug', 0): + env = Environment(CCFLAGS = '-g') +else: + env = Environment() + + +The command-line variable arguments are also available +in the ARGLIST list, +indexed by their order on the command line. +This allows you to process them in order rather than by name, +if necessary. +ARGLIST[0] returns a tuple +containing (argname, argvalue). +A Python exception is thrown if you +try to access a list member that +does not exist. + +scons +requires Python version 2.4 or later. +There should be no other dependencies or requirements to run +scons. + + + + +By default, +scons +knows how to search for available programming tools +on various systems. +On Windows systems, +scons +searches in order for the +Microsoft Visual C++ tools, +the MinGW tool chain, +the Intel compiler tools, +and the PharLap ETS compiler. +On OS/2 systems, +scons +searches in order for the +OS/2 compiler, +the GCC tool chain, +and the Microsoft Visual C++ tools, +On SGI IRIX, IBM AIX, Hewlett Packard HP-UX, and Sun Solaris systems, +scons +searches for the native compiler tools +(MIPSpro, Visual Age, aCC, and Forte tools respectively) +and the GCC tool chain. +On all other platforms, +including POSIX (Linux and UNIX) platforms, +scons +searches in order +for the GCC tool chain, +the Microsoft Visual C++ tools, +and the Intel compiler tools. +You may, of course, override these default values +by appropriate configuration of +Environment construction variables. + + + +OPTIONS +In general, +scons +supports the same command-line options as GNU +make, +and many of those supported by +cons. + + + + -b + +Ignored for compatibility with non-GNU versions of +make. + + + + + -c, --clean, --remove + +Clean up by removing all target files for which a construction +command is specified. +Also remove any files or directories associated to the construction command +using the +Clean() +function. +Will not remove any targets specified by the +NoClean() +function. + + + + + --cache-debug=file + +Print debug information about the +CacheDir() +derived-file caching +to the specified +file. +If +file +is +- +(a hyphen), +the debug information are printed to the standard output. +The printed messages describe what signature file names are +being looked for in, retrieved from, or written to the +CacheDir() +directory tree. + + + + + --cache-disable, --no-cache + +Disable the derived-file caching specified by +CacheDir(). +scons +will neither retrieve files from the cache +nor copy files to the cache. + + + + + --cache-force, --cache-populate + +When using +CacheDir(), +populate a cache by copying any already-existing, up-to-date +derived files to the cache, +in addition to files built by this invocation. +This is useful to populate a new cache with +all the current derived files, +or to add to the cache any derived files +recently built with caching disabled via the + +option. + + + + + --cache-readonly + +Use the cache (if enabled) for reading, but do not not update the +cache with changed files. + + + + + + --cache-show + +When using +CacheDir() +and retrieving a derived file from the cache, +show the command +that would have been executed to build the file, +instead of the usual report, +"Retrieved `file' from cache." +This will produce consistent output for build logs, +regardless of whether a target +file was rebuilt or retrieved from the cache. + + + + + --config=mode + +This specifies how the +Configure +call should use or generate the +results of configuration tests. +The option should be specified from +among the following choices: + + + + + --config=auto + +scons will use its normal dependency mechanisms +to decide if a test must be rebuilt or not. +This saves time by not running the same configuration tests +every time you invoke scons, +but will overlook changes in system header files +or external commands (such as compilers) +if you don't specify those dependecies explicitly. +This is the default behavior. + + + + + --config=force + +If this option is specified, +all configuration tests will be re-run +regardless of whether the +cached results are out of date. +This can be used to explicitly +force the configuration tests to be updated +in response to an otherwise unconfigured change +in a system header file or compiler. + + + + + --config=cache + +If this option is specified, +no configuration tests will be rerun +and all results will be taken from cache. +Note that scons will still consider it an error +if --config=cache is specified +and a necessary test does not +yet have any results in the cache. + + + + + -C directory, --directory=directory + +Change to the specified +directory +before searching for the +SConstruct, +Sconstruct, +or +sconstruct +file, or doing anything +else. Multiple + +options are interpreted +relative to the previous one, and the right-most + +option wins. (This option is nearly +equivalent to +, +except that it will search for +SConstruct, +Sconstruct, +or +sconstruct +in the specified directory.) + + + + + + + + + + + -D + +Works exactly the same way as the + +option except for the way default targets are handled. +When this option is used and no targets are specified on the command line, +all default targets are built, whether or not they are below the current +directory. + + + + + --debug=type + +Debug the build process. +type[,type...] +specifies what type of debugging. Multiple types may be specified, +separated by commas. The following types are valid: + + + + + --debug=count + +Print how many objects are created +of the various classes used internally by SCons +before and after reading the SConscript files +and before and after building targets. +This is not supported when SCons is executed with the Python + +(optimized) option +or when the SCons modules +have been compiled with optimization +(that is, when executing from +*.pyo +files). + + + + + --debug=duplicate + +Print a line for each unlink/relink (or copy) of a variant file from +its source file. Includes debugging info for unlinking stale variant +files, as well as unlinking old targets before building them. + + + + + --debug=dtree + +A synonym for the newer + +option. +This will be deprecated in some future release +and ultimately removed. + + + + + --debug=explain + +Print an explanation of precisely why +scons +is deciding to (re-)build any targets. +(Note: this does not print anything +for targets that are +not +rebuilt.) + + + + + --debug=findlibs + +Instruct the scanner that searches for libraries +to print a message about each potential library +name it is searching for, +and about the actual libraries it finds. + + + + + --debug=includes + +Print the include tree after each top-level target is built. +This is generally used to find out what files are included by the sources +of a given derived file: + + +$ scons --debug=includes foo.o + + + + + + --debug=memoizer + +Prints a summary of hits and misses using the Memoizer, +an internal subsystem that counts +how often SCons uses cached values in memory +instead of recomputing them each time they're needed. + + + + + --debug=memory + +Prints how much memory SCons uses +before and after reading the SConscript files +and before and after building targets. + + + + + --debug=nomemoizer + +A deprecated option preserved for backwards compatibility. + + + + + --debug=objects + +Prints a list of the various objects +of the various classes used internally by SCons. + + + + + --debug=pdb + +Re-run SCons under the control of the +pdb +Python debugger. + + + + + --debug=prepare + +Print a line each time any target (internal or external) +is prepared for building. +scons +prints this for each target it considers, even if that +target is up to date (see also --debug=explain). +This can help debug problems with targets that aren't being +built; it shows whether +scons +is at least considering them or not. + + + + + --debug=presub + +Print the raw command line used to build each target +before the construction environment variables are substituted. +Also shows which targets are being built by this command. +Output looks something like this: + +$ scons --debug=presub +Building myprog.o with action(s): + $SHCC $SHCFLAGS $SHCCFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES +... + + + + + + --debug=stacktrace + +Prints an internal Python stack trace +when encountering an otherwise unexplained error. + + + + + --debug=stree + +A synonym for the newer + +option. +This will be deprecated in some future release +and ultimately removed. + + + + + --debug=time + +Prints various time profiling information: +the time spent executing each individual build command; +the total build time (time SCons ran from beginning to end); +the total time spent reading and executing SConscript files; +the total time spent SCons itself spend running +(that is, not counting reading and executing SConscript files); +and both the total time spent executing all build commands +and the elapsed wall-clock time spent executing those build commands. +(When +scons +is executed without the + +option, +the elapsed wall-clock time will typically +be slightly longer than the total time spent +executing all the build commands, +due to the SCons processing that takes place +in between executing each command. +When +scons +is executed +with +the + +option, +and your build configuration allows good parallelization, +the elapsed wall-clock time should +be significantly smaller than the +total time spent executing all the build commands, +since multiple build commands and +intervening SCons processing +should take place in parallel.) + + + + + --debug=tree + +A synonym for the newer + +option. +This will be deprecated in some future release +and ultimately removed. + + + + + --diskcheck=types + +Enable specific checks for +whether or not there is a file on disk +where the SCons configuration expects a directory +(or vice versa), +and whether or not RCS or SCCS sources exist +when searching for source and include files. +The +types +argument can be set to: +all, +to enable all checks explicitly +(the default behavior); +none, +to disable all such checks; +match, +to check that files and directories on disk +match SCons' expected configuration; +rcs, +to check for the existence of an RCS source +for any missing source or include files; +sccs, +to check for the existence of an SCCS source +for any missing source or include files. +Multiple checks can be specified separated by commas; +for example, + +would still check for SCCS and RCS sources, +but disable the check for on-disk matches of files and directories. +Disabling some or all of these checks +can provide a performance boost for large configurations, +or when the configuration will check for files and/or directories +across networked or shared file systems, +at the slight increased risk of an incorrect build +or of not handling errors gracefully +(if include files really should be +found in SCCS or RCS, for example, +or if a file really does exist +where the SCons configuration expects a directory). + + + + + --duplicate=ORDER + +There are three ways to duplicate files in a build tree: hard links, +soft (symbolic) links and copies. The default behaviour of SCons is to +prefer hard links to soft links to copies. You can specify different +behaviours with this option. +ORDER +must be one of +hard-soft-copy +(the default), +soft-hard-copy, +hard-copy, +soft-copy +or +copy. +SCons will attempt to duplicate files using +the mechanisms in the specified order. + + + + + + + + + + -f file, --file=file, --makefile=file, --sconstruct=file + +Use +file +as the initial SConscript file. +Multiple + +options may be specified, +in which case +scons +will read all of the specified files. + + + + + -h, --help + +Print a local help message for this build, if one is defined in +the SConscript file(s), plus a line that describes the + +option for command-line option help. If no local help message +is defined, prints the standard help message about command-line +options. Exits after displaying the appropriate message. + + + + + -H, --help-options + +Print the standard help message about command-line options and +exit. + + + + + -i, --ignore-errors + +Ignore all errors from commands executed to rebuild files. + + + + + -I directory, --include-dir=directory + +Specifies a +directory +to search for +imported Python modules. If several + +options +are used, the directories are searched in the order specified. + + + + + --implicit-cache + +Cache implicit dependencies. +This causes +scons +to use the implicit (scanned) dependencies +from the last time it was run +instead of scanning the files for implicit dependencies. +This can significantly speed up SCons, +but with the following limitations: + + + + +scons +will not detect changes to implicit dependency search paths +(e.g. +CPPPATH, LIBPATH) +that would ordinarily +cause different versions of same-named files to be used. + +scons +will miss changes in the implicit dependencies +in cases where a new implicit +dependency is added earlier in the implicit dependency search path +(e.g. +CPPPATH, LIBPATH) +than a current implicit dependency with the same name. + + + + --implicit-deps-changed + +Forces SCons to ignore the cached implicit dependencies. This causes the +implicit dependencies to be rescanned and recached. This implies +. + + + + + --implicit-deps-unchanged + +Force SCons to ignore changes in the implicit dependencies. +This causes cached implicit dependencies to always be used. +This implies +. + + + + + --interactive + +Starts SCons in interactive mode. +The SConscript files are read once and a +scons>>> +prompt is printed. +Targets may now be rebuilt by typing commands at interactive prompt +without having to re-read the SConscript files +and re-initialize the dependency graph from scratch. + +SCons interactive mode supports the following commands: + +
+ + + build[OPTIONS] [TARGETS] ... + +Builds the specified +TARGETS +(and their dependencies) +with the specified +SCons command-line +OPTIONS. +b +and +scons +are synonyms. + +The following SCons command-line options affect the +build +command: + + +--cache-debug=FILE +--cache-disable, --no-cache +--cache-force, --cache-populate +--cache-readonly +--cache-show +--debug=TYPE +-i, --ignore-errors +-j N, --jobs=N +-k, --keep-going +-n, --no-exec, --just-print, --dry-run, --recon +-Q +-s, --silent, --quiet +--taskmastertrace=FILE +--tree=OPTIONS + + + + + + +Any other SCons command-line options that are specified +do not cause errors +but have no effect on the +build +command +(mainly because they affect how the SConscript files are read, +which only happens once at the beginning of interactive mode). + + + + clean[OPTIONS] [TARGETS] ... + +Cleans the specified +TARGETS +(and their dependencies) +with the specified options. +c +is a synonym. +This command is itself a synonym for +build --clean + + + + + exit + +Exits SCons interactive mode. +You can also exit by terminating input +(CTRL+D on UNIX or Linux systems, +CTRL+Z on Windows systems). + + + + + help[COMMAND] + +Provides a help message about +the commands available in SCons interactive mode. +If +COMMAND +is specified, +h +and +? +are synonyms. + + + + + shell[COMMANDLINE] + +Executes the specified +COMMANDLINE +in a subshell. +If no +COMMANDLINE +is specified, +executes the interactive command interpreter +specified in the +SHELL +environment variable +(on UNIX and Linux systems) +or the +COMSPEC +environment variable +(on Windows systems). +sh +and +! +are synonyms. + + + + + version + +Prints SCons version information. + + + +
+ +
+
+
+ +An empty line repeats the last typed command. +Command-line editing can be used if the +readline +module is available. + + +$ scons --interactive +scons: Reading SConscript files ... +scons: done reading SConscript files. +scons>>> build -n prog +scons>>> exit + + + + + -j N, --jobs=N + +Specifies the number of jobs (commands) to run simultaneously. +If there is more than one + +option, the last one is effective. + + + + + + + + + + + + -k, --keep-going + +Continue as much as possible after an error. The target that +failed and those that depend on it will not be remade, but other +targets specified on the command line will still be processed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -m + +Ignored for compatibility with non-GNU versions of +make. + + + + + --max-drift=SECONDS + +Set the maximum expected drift in the modification time of files to +SECONDS. +This value determines how long a file must be unmodified +before its cached content signature +will be used instead of +calculating a new content signature (MD5 checksum) +of the file's contents. +The default value is 2 days, which means a file must have a +modification time of at least two days ago in order to have its +cached content signature used. +A negative value means to never cache the content +signature and to ignore the cached value if there already is one. A value +of 0 means to always use the cached signature, +no matter how old the file is. + + + + + --md5-chunksize=KILOBYTES + +Set the block size used to compute MD5 signatures to +KILOBYTES. +This value determines the size of the chunks which are read in at once when +computing MD5 signatures. Files below that size are fully stored in memory +before performing the signature computation while bigger files are read in +block-by-block. A huge block-size leads to high memory consumption while a very +small block-size slows down the build considerably. + +The default value is to use a chunk size of 64 kilobytes, which should +be appropriate for most uses. + + + + + -n, --just-print, --dry-run, --recon + +No execute. Print the commands that would be executed to build +any out-of-date target files, but do not execute the commands. + + + + + --no-site-dir + +Prevents the automatic addition of the standard +site_scons +dirs to +sys.path. +Also prevents loading the +site_scons/site_init.py +modules if they exist, and prevents adding their +site_scons/site_tools +dirs to the toolpath. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --profile=file + +Run SCons under the Python profiler +and save the results in the specified +file. +The results may be analyzed using the Python +pstats module. + + + + + -q, --question + +Do not run any commands, or print anything. Just return an exit +status that is zero if the specified targets are already up to +date, non-zero otherwise. + + + + -Q + +Quiets SCons status messages about +reading SConscript files, +building targets +and entering directories. +Commands that are executed +to rebuild target files are still printed. + + + + + + + + + + --random + +Build dependencies in a random order. This is useful when +building multiple trees simultaneously with caching enabled, +to prevent multiple builds from simultaneously trying to build +or retrieve the same target files. + + + + + -s, --silent, --quiet + +Silent. Do not print commands that are executed to rebuild +target files. +Also suppresses SCons status messages. + + + + + -S, --no-keep-going, --stop + +Ignored for compatibility with GNU +make. + + + + + --site-dir=dir + +Uses the named dir as the site dir rather than the default +site_scons +dirs. This dir will get prepended to +sys.path, +the module +dir/site_init.py +will get loaded if it exists, and +dir/site_tools +will get added to the default toolpath. + +The default set of +site_scons +dirs used when + +is not specified depends on the system platform, as follows. Note +that the directories are examined in the order given, from most +generic to most specific, so the last-executed site_init.py file is +the most specific one (which gives it the chance to override +everything else), and the dirs are prepended to the paths, again so +the last dir examined comes first in the resulting path. + + + + + + + Windows: + + +%ALLUSERSPROFILE/Application Data/scons/site_scons +%USERPROFILE%/Local Settings/Application Data/scons/site_scons +%APPDATA%/scons/site_scons +%HOME%/.scons/site_scons +./site_scons + + + + + Mac OS X: + + +/Library/Application Support/SCons/site_scons +/opt/local/share/scons/site_scons (for MacPorts) +/sw/share/scons/site_scons (for Fink) +$HOME/Library/Application Support/SCons/site_scons +$HOME/.scons/site_scons +./site_scons + + + + + Solaris: + + +/opt/sfw/scons/site_scons +/usr/share/scons/site_scons +$HOME/.scons/site_scons +./site_scons + + + + + Linux, HPUX, and other Posix-like systems: + + +/usr/share/scons/site_scons +$HOME/.scons/site_scons +./site_scons + + + + + + + + --stack-size=KILOBYTES + +Set the size stack used to run threads to +KILOBYTES. +This value determines the stack size of the threads used to run jobs. +These are the threads that execute the actions of the builders for the +nodes that are out-of-date. +Note that this option has no effect unless the +num_jobs +option, which corresponds to -j and --jobs, is larger than one. Using +a stack size that is too small may cause stack overflow errors. This +usually shows up as segmentation faults that cause scons to abort +before building anything. Using a stack size that is too large will +cause scons to use more memory than required and may slow down the entire +build process. + +The default value is to use a stack size of 256 kilobytes, which should +be appropriate for most uses. You should not need to increase this value +unless you encounter stack overflow errors. + + + + + -t, --touch + +Ignored for compatibility with GNU +make. +(Touching a file to make it +appear up-to-date is unnecessary when using +scons.) + + + + + --taskmastertrace=file + +Prints trace information to the specified +file +about how the internal Taskmaster object +evaluates and controls the order in which Nodes are built. +A file name of +- +may be used to specify the standard output. + + + + + -tree=options + +Prints a tree of the dependencies +after each top-level target is built. +This prints out some or all of the tree, +in various formats, +depending on the +options +specified: + + + + + --tree=all + +Print the entire dependency tree +after each top-level target is built. +This prints out the complete dependency tree, +including implicit dependencies and ignored dependencies. + + + + + --tree=derived + +Restricts the tree output to only derived (target) files, +not source files. + + + + + --tree=status + +Prints status information for each displayed node. + + + + + --tree=prune + +Prunes the tree to avoid repeating dependency information +for nodes that have already been displayed. +Any node that has already been displayed +will have its name printed in +[square brackets], +as an indication that the dependencies +for that node can be found by searching +for the relevant output higher up in the tree. + + + + + +Multiple options may be specified, +separated by commas: + + +# Prints only derived files, with status information: +scons --tree=derived,status + +# Prints all dependencies of target, with status information +# and pruning dependencies of already-visited Nodes: +scons --tree=all,prune,status target + + + + + -u, --up, --search-up + +Walks up the directory structure until an +SConstruct , +Sconstruct +or +sconstruct +file is found, and uses that +as the top of the directory tree. +If no targets are specified on the command line, +only targets at or below the +current directory will be built. + + + + + -U + +Works exactly the same way as the + +option except for the way default targets are handled. +When this option is used and no targets are specified on the command line, +all default targets that are defined in the SConscript(s) in the current +directory are built, regardless of what directory the resultant targets end +up in. + + + + + -v, --version + +Print the +scons +version, copyright information, +list of authors, and any other relevant information. +Then exit. + + + + + -w, --print-directory + +Print a message containing the working directory before and +after other processing. + + + + + --no-print-directory + +Turn off -w, even if it was turned on implicitly. + + + + + --warn=type, --warn=no-type + +Enable or disable warnings. +type +specifies the type of warnings to be enabled or disabled: + + + + + --warn=all, --warn=no-all + +Enables or disables all warnings. + + + + + --warn=cache-write-error, --warn=no-cache-write-error + +Enables or disables warnings about errors trying to +write a copy of a built file to a specified +CacheDir(). +These warnings are disabled by default. + + + + + --warn=corrupt-sconsign, --warn=no-corrupt-sconsign + +Enables or disables warnings about unfamiliar signature data in +.sconsign +files. +These warnings are enabled by default. + + + + + --warn=dependency, --warn=no-dependency + +Enables or disables warnings about dependencies. +These warnings are disabled by default. + + + + + --warn=deprecated, --warn=no-deprecated + +Enables or disables all warnings about use of +currently deprecated features. +These warnings are enabled by default. +Note that the + +option does not disable warnings about absolutely all deprecated features. +Warnings for some deprecated features that have already been through +several releases with deprecation warnings +may be mandatory for a release or two +before they are officially no longer supported by SCons. +Warnings for some specific deprecated features +may be enabled or disabled individually; +see below. + +
+ + + --warn=deprecated-copy, --warn=no-deprecated-copy + +Enables or disables warnings about use of the deprecated +env.Copy() +method. + + + + + --warn=deprecated-source-signatures, --warn=no-deprecated-source-signatures + +Enables or disables warnings about use of the deprecated +SourceSignatures() +function or +env.SourceSignatures() +method. + + + + + --warn=deprecated-target-signatures, --warn=no-deprecated-target-signatures + +Enables or disables warnings about use of the deprecated +TargetSignatures() +function or +env.TargetSignatures() +method. + + + +
+ +
+
+ + --warn=duplicate-environment, --warn=no-duplicate-environment + +Enables or disables warnings about attempts to specify a build +of a target with two different construction environments +that use the same action. +These warnings are enabled by default. + + + + + --warn=fortran-cxx-mix, --warn=no-fortran-cxx-mix + +Enables or disables the specific warning about linking +Fortran and C++ object files in a single executable, +which can yield unpredictable behavior with some compilers. + + + + + --warn=future-deprecated, --warn=no-future-deprecated + +Enables or disables warnings about features +that will be deprecated in the future. +These warnings are disabled by default. +Enabling this warning is especially +recommended for projects that redistribute +SCons configurations for other users to build, +so that the project can be warned as soon as possible +about to-be-deprecated features +that may require changes to the configuration. + + + + + --warn=link, --warn=no-link + +Enables or disables warnings about link steps. + + + + + --warn=misleading-keywords, --warn=no-misleading-keywords + +Enables or disables warnings about use of the misspelled keywords +targets +and +sources +when calling Builders. +(Note the last +s +characters, the correct spellings are +target +and +source.) +These warnings are enabled by default. + + + + + --warn=missing-sconscript, --warn=no-missing-sconscript + +Enables or disables warnings about missing SConscript files. +These warnings are enabled by default. + + + + + --warn=no-md5-module, --warn=no-no-md5-module + +Enables or disables warnings about the version of Python +not having an MD5 checksum module available. +These warnings are enabled by default. + + + + + --warn=no-metaclass-support, --warn=no-no-metaclass-support + +Enables or disables warnings about the version of Python +not supporting metaclasses when the + +option is used. +These warnings are enabled by default. + + + + + --warn=no-object-count, --warn=no-no-object-count + +Enables or disables warnings about the + +feature not working when +scons +is run with the python + +option or from optimized Python (.pyo) modules. + + + + + --warn=no-parallel-support, --warn=no-no-parallel-support + +Enables or disables warnings about the version of Python +not being able to support parallel builds when the + +option is used. +These warnings are enabled by default. + + + + + --warn=python-version, --warn=no-python-version + +Enables or disables the warning about running +SCons with a deprecated version of Python. +These warnings are enabled by default. + + + + + --warn=reserved-variable, --warn=no-reserved-variable + +Enables or disables warnings about attempts to set the +reserved construction variable names +CHANGED_SOURCES, +CHANGED_TARGETS, +TARGET, +TARGETS, +SOURCE, +SOURCES, +UNCHANGED_SOURCES +or +UNCHANGED_TARGETS. +These warnings are disabled by default. + + + + + --warn=stack-size, --warn=no-stack-size + +Enables or disables warnings about requests to set the stack size +that could not be honored. +These warnings are enabled by default. + + + + + + + + + + + + + + + + + + + + + + + + + + + --warn=target_not_build, --warn=no-target_not_built + +Enables or disables warnings about a build rule not building the + expected targets. These warnings are not currently enabled by default. + + + + + -Y repository, --repository=repository, --srcdir=repository + +Search the specified repository for any input and target +files not found in the local directory hierarchy. Multiple + +options may be specified, in which case the +repositories are searched in the order specified. + + + +
+
+ +CONFIGURATION FILE REFERENCE + + + +Construction Environments +A construction environment is the basic means by which the SConscript +files communicate build information to +scons. +A new construction environment is created using the +Environment +function: + + +env = Environment() + + +Variables, called +construction +variables, +may be set in a construction environment +either by specifying them as keywords when the object is created +or by assigning them a value after the object is created: + + +env = Environment(FOO = 'foo') +env['BAR'] = 'bar' + + +As a convenience, +construction variables may also be set or modified by the +parse_flags +keyword argument, which applies the +ParseFlags +method (described below) to the argument value +after all other processing is completed. +This is useful either if the exact content of the flags is unknown +(for example, read from a control file) +or if the flags are distributed to a number of construction variables. + + +env = Environment(parse_flags = '-Iinclude -DEBUG -lm') + + +This example adds 'include' to +CPPPATH, +'EBUG' to +CPPDEFINES, +and 'm' to +LIBS. + +By default, a new construction environment is +initialized with a set of builder methods +and construction variables that are appropriate +for the current platform. +An optional platform keyword argument may be +used to specify that an environment should +be initialized for a different platform: + + +env = Environment(platform = 'cygwin') +env = Environment(platform = 'os2') +env = Environment(platform = 'posix') +env = Environment(platform = 'win32') + + +Specifying a platform initializes the appropriate +construction variables in the environment +to use and generate file names with prefixes +and suffixes appropriate for the platform. + +Note that the +win32 +platform adds the +SystemDrive +and +SystemRoot +variables from the user's external environment +to the construction environment's +ENV +dictionary. +This is so that any executed commands +that use sockets to connect with other systems +(such as fetching source files from +external CVS repository specifications like +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/scons) +will work on Windows systems. + +The platform argument may be function or callable object, +in which case the Environment() method +will call the specified argument to update +the new construction environment: + + +def my_platform(env): + env['VAR'] = 'xyzzy' + +env = Environment(platform = my_platform) + + +Additionally, a specific set of tools +with which to initialize the environment +may be specified as an optional keyword argument: + + +env = Environment(tools = ['msvc', 'lex']) + + +Non-built-in tools may be specified using the toolpath argument: + + +env = Environment(tools = ['default', 'foo'], toolpath = ['tools']) + + +This looks for a tool specification in tools/foo.py (as well as +using the ordinary default tools for the platform). foo.py should +have two functions: generate(env, **kw) and exists(env). +The +generate() +function +modifies the passed-in environment +to set up variables so that the tool +can be executed; +it may use any keyword arguments +that the user supplies (see below) +to vary its initialization. +The +exists() +function should return a true +value if the tool is available. +Tools in the toolpath are used before +any of the built-in ones. For example, adding gcc.py to the toolpath +would override the built-in gcc tool. +Also note that the toolpath is +stored in the environment for use +by later calls to +Clone() +and +Tool() +methods: + + +base = Environment(toolpath=['custom_path']) +derived = base.Clone(tools=['custom_tool']) +derived.CustomBuilder() + + +The elements of the tools list may also +be functions or callable objects, +in which case the Environment() method +will call the specified elements +to update the new construction environment: + + +def my_tool(env): + env['XYZZY'] = 'xyzzy' + +env = Environment(tools = [my_tool]) + + +The individual elements of the tools list +may also themselves be two-element lists of the form +(toolname, kw_dict). +SCons searches for the +toolname +specification file as described above, and +passes +kw_dict, +which must be a dictionary, as keyword arguments to the tool's +generate +function. +The +generate +function can use the arguments to modify the tool's behavior +by setting up the environment in different ways +or otherwise changing its initialization. + + +# in tools/my_tool.py: +def generate(env, **kw): + # Sets MY_TOOL to the value of keyword argument 'arg1' or 1. + env['MY_TOOL'] = kw.get('arg1', '1') +def exists(env): + return 1 + +# in SConstruct: +env = Environment(tools = ['default', ('my_tool', {'arg1': 'abc'})], + toolpath=['tools']) + + +The tool definition (i.e. my_tool()) can use the PLATFORM variable from +the environment it receives to customize the tool for different platforms. + +If no tool list is specified, then SCons will auto-detect the installed +tools using the PATH variable in the ENV construction variable and the +platform name when the Environment is constructed. Changing the PATH +variable after the Environment is constructed will not cause the tools to +be redetected. + +SCons supports the following tool specifications out of the box: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Additionally, there is a "tool" named +default +which configures the +environment with a default set of tools for the current platform. + +On posix and cygwin platforms +the GNU tools (e.g. gcc) are preferred by SCons, +on Windows the Microsoft tools (e.g. msvc) +followed by MinGW are preferred by SCons, +and in OS/2 the IBM tools (e.g. icc) are preferred by SCons. + + + +Builder Methods + +Build rules are specified by calling a construction +environment's builder methods. +The arguments to the builder methods are +target +(a list of targets to be built, +usually file names) +and +source +(a list of sources to be built, +usually file names). + +Because long lists of file names +can lead to a lot of quoting, +scons +supplies a +Split() +global function +and a same-named environment method +that split a single string +into a list, separated on +strings of white-space characters. +(These are similar to the split() member function of Python strings +but work even if the input isn't a string.) + +Like all Python arguments, +the target and source arguments to a builder method +can be specified either with or without +the "target" and "source" keywords. +When the keywords are omitted, +the target is first, +followed by the source. +The following are equivalent examples of calling the Program builder method: + + +env.Program('bar', ['bar.c', 'foo.c']) +env.Program('bar', Split('bar.c foo.c')) +env.Program('bar', env.Split('bar.c foo.c')) +env.Program(source = ['bar.c', 'foo.c'], target = 'bar') +env.Program(target = 'bar', Split('bar.c foo.c')) +env.Program(target = 'bar', env.Split('bar.c foo.c')) +env.Program('bar', source = 'bar.c foo.c'.split()) + + +Target and source file names +that are not absolute path names +(that is, do not begin with +/ +on POSIX systems +or +\fR +on Windows systems, +with or without +an optional drive letter) +are interpreted relative to the directory containing the +SConscript +file being read. +An initial +# +(hash mark) +on a path name means that the rest of the file name +is interpreted relative to +the directory containing +the top-level +SConstruct +file, +even if the +# +is followed by a directory separator character +(slash or backslash). + +Examples: + + +# The comments describing the targets that will be built +# assume these calls are in a SConscript file in the +# a subdirectory named "subdir". + +# Builds the program "subdir/foo" from "subdir/foo.c": +env.Program('foo', 'foo.c') + +# Builds the program "/tmp/bar" from "subdir/bar.c": +env.Program('/tmp/bar', 'bar.c') + +# An initial '#' or '#/' are equivalent; the following +# calls build the programs "foo" and "bar" (in the +# top-level SConstruct directory) from "subdir/foo.c" and +# "subdir/bar.c", respectively: +env.Program('#foo', 'foo.c') +env.Program('#/bar', 'bar.c') + +# Builds the program "other/foo" (relative to the top-level +# SConstruct directory) from "subdir/foo.c": +env.Program('#other/foo', 'foo.c') + + +When the target shares the same base name +as the source and only the suffix varies, +and if the builder method has a suffix defined for the target file type, +then the target argument may be omitted completely, +and +scons +will deduce the target file name from +the source file name. +The following examples all build the +executable program +bar +(on POSIX systems) +or +bar.exe +(on Windows systems) +from the bar.c source file: + + +env.Program(target = 'bar', source = 'bar.c') +env.Program('bar', source = 'bar.c') +env.Program(source = 'bar.c') +env.Program('bar.c') + + +As a convenience, a +srcdir +keyword argument may be specified +when calling a Builder. +When specified, +all source file strings that are not absolute paths +will be interpreted relative to the specified +srcdir. +The following example will build the +build/prog +(or +build/prog.exe +on Windows) +program from the files +src/f1.c +and +src/f2.c: + + +env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src') + + +It is possible to override or add construction variables when calling a +builder method by passing additional keyword arguments. +These overridden or added +variables will only be in effect when building the target, so they will not +affect other parts of the build. For example, if you want to add additional +libraries for just one program: + + +env.Program('hello', 'hello.c', LIBS=['gl', 'glut']) + + +or generate a shared library with a non-standard suffix: + + +env.SharedLibrary('word', 'word.cpp', + SHLIBSUFFIX='.ocx', + LIBSUFFIXES=['.ocx']) + + +(Note that both the $SHLIBSUFFIX and $LIBSUFFIXES variables must be set +if you want SCons to search automatically +for dependencies on the non-standard library names; +see the descriptions of these variables, below, for more information.) + +It is also possible to use the +parse_flags +keyword argument in an override: + + +env = Program('hello', 'hello.c', parse_flags = '-Iinclude -DEBUG -lm') + + +This example adds 'include' to +CPPPATH, +'EBUG' to +CPPDEFINES, +and 'm' to +LIBS. + +Although the builder methods defined by +scons +are, in fact, +methods of a construction environment object, +they may also be called without an explicit environment: + + +Program('hello', 'hello.c') +SharedLibrary('word', 'word.cpp') + + +In this case, +the methods are called internally using a default construction +environment that consists of the tools and values that +scons +has determined are appropriate for the local system. + +Builder methods that can be called without an explicit +environment may be called from custom Python modules that you +import into an SConscript file by adding the following +to the Python module: + + +from SCons.Script import * + + +All builder methods return a list-like object +containing Nodes that +represent the target or targets that will be built. +A +Node +is an internal SCons object +which represents +build targets or sources. + +The returned Node-list object +can be passed to other builder methods as source(s) +or passed to any SCons function or method +where a filename would normally be accepted. +For example, if it were necessary +to add a specific + +flag when compiling one specific object file: + + +bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR') +env.Program(source = ['foo.c', bar_obj_list, 'main.c']) + + +Using a Node in this way +makes for a more portable build +by avoiding having to specify +a platform-specific object suffix +when calling the Program() builder method. + +Note that Builder calls will automatically "flatten" +the source and target file lists, +so it's all right to have the bar_obj list +return by the StaticObject() call +in the middle of the source file list. +If you need to manipulate a list of lists returned by Builders +directly using Python, +you can either build the list by hand: + + +foo = Object('foo.c') +bar = Object('bar.c') +objects = ['begin.o'] + foo + ['middle.o'] + bar + ['end.o'] +for object in objects: + print str(object) + + +Or you can use the +Flatten() +function supplied by scons +to create a list containing just the Nodes, +which may be more convenient: + + +foo = Object('foo.c') +bar = Object('bar.c') +objects = Flatten(['begin.o', foo, 'middle.o', bar, 'end.o']) +for object in objects: + print str(object) + + +Note also that because Builder calls return +a list-like object, not an actual Python list, +you should +not +use the Python ++= +operator to append Builder results to a Python list. +Because the list and the object are different types, +Python will not update the original list in place, +but will instead create a new Node-list object +containing the concatenation of the list +elements and the Builder results. +This will cause problems for any other Python variables +in your SCons configuration +that still hold on to a reference to the original list. +Instead, use the Python +.extend() +method to make sure the list is updated in-place. +Example: + + +object_files = [] + +# Do NOT use += as follows: +# +# object_files += Object('bar.c') +# +# It will not update the object_files list in place. +# +# Instead, use the .extend() method: +object_files.extend(Object('bar.c')) + + + +The path name for a Node's file may be used +by passing the Node to the Python-builtin +str() +function: + + +bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR') +print "The path to bar_obj is:", str(bar_obj_list[0]) + + +Note again that because the Builder call returns a list, +we have to access the first element in the list +(bar_obj_list[0]) +to get at the Node that actually represents +the object file. + +Builder calls support a +chdir +keyword argument that +specifies that the Builder's action(s) +should be executed +after changing directory. +If the +chdir +argument is +a string or a directory Node, +scons will change to the specified directory. +If the +chdir +is not a string or Node +and is non-zero, +then scons will change to the +target file's directory. + + +# scons will change to the "sub" subdirectory +# before executing the "cp" command. +env.Command('sub/dir/foo.out', 'sub/dir/foo.in', + "cp dir/foo.in dir/foo.out", + chdir='sub') + +# Because chdir is not a string, scons will change to the +# target's directory ("sub/dir") before executing the +# "cp" command. +env.Command('sub/dir/foo.out', 'sub/dir/foo.in', + "cp foo.in foo.out", + chdir=1) + + +Note that scons will +not +automatically modify +its expansion of +construction variables like +$TARGET +and +$SOURCE +when using the chdir +keyword argument--that is, +the expanded file names +will still be relative to +the top-level SConstruct directory, +and consequently incorrect +relative to the chdir directory. +If you use the chdir keyword argument, +you will typically need to supply a different +command line using +expansions like +${TARGET.file} +and +${SOURCE.file} +to use just the filename portion of the +targets and source. + +scons +provides the following builder methods: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +All +targets of builder methods automatically depend on their sources. +An explicit dependency can +be specified using the +Depends +method of a construction environment (see below). + +In addition, +scons +automatically scans +source files for various programming languages, +so the dependencies do not need to be specified explicitly. +By default, SCons can +C source files, +C++ source files, +Fortran source files with +.F +(POSIX systems only), +.fpp, +or +.FPP +file extensions, +and assembly language files with +.S +(POSIX systems only), +.spp, +or +.SPP +files extensions +for C preprocessor dependencies. +SCons also has default support +for scanning D source files, +You can also write your own Scanners +to add support for additional source file types. +These can be added to the default +Scanner object used by the +Object(), +StaticObject(), +and +SharedObject() +Builders by adding them +to the +SourceFileScanner +object. +See the section "Scanner Objects" +below, for more information about +defining your own Scanner objects +and using the +SourceFileScanner +object. + + + +Methods and Functions to Do Things +In addition to Builder methods, +scons +provides a number of other construction environment methods +and global functions to +manipulate the build configuration. + +Usually, a construction environment method +and global function with the same name both exist +so that you don't have to remember whether +to a specific bit of functionality +must be called with or without a construction environment. +In the following list, +if you call something as a global function +it looks like: + +Function(arguments) + +and if you call something through a construction +environment it looks like: + +env.Function(arguments) + +If you can call the functionality in both ways, +then both forms are listed. + +Global functions may be called from custom Python modules that you +import into an SConscript file by adding the following +to the Python module: + + +from SCons.Script import * + + +Except where otherwise noted, +the same-named +construction environment method +and global function +provide the exact same functionality. +The only difference is that, +where appropriate, +calling the functionality through a construction environment will +substitute construction variables into +any supplied strings. +For example: + + +env = Environment(FOO = 'foo') +Default('$FOO') +env.Default('$FOO') + + +In the above example, +the first call to the global +Default() +function will actually add a target named +$FOO +to the list of default targets, +while the second call to the +env.Default() +construction environment method +will expand the value +and add a target named +foo +to the list of default targets. +For more on construction variable expansion, +see the next section on +construction variables. + +Construction environment methods +and global functions supported by +scons +include: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SConscript Variables +In addition to the global functions and methods, +scons +supports a number of Python variables +that can be used in SConscript files +to affect how you want the build to be performed. +These variables may be accessed from custom Python modules that you +import into an SConscript file by adding the following +to the Python module: + + +from SCons.Script import * + + + + + + ARGLIST + +A list +keyword=value +arguments specified on the command line. +Each element in the list is a tuple +containing the +(keyword,value) +of the argument. +The separate +keyword +and +value +elements of the tuple +can be accessed by +subscripting for element +[0] +and +[1] +of the tuple, respectively. + +Example: + + +print "first keyword, value =", ARGLIST[0][0], ARGLIST[0][1] +print "second keyword, value =", ARGLIST[1][0], ARGLIST[1][1] +third_tuple = ARGLIST[2] +print "third keyword, value =", third_tuple[0], third_tuple[1] +for key, value in ARGLIST: + # process key and value + + + + + + + ARGUMENTS + +A dictionary of all the +keyword=value +arguments specified on the command line. +The dictionary is not in order, +and if a given keyword has +more than one value assigned to it +on the command line, +the last (right-most) value is +the one in the +ARGUMENTS +dictionary. + +Example: + + +if ARGUMENTS.get('debug', 0): + env = Environment(CCFLAGS = '-g') +else: + env = Environment() + + + + + + + BUILD_TARGETS + +A list of the targets which +scons +will actually try to build, +regardless of whether they were specified on +the command line or via the +Default() +function or method. +The elements of this list may be strings +or +nodes, so you should run the list through the Python +str +function to make sure any Node path names +are converted to strings. + +Because this list may be taken from the +list of targets specified using the +Default() +function or method, +the contents of the list may change +on each successive call to +Default(). +See the +DEFAULT_TARGETS +list, below, +for additional information. + +Example: + + +if 'foo' in BUILD_TARGETS: + print "Don't forget to test the `foo' program!" +if 'special/program' in BUILD_TARGETS: + SConscript('special') + + + + + +Note that the +BUILD_TARGETS +list only contains targets expected listed +on the command line or via calls to the +Default() +function or method. +It does +not +contain all dependent targets that will be built as +a result of making the sure the explicitly-specified +targets are up to date. + + + + + COMMAND_LINE_TARGETS + +A list of the targets explicitly specified on +the command line. +If there are no targets specified on the command line, +the list is empty. +This can be used, for example, +to take specific actions only +when a certain target or targets +is explicitly being built. + +Example: + + +if 'foo' in COMMAND_LINE_TARGETS: + print "Don't forget to test the `foo' program!" +if 'special/program' in COMMAND_LINE_TARGETS: + SConscript('special') + + + + + + + DEFAULT_TARGETS + +A list of the target +nodes +that have been specified using the +Default() +function or method. +The elements of the list are nodes, +so you need to run them through the Python +str +function to get at the path name for each Node. + +Example: + + +print str(DEFAULT_TARGETS[0]) +if 'foo' in map(str, DEFAULT_TARGETS): + print "Don't forget to test the `foo' program!" + + + + + +The contents of the +DEFAULT_TARGETS +list change on on each successive call to the +Default() +function: + + +print map(str, DEFAULT_TARGETS) # originally [] +Default('foo') +print map(str, DEFAULT_TARGETS) # now a node ['foo'] +Default('bar') +print map(str, DEFAULT_TARGETS) # now a node ['foo', 'bar'] +Default(None) +print map(str, DEFAULT_TARGETS) # back to [] + + +Consequently, be sure to use +DEFAULT_TARGETS +only after you've made all of your +Default() +calls, +or else simply be careful of the order +of these statements in your SConscript files +so that you don't look for a specific +default target before it's actually been added to the list. + + + +Construction Variables + + + + + + + + + + + + + + + + +A construction environment has an associated dictionary of +construction variables +that are used by built-in or user-supplied build rules. +Construction variables must follow the same rules for +Python identifiers: +the initial character must be an underscore or letter, +followed by any number of underscores, letters, or digits. + +A number of useful construction variables are automatically defined by +scons for each supported platform, and additional construction variables +can be defined by the user. The following is a list of the automatically +defined construction variables: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Construction variables can be retrieved and set using the +Dictionary +method of the construction environment: + + +dict = env.Dictionary() +dict["CC"] = "cc" + + +or using the [] operator: + + +env["CC"] = "cc" + + +Construction variables can also be passed to the construction environment +constructor: + + +env = Environment(CC="cc") + + +or when copying a construction environment using the +Clone +method: + + +env2 = env.Clone(CC="cl.exe") + + + + +Configure Contexts + +scons +supports +configure contexts, +an integrated mechanism similar to the +various AC_CHECK macros in GNU autoconf +for testing for the existence of C header +files, libraries, etc. +In contrast to autoconf, +scons +does not maintain an explicit cache of the tested values, +but uses its normal dependency tracking to keep the checked values +up to date. However, users may override this behaviour with the + +command line option. + +The following methods can be used to perform checks: + + + + Configure(env, [custom_tests, conf_dir, log_file, config_h, clean, help]) + env.Configure([custom_tests, conf_dir, log_file, config_h, clean, help]) + +This creates a configure context, which can be used to perform checks. +env +specifies the environment for building the tests. +This environment may be modified when performing checks. +custom_tests +is a dictionary containing custom tests. +See also the section about custom tests below. +By default, no custom tests are added to the configure context. +conf_dir +specifies a directory where the test cases are built. +Note that this directory is not used for building +normal targets. +The default value is the directory +#/.sconf_temp. +log_file +specifies a file which collects the output from commands +that are executed to check for the existence of header files, libraries, etc. +The default is the file #/config.log. +If you are using the +VariantDir() +method, +you may want to specify a subdirectory under your variant directory. +config_h +specifies a C header file where the results of tests +will be written, e.g. #define HAVE_STDIO_H, #define HAVE_LIBM, etc. +The default is to not write a +config.h +file. +You can specify the same +config.h +file in multiple calls to Configure, +in which case +scons +will concatenate all results in the specified file. +Note that SCons +uses its normal dependency checking +to decide if it's necessary to rebuild +the specified +config_h +file. +This means that the file is not necessarily re-built each +time scons is run, +but is only rebuilt if its contents will have changed +and some target that depends on the +config_h +file is being built. + +The optional +clean +and +help +arguments can be used to suppress execution of the configuration +tests when the + +or + +options are used, respectively. +The default behavior is always to execute +configure context tests, +since the results of the tests may +affect the list of targets to be cleaned +or the help text. +If the configure tests do not affect these, +then you may add the +clean=False +or +help=False +arguments +(or both) +to avoid unnecessary test execution. + + + + +A created +Configure +instance has the following associated methods: + + + + SConf.Finish(context) + sconf.Finish() + +This method should be called after configuration is done. +It returns the environment as modified +by the configuration checks performed. +After this method is called, no further checks can be performed +with this configuration context. +However, you can create a new +Configure +context to perform additional checks. +Only one context should be active at a time. + +The following Checks are predefined. +(This list will likely grow larger as time +goes by and developers contribute new useful tests.) + + + + + SConf.CheckHeader(context, header, [include_quotes, language]) + sconf.CheckHeader(header, [include_quotes, language]) + +Checks if +header +is usable in the specified language. +header +may be a list, +in which case the last item in the list +is the header file to be checked, +and the previous list items are +header files whose +#include +lines should precede the +header line being checked for. +The optional argument +include_quotes +must be +a two character string, where the first character denotes the opening +quote and the second character denotes the closing quote. +By default, both characters are " (double quote). +The optional argument +language +should be either +C +or +C++ +and selects the compiler to be used for the check. +Returns 1 on success and 0 on failure. + + + + + SConf.CheckCHeader(context, header, [include_quotes]) + sconf.CheckCHeader(header, [include_quotes]) + +This is a wrapper around +SConf.CheckHeader +which checks if +header +is usable in the C language. +header +may be a list, +in which case the last item in the list +is the header file to be checked, +and the previous list items are +header files whose +#include +lines should precede the +header line being checked for. +The optional argument +include_quotes +must be +a two character string, where the first character denotes the opening +quote and the second character denotes the closing quote (both default +to \N'34'). +Returns 1 on success and 0 on failure. + + + + + SConf.CheckCXXHeader(context, header, [include_quotes]) + sconf.CheckCXXHeader(header, [include_quotes]) + +This is a wrapper around +SConf.CheckHeader +which checks if +header +is usable in the C++ language. +header +may be a list, +in which case the last item in the list +is the header file to be checked, +and the previous list items are +header files whose +#include +lines should precede the +header line being checked for. +The optional argument +include_quotes +must be +a two character string, where the first character denotes the opening +quote and the second character denotes the closing quote (both default +to \N'34'). +Returns 1 on success and 0 on failure. + + + + + SConf.CheckFunc(context,, function_name, [header, language]) + sconf.CheckFunc(function_name, [header, language]) + +Checks if the specified +C or C++ function is available. +function_name +is the name of the function to check for. +The optional +header +argument is a string +that will be +placed at the top +of the test file +that will be compiled +to check if the function exists; +the default is: + +#ifdef __cplusplus +extern "C" +#endif +char function_name(); + +The optional +language +argument should be +C +or +C++ +and selects the compiler to be used for the check; +the default is "C". + + + + + SConf.CheckLib(context, [library, symbol, header, language, autoadd=1]) + sconf.CheckLib([library, symbol, header, language, autoadd=1]) + +Checks if +library +provides +symbol. +If the value of +autoadd +is 1 and the library provides the specified +symbol, +appends the library to the LIBS construction environment variable. +library +may also be None (the default), +in which case +symbol +is checked with the current LIBS variable, +or a list of library names, +in which case each library in the list +will be checked for +symbol. +If +symbol +is not set or is +None, +then +SConf.CheckLib() +just checks if +you can link against the specified +library. +The optional +language +argument should be +C +or +C++ +and selects the compiler to be used for the check; +the default is "C". +The default value for +autoadd +is 1. +This method returns 1 on success and 0 on error. + + + + + SConf.CheckLibWithHeader(context, library, header, language, [call, autoadd]) + sconf.CheckLibWithHeader(library, header, language, [call, autoadd]) + + +In contrast to the +SConf.CheckLib +call, this call provides a more sophisticated way to check against libraries. +Again, +library +specifies the library or a list of libraries to check. +header +specifies a header to check for. +header +may be a list, +in which case the last item in the list +is the header file to be checked, +and the previous list items are +header files whose +#include +lines should precede the +header line being checked for. +language +may be one of 'C','c','CXX','cxx','C++' and 'c++'. +call +can be any valid expression (with a trailing ';'). +If +call +is not set, +the default simply checks that you +can link against the specified +library. +autoadd +specifies whether to add the library to the environment (only if the check +succeeds). This method returns 1 on success and 0 on error. + + + + + SConf.CheckType(context, type_name, [includes, language]) + sconf.CheckType(type_name, [includes, language]) + +Checks for the existence of a type defined by +typedef. +type_name +specifies the typedef name to check for. +includes +is a string containing one or more +#include +lines that will be inserted into the program +that will be run to test for the existence of the type. +The optional +language +argument should be +C +or +C++ +and selects the compiler to be used for the check; +the default is "C". +Example: + +sconf.CheckType('foo_type', '#include "my_types.h"', 'C++') + + + + + + Configure.CheckCC(self) + +Checks whether the C compiler (as defined by the CC construction variable) works +by trying to compile a small source file. + +By default, SCons only detects if there is a program with the correct name, not +if it is a functioning compiler. + +This uses the exact same command than the one used by the object builder for C +source file, so it can be used to detect if a particular compiler flag works or +not. + + + + + Configure.CheckCXX(self) + +Checks whether the C++ compiler (as defined by the CXX construction variable) +works by trying to compile a small source file. By default, SCons only detects +if there is a program with the correct name, not if it is a functioning compiler. + +This uses the exact same command than the one used by the object builder for +CXX source files, so it can be used to detect if a particular compiler flag +works or not. + + + + + Configure.CheckSHCC(self) + +Checks whether the C compiler (as defined by the SHCC construction variable) works +by trying to compile a small source file. By default, SCons only detects if +there is a program with the correct name, not if it is a functioning compiler. + +This uses the exact same command than the one used by the object builder for C +source file, so it can be used to detect if a particular compiler flag works or +not. This does not check whether the object code can be used to build a shared +library, only that the compilation (not link) succeeds. + + + + + Configure.CheckSHCXX(self) + +Checks whether the C++ compiler (as defined by the SHCXX construction variable) +works by trying to compile a small source file. By default, SCons only detects +if there is a program with the correct name, not if it is a functioning compiler. + +This uses the exact same command than the one used by the object builder for +CXX source files, so it can be used to detect if a particular compiler flag +works or not. This does not check whether the object code can be used to build +a shared library, only that the compilation (not link) succeeds. + + + + +Example of a typical Configure usage: + + +env = Environment() +conf = Configure( env ) +if not conf.CheckCHeader( 'math.h' ): + print 'We really need math.h!' + Exit(1) +if conf.CheckLibWithHeader( 'qt', 'qapp.h', 'c++', + 'QApplication qapp(0,0);' ): + # do stuff for qt - usage, e.g. + conf.env.Append( CPPFLAGS = '-DWITH_QT' ) +env = conf.Finish() + + + + + SConf.CheckTypeSize(context, type_name, [header, language, expect]) + sconf.CheckTypeSize(type_name, [header, language, expect]) + +Checks for the size of a type defined by +typedef. +type_name +specifies the typedef name to check for. +The optional +header +argument is a string +that will be +placed at the top +of the test file +that will be compiled +to check if the function exists; +the default is empty. +The optional +language +argument should be +C +or +C++ +and selects the compiler to be used for the check; +the default is "C". +The optional +expect +argument should be an integer. +If this argument is used, +the function will only check whether the type +given in type_name has the expected size (in bytes). +For example, +CheckTypeSize('short', expect = 2) +will return success only if short is two bytes. + + + + + + + + SConf.CheckDeclaration(context, symbol, [includes, language]) + sconf.CheckDeclaration(symbol, [includes, language]) + +Checks if the specified +symbol +is declared. +includes +is a string containing one or more +#include +lines that will be inserted into the program +that will be run to test for the existence of the type. +The optional +language +argument should be +C +or +C++ +and selects the compiler to be used for the check; +the default is "C". + + + + + SConf.Define(context, symbol, [value, comment]) + sconf.Define(symbol, [value, comment]) + +This function does not check for anything, but defines a +preprocessor symbol that will be added to the configuration header file. +It is the equivalent of AC_DEFINE, +and defines the symbol +name +with the optional +value +and the optional comment +comment. + + + + + +Examples: + + +env = Environment() +conf = Configure( env ) + +# Puts the following line in the config header file: +# #define A_SYMBOL +conf.Define('A_SYMBOL') + +# Puts the following line in the config header file: +# #define A_SYMBOL 1 +conf.Define('A_SYMBOL', 1) + + + +Be careful about quoting string values, though: + + +env = Environment() +conf = Configure( env ) + +# Puts the following line in the config header file: +# #define A_SYMBOL YA +conf.Define('A_SYMBOL', "YA") + +# Puts the following line in the config header file: +# #define A_SYMBOL "YA" +conf.Define('A_SYMBOL', '"YA"') + + + +For comment: + + +env = Environment() +conf = Configure( env ) + +# Puts the following lines in the config header file: +# /* Set to 1 if you have a symbol */ +# #define A_SYMBOL 1 +conf.Define('A_SYMBOL', 1, 'Set to 1 if you have a symbol') + + +You can define your own custom checks. +in addition to the predefined checks. +These are passed in a dictionary to the Configure function. +This dictionary maps the names of the checks +to user defined Python callables +(either Python functions or class instances implementing the +__call__ +method). +The first argument of the call is always a +CheckContext +instance followed by the arguments, +which must be supplied by the user of the check. +These CheckContext instances define the following methods: + + + + CheckContext.Message(self, text) + + +Usually called before the check is started. +text +will be displayed to the user, e.g. 'Checking for library X...' + + + + + CheckContext.Result(self,, res) + + +Usually called after the check is done. +res +can be either an integer or a string. In the former case, 'yes' (res != 0) +or 'no' (res == 0) is displayed to the user, in the latter case the +given string is displayed. + + + + + CheckContext.TryCompile(self, text, extension) + +Checks if a file with the specified +extension +(e.g. '.c') containing +text +can be compiled using the environment's +Object +builder. Returns 1 on success and 0 on failure. + + + + + CheckContext.TryLink(self, text, extension) + +Checks, if a file with the specified +extension +(e.g. '.c') containing +text +can be compiled using the environment's +Program +builder. Returns 1 on success and 0 on failure. + + + + + CheckContext.TryRun(self, text, extension) + +Checks, if a file with the specified +extension +(e.g. '.c') containing +text +can be compiled using the environment's +Program +builder. On success, the program is run. If the program +executes successfully +(that is, its return status is 0), +a tuple +(1, outputStr) +is returned, where +outputStr +is the standard output of the +program. +If the program fails execution +(its return status is non-zero), +then (0, '') is returned. + + + + + CheckContext.TryAction(self, action, [text, extension]) + +Checks if the specified +action +with an optional source file (contents +text +, extension +extension += '' +) can be executed. +action +may be anything which can be converted to a +scons +Action. +On success, +(1, outputStr) +is returned, where +outputStr +is the content of the target file. +On failure +(0, '') +is returned. + + + + + CheckContext.TryBuild(self, builder, [text, extension]) + +Low level implementation for testing specific builds; +the methods above are based on this method. +Given the Builder instance +builder +and the optional +text +of a source file with optional +extension, +this method returns 1 on success and 0 on failure. In addition, +self.lastTarget +is set to the build target node, if the build was successful. + + + + +Example for implementing and using custom tests: + + +def CheckQt(context, qtdir): + context.Message( 'Checking for qt ...' ) + lastLIBS = context.env['LIBS'] + lastLIBPATH = context.env['LIBPATH'] + lastCPPPATH= context.env['CPPPATH'] + context.env.Append(LIBS = 'qt', LIBPATH = qtdir + '/lib', CPPPATH = qtdir + '/include' ) + ret = context.TryLink(""" +#include <qapp.h> +int main(int argc, char **argv) { + QApplication qapp(argc, argv); + return 0; +} +""") + if not ret: + context.env.Replace(LIBS = lastLIBS, LIBPATH=lastLIBPATH, CPPPATH=lastCPPPATH) + context.Result( ret ) + return ret + +env = Environment() +conf = Configure( env, custom_tests = { 'CheckQt' : CheckQt } ) +if not conf.CheckQt('/usr/lib/qt'): + print 'We really need qt!' + Exit(1) +env = conf.Finish() + + + + +Command-Line Construction Variables + +Often when building software, +some variables must be specified at build time. +For example, libraries needed for the build may be in non-standard +locations, or site-specific compiler options may need to be passed to the +compiler. +scons +provides a +Variables +object to support overriding construction variables +on the command line: + +$ scons VARIABLE=foo + +The variable values can also be specified in a text-based SConscript file. +To create a Variables object, call the Variables() function: + + + + Variables([files], [args]) + +This creates a Variables object that will read construction variables from +the file or list of filenames specified in +files. +If no files are specified, +or the +files +argument is +None, +then no files will be read. +The optional argument +args +is a dictionary of +values that will override anything read from the specified files; +it is primarily intended to be passed the +ARGUMENTS +dictionary that holds variables +specified on the command line. +Example: + + +vars = Variables('custom.py') +vars = Variables('overrides.py', ARGUMENTS) +vars = Variables(None, {FOO:'expansion', BAR:7}) + + +Variables objects have the following methods: + + + + + Add(key, [help, default, validator, converter]) + +This adds a customizable construction variable to the Variables object. +key +is the name of the variable. +help +is the help text for the variable. +default +is the default value of the variable; +if the default value is +None +and there is no explicit value specified, +the construction variable will +not +be added to the construction environment. +validator +is called to validate the value of the variable, and should take three +arguments: key, value, and environment. +The recommended way to handle an invalid value is +to raise an exception (see example below). +converter +is called to convert the value before putting it in the environment, and +should take either a value, or the value and environment, as parameters. +The +converter +must return a value, +which will be converted into a string +before being validated by the +validator +(if any) +and then added to the environment. + +Examples: + + +vars.Add('CC', 'The C compiler') + +def validate_color(key, val, env): + if not val in ['red', 'blue', 'yellow']: + raise Exception("Invalid color value '%s'" % val) +vars.Add('COLOR', validator=valid_color) + + + + + + AddVariables(list) + +A wrapper script that adds +multiple customizable construction variables +to a Variables object. +list +is a list of tuple or list objects +that contain the arguments +for an individual call to the +Add +method. + + +opt.AddVariables( + ('debug', '', 0), + ('CC', 'The C compiler'), + ('VALIDATE', 'An option for testing validation', + 'notset', validator, None), + ) + + + + + + Update(env, [args]) + +This updates a construction environment +env +with the customized construction variables. +Any specified variables that are +not +configured for the Variables object +will be saved and may be +retrieved with the +UnknownVariables() +method, below. + +Normally this method is not called directly, +but is called indirectly by passing the Variables object to +the Environment() function: + + +env = Environment(variables=vars) + + + + + + +The text file(s) that were specified +when the Variables object was created +are executed as Python scripts, +and the values of (global) Python variables set in the file +are added to the construction environment. + +Example: + + +CC = 'my_cc' + + + + + UnknownVariables() + +Returns a dictionary containing any +variables that were specified +either in the files or the dictionary +with which the Variables object was initialized, +but for which the Variables object was +not configured. + + +env = Environment(variables=vars) +for key, value in vars.UnknownVariables(): + print "unknown variable: %s=%s" % (key, value) + + + + + + Save(filename, env) + +This saves the currently set variables into a script file named +filename +that can be used on the next invocation to automatically load the current +settings. This method combined with the Variables method can be used to +support caching of variables between runs. + + +env = Environment() +vars = Variables(['variables.cache', 'custom.py']) +vars.Add(...) +vars.Update(env) +vars.Save('variables.cache', env) + + + + + + GenerateHelpText(env, [sort]) + +This generates help text documenting the customizable construction +variables suitable to passing in to the Help() function. +env +is the construction environment that will be used to get the actual values +of customizable variables. Calling with +an optional +sort +function +will cause the output to be sorted +by the specified argument. +The specific +sort +function +should take two arguments +and return +-1, 0 or 1 +(like the standard Python +cmp +function). + + +Help(vars.GenerateHelpText(env)) +Help(vars.GenerateHelpText(env, sort=cmp)) + + + + + + FormatVariableHelpText(env, opt, help, default, actual) + +This method returns a formatted string +containing the printable help text +for one option. +It is normally not called directly, +but is called by the +GenerateHelpText() +method to create the returned help text. +It may be overridden with your own +function that takes the arguments specified above +and returns a string of help text formatted to your liking. +Note that the +GenerateHelpText() +will not put any blank lines or extra +characters in between the entries, +so you must add those characters to the returned +string if you want the entries separated. + + +def my_format(env, opt, help, default, actual): + fmt = "\n%s: default=%s actual=%s (%s)\n" + return fmt % (opt, default. actual, help) +vars.FormatVariableHelpText = my_format + + +To make it more convenient to work with customizable Variables, +scons +provides a number of functions +that make it easy to set up +various types of Variables: + + + + + BoolVariable(key, help, default) + +Return a tuple of arguments +to set up a Boolean option. +The option will use +the specified name +key, +have a default value of +default, +and display the specified +help +text. +The option will interpret the values +y, +yes, +t, +true, +1, +on +and +all +as true, +and the values +n, +no, +f, +false, +0, +off +and +none +as false. + + + + + EnumVariable(key, help, default, allowed_values, [map, ignorecase]) + +Return a tuple of arguments +to set up an option +whose value may be one +of a specified list of legal enumerated values. +The option will use +the specified name +key, +have a default value of +default, +and display the specified +help +text. +The option will only support those +values in the +allowed_values +list. +The optional +map +argument is a dictionary +that can be used to convert +input values into specific legal values +in the +allowed_values +list. +If the value of +ignore_case +is +0 +(the default), +then the values are case-sensitive. +If the value of +ignore_case +is +1, +then values will be matched +case-insensitive. +If the value of +ignore_case +is +2, +then values will be matched +case-insensitive, +and all input values will be +converted to lower case. + + + + + ListVariable(key, help, default, names, [,map]) + +Return a tuple of arguments +to set up an option +whose value may be one or more +of a specified list of legal enumerated values. +The option will use +the specified name +key, +have a default value of +default, +and display the specified +help +text. +The option will only support the values +all, +none, +or the values in the +names +list. +More than one value may be specified, +with all values separated by commas. +The default may be a string of +comma-separated default values, +or a list of the default values. +The optional +map +argument is a dictionary +that can be used to convert +input values into specific legal values +in the +names +list. + + + + + PackageVariable(key, help, default) + +Return a tuple of arguments +to set up an option +whose value is a path name +of a package that may be +enabled, disabled or +given an explicit path name. +The option will use +the specified name +key, +have a default value of +default, +and display the specified +help +text. +The option will support the values +yes, +true, +on, +enable +or +search, +in which case the specified +default +will be used, +or the option may be set to an +arbitrary string +(typically the path name to a package +that is being enabled). +The option will also support the values +no, +false, +off +or +disable +to disable use of the specified option. + + + + + PathVariable(key, help, default, [validator]) + +Return a tuple of arguments +to set up an option +whose value is expected to be a path name. +The option will use +the specified name +key, +have a default value of +default, +and display the specified +help +text. +An additional +validator +may be specified +that will be called to +verify that the specified path +is acceptable. +SCons supplies the +following ready-made validators: +PathVariable.PathExists +(the default), +which verifies that the specified path exists; +PathVariable.PathIsFile, +which verifies that the specified path is an existing file; +PathVariable.PathIsDir, +which verifies that the specified path is an existing directory; +PathVariable.PathIsDirCreate, +which verifies that the specified path is a directory +and will create the specified directory if the path does not exist; +and +PathVariable.PathAccept, +which simply accepts the specific path name argument without validation, +and which is suitable if you want your users +to be able to specify a directory path that will be +created as part of the build process, for example. +You may supply your own +validator +function, +which must take three arguments +(key, +the name of the variable to be set; +val, +the specified value being checked; +and +env, +the construction environment) +and should raise an exception +if the specified value is not acceptable. + + + + +These functions make it +convenient to create a number +of variables with consistent behavior +in a single call to the +AddVariables +method: + + +vars.AddVariables( + BoolVariable('warnings', 'compilation with -Wall and similiar', 1), + EnumVariable('debug', 'debug output and symbols', 'no' + allowed_values=('yes', 'no', 'full'), + map={}, ignorecase=0), # case sensitive + ListVariable('shared', + 'libraries to build as shared libraries', + 'all', + names = list_of_libs), + PackageVariable('x11', + 'use X11 installed here (yes = search some places)', + 'yes'), + PathVariable('qtdir', 'where the root of Qt is installed', qtdir), + PathVariable('foopath', 'where the foo library is installed', foopath, + PathVariable.PathIsDir), + +) + + + + +File and Directory Nodes + +The +File() +and +Dir() +functions return +File +and +Dir +Nodes, respectively. +python objects, respectively. +Those objects have several user-visible attributes +and methods that are often useful: + + + + path + +The build path +of the given +file or directory. +This path is relative to the top-level directory +(where the +SConstruct +file is found). +The build path is the same as the source path if +variant_dir +is not being used. + + + + + abspath + +The absolute build path of the given file or directory. + + + + + srcnode() + +The +srcnode() +method +returns another +File +or +Dir +object representing the +source +path of the given +File +or +Dir. +The + + +# Get the current build dir's path, relative to top. +Dir('.').path +# Current dir's absolute path +Dir('.').abspath +# Next line is always '.', because it is the top dir's path relative to itself. +Dir('#.').path +File('foo.c').srcnode().path # source path of the given source file. + +# Builders also return File objects: +foo = env.Program('foo.c') +print "foo will be built in %s"%foo.path + + +A +Dir +Node or +File +Node can also be used to create +file and subdirectory Nodes relative to the generating Node. +A +Dir +Node will place the new Nodes within the directory it represents. +A +File +node will place the new Nodes within its parent directory +(that is, "beside" the file in question). +If +d +is a +Dir +(directory) Node and +f +is a +File +(file) Node, +then these methods are available: + + + + + + + d.Dir(name) + +Returns a directory Node for a subdirectory of +d +named +name. + + + + + d.File(name) + +Returns a file Node for a file within +d +named +name. + + + + + d.Entry(name) + +Returns an unresolved Node within +d +named +name. + + + + + f.Dir(name) + +Returns a directory named +name +within the parent directory of +f. + + + + + f.File(name) + +Returns a file named +name +within the parent directory of +f. + + + + + f.Entry(name) + +Returns an unresolved Node named +name +within the parent directory of +f. + + + + +For example: + + +# Get a Node for a file within a directory +incl = Dir('include') +f = incl.File('header.h') + +# Get a Node for a subdirectory within a directory +dist = Dir('project-3.2.1) +src = dist.Dir('src') + +# Get a Node for a file in the same directory +cfile = File('sample.c') +hfile = cfile.File('sample.h') + +# Combined example +docs = Dir('docs') +html = docs.Dir('html') +index = html.File('index.html') +css = index.File('app.css') + + + + + +EXTENDING SCONS + +Builder Objects +scons +can be extended to build different types of targets +by adding new Builder objects +to a construction environment. +In general, +you should only need to add a new Builder object +when you want to build a new type of file or other external target. +If you just want to invoke a different compiler or other tool +to build a Program, Object, Library, or any other +type of output file for which +scons +already has an existing Builder, +it is generally much easier to +use those existing Builders +in a construction environment +that sets the appropriate construction variables +(CC, LINK, etc.). + +Builder objects are created +using the +Builder +function. +The +Builder +function accepts the following arguments: + + + + action + +The command line string used to build the target from the source. +action +can also be: +a list of strings representing the command +to be executed and its arguments +(suitable for enclosing white space in an argument), +a dictionary +mapping source file name suffixes to +any combination of command line strings +(if the builder should accept multiple source file extensions), +a Python function; +an Action object +(see the next section); +or a list of any of the above. + +An action function +takes three arguments: +source +- a list of source nodes, +target +- a list of target nodes, +env +- the construction environment. + + + + + prefix + +The prefix that will be prepended to the target file name. +This may be specified as a: + +
+ +* +string, + + +* +callable object +- a function or other callable that takes +two arguments (a construction environment and a list of sources) +and returns a prefix, + + +* +dictionary +- specifies a mapping from a specific source suffix (of the first +source specified) to a corresponding target prefix. Both the source +suffix and target prefix specifications may use environment variable +substitution, and the target prefix (the 'value' entries in the +dictionary) may also be a callable object. The default target prefix +may be indicated by a dictionary entry with a key value of None. +
+
+
+
+ + + +b = Builder("build_it < $SOURCE > $TARGET", + prefix = "file-") + +def gen_prefix(env, sources): + return "file-" + env['PLATFORM'] + '-' +b = Builder("build_it < $SOURCE > $TARGET", + prefix = gen_prefix) + +b = Builder("build_it < $SOURCE > $TARGET", + suffix = { None: "file-", + "$SRC_SFX_A": gen_prefix }) + + + + + suffix + +The suffix that will be appended to the target file name. +This may be specified in the same manner as the prefix above. +If the suffix is a string, then +scons +will append a '.' to the beginning of the suffix if it's not already +there. The string returned by callable object (or obtained from the +dictionary) is untouched and must append its own '.' to the beginning +if one is desired. + + +b = Builder("build_it < $SOURCE > $TARGET" + suffix = "-file") + +def gen_suffix(env, sources): + return "." + env['PLATFORM'] + "-file" +b = Builder("build_it < $SOURCE > $TARGET", + suffix = gen_suffix) + +b = Builder("build_it < $SOURCE > $TARGET", + suffix = { None: ".sfx1", + "$SRC_SFX_A": gen_suffix }) + + + + + + ensure_suffix + +When set to any true value, causes +scons +to add the target suffix specified by the +suffix +keyword to any target strings +that have a different suffix. +(The default behavior is to leave untouched +any target file name that looks like it already has any suffix.) + + +b1 = Builder("build_it < $SOURCE > $TARGET" + suffix = ".out") +b2 = Builder("build_it < $SOURCE > $TARGET" + suffix = ".out", + ensure_suffix) +env = Environment() +env['BUILDERS']['B1'] = b1 +env['BUILDERS']['B2'] = b2 + +# Builds "foo.txt" because ensure_suffix is not set. +env.B1('foo.txt', 'foo.in') + +# Builds "bar.txt.out" because ensure_suffix is set. +env.B2('bar.txt', 'bar.in') + + + + + + src_suffix + +The expected source file name suffix. This may be a string or a list +of strings. + + + + + target_scanner + +A Scanner object that +will be invoked to find +implicit dependencies for this target file. +This keyword argument should be used +for Scanner objects that find +implicit dependencies +based only on the target file +and the construction environment, +not +for implicit dependencies based on source files. +(See the section "Scanner Objects" below, +for information about creating Scanner objects.) + + + + + source_scanner + +A Scanner object that +will be invoked to +find implicit dependencies in +any source files +used to build this target file. +This is where you would +specify a scanner to +find things like +#include +lines in source files. +The pre-built +DirScanner +Scanner object may be used to +indicate that this Builder +should scan directory trees +for on-disk changes to files +that +scons +does not know about from other Builder or function calls. +(See the section "Scanner Objects" below, +for information about creating your own Scanner objects.) + + + + + target_factory + +A factory function that the Builder will use +to turn any targets specified as strings into SCons Nodes. +By default, +SCons assumes that all targets are files. +Other useful target_factory +values include +Dir, +for when a Builder creates a directory target, +and +Entry, +for when a Builder can create either a file +or directory target. + +Example: + + +MakeDirectoryBuilder = Builder(action=my_mkdir, target_factory=Dir) +env = Environment() +env.Append(BUILDERS = {'MakeDirectory':MakeDirectoryBuilder}) +env.MakeDirectory('new_directory', []) + + + +Note that the call to the MakeDirectory Builder +needs to specify an empty source list +to make the string represent the builder's target; +without that, it would assume the argument is the source, +and would try to deduce the target name from it, +which in the absence of an automatically-added prefix or suffix +would lead to a matching target and source name +and a circular dependency. + + + + + source_factory + +A factory function that the Builder will use +to turn any sources specified as strings into SCons Nodes. +By default, +SCons assumes that all source are files. +Other useful source_factory +values include +Dir, +for when a Builder uses a directory as a source, +and +Entry, +for when a Builder can use files +or directories (or both) as sources. + +Example: + + +CollectBuilder = Builder(action=my_mkdir, source_factory=Entry) +env = Environment() +env.Append(BUILDERS = {'Collect':CollectBuilder}) +env.Collect('archive', ['directory_name', 'file_name']) + + + + + + emitter + +A function or list of functions to manipulate the target and source +lists before dependencies are established +and the target(s) are actually built. +emitter +can also be a string containing a construction variable to expand +to an emitter function or list of functions, +or a dictionary mapping source file suffixes +to emitter functions. +(Only the suffix of the first source file +is used to select the actual emitter function +from an emitter dictionary.) + +An emitter function +takes three arguments: +source +- a list of source nodes, +target +- a list of target nodes, +env +- the construction environment. +An emitter must return a tuple containing two lists, +the list of targets to be built by this builder, +and the list of sources for this builder. + +Example: + + +def e(target, source, env): + return (target + ['foo.foo'], source + ['foo.src']) + +# Simple association of an emitter function with a Builder. +b = Builder("my_build < $TARGET > $SOURCE", + emitter = e) + +def e2(target, source, env): + return (target + ['bar.foo'], source + ['bar.src']) + +# Simple association of a list of emitter functions with a Builder. +b = Builder("my_build < $TARGET > $SOURCE", + emitter = [e, e2]) + +# Calling an emitter function through a construction variable. +env = Environment(MY_EMITTER = e) +b = Builder("my_build < $TARGET > $SOURCE", + emitter = '$MY_EMITTER') + +# Calling a list of emitter functions through a construction variable. +env = Environment(EMITTER_LIST = [e, e2]) +b = Builder("my_build < $TARGET > $SOURCE", + emitter = '$EMITTER_LIST') + +# Associating multiple emitters with different file +# suffixes using a dictionary. +def e_suf1(target, source, env): + return (target + ['another_target_file'], source) +def e_suf2(target, source, env): + return (target, source + ['another_source_file']) +b = Builder("my_build < $TARGET > $SOURCE", + emitter = {'.suf1' : e_suf1, + '.suf2' : e_suf2}) + + + + + + multi + +Specifies whether this builder is allowed to be called multiple times for +the same target file(s). The default is 0, which means the builder +can not be called multiple times for the same target file(s). Calling a +builder multiple times for the same target simply adds additional source +files to the target; it is not allowed to change the environment associated +with the target, specify addition environment overrides, or associate a different +builder with the target. + + + + + env + +A construction environment that can be used +to fetch source code using this Builder. +(Note that this environment is +not +used for normal builds of normal target files, +which use the environment that was +used to call the Builder for the target file.) + + + + + generator + +A function that returns a list of actions that will be executed to build +the target(s) from the source(s). +The returned action(s) may be +an Action object, or anything that +can be converted into an Action object +(see the next section). + +The generator function +takes four arguments: +source +- a list of source nodes, +target +- a list of target nodes, +env +- the construction environment, +for_signature +- a Boolean value that specifies +whether the generator is being called +for generating a build signature +(as opposed to actually executing the command). +Example: + + +def g(source, target, env, for_signature): + return [["gcc", "-c", "-o"] + target + source] + +b = Builder(generator=g) + + + +The +generator +and +action +arguments must not both be used for the same Builder. + + + + + src_builder + +Specifies a builder to use when a source file name suffix does not match +any of the suffixes of the builder. Using this argument produces a +multi-stage builder. + + + + + single_source + +Specifies that this builder expects exactly one source file per call. Giving +more than one source file without target files results in implicitely calling +the builder multiple times (once for each source given). Giving multiple +source files together with target files results in a UserError exception. + + + + + +The +generator +and +action +arguments must not both be used for the same Builder. + + + + source_ext_match + +When the specified +action +argument is a dictionary, +the default behavior when a builder is passed +multiple source files is to make sure that the +extensions of all the source files match. +If it is legal for this builder to be +called with a list of source files with different extensions, +this check can be suppressed by setting +source_ext_match +to +None +or some other non-true value. +When +source_ext_match +is disable, +scons +will use the suffix of the first specified +source file to select the appropriate action from the +action +dictionary. + +In the following example, +the setting of +source_ext_match +prevents +scons +from exiting with an error +due to the mismatched suffixes of +foo.in +and +foo.extra. + + +b = Builder(action={'.in' : 'build $SOURCES > $TARGET'}, + source_ext_match = None) + +env = Environment(BUILDERS = {'MyBuild':b}) +env.MyBuild('foo.out', ['foo.in', 'foo.extra']) + + + + + + env + +A construction environment that can be used +to fetch source code using this Builder. +(Note that this environment is +not +used for normal builds of normal target files, +which use the environment that was +used to call the Builder for the target file.) + + +b = Builder(action="build < $SOURCE > $TARGET") +env = Environment(BUILDERS = {'MyBuild' : b}) +env.MyBuild('foo.out', 'foo.in', my_arg = 'xyzzy') + + + + + + chdir + +A directory from which scons +will execute the +action(s) specified +for this Builder. +If the +chdir +argument is +a string or a directory Node, +scons will change to the specified directory. +If the +chdir +is not a string or Node +and is non-zero, +then scons will change to the +target file's directory. + +Note that scons will +not +automatically modify +its expansion of +construction variables like +$TARGET +and +$SOURCE +when using the chdir +keyword argument--that is, +the expanded file names +will still be relative to +the top-level SConstruct directory, +and consequently incorrect +relative to the chdir directory. +Builders created using chdir keyword argument, +will need to use construction variable +expansions like +${TARGET.file} +and +${SOURCE.file} +to use just the filename portion of the +targets and source. + + +b = Builder(action="build < ${SOURCE.file} > ${TARGET.file}", + chdir=1) +env = Environment(BUILDERS = {'MyBuild' : b}) +env.MyBuild('sub/dir/foo.out', 'sub/dir/foo.in') + + +WARNING: +Python only keeps one current directory +location for all of the threads. +This means that use of the +chdir +argument +will +not +work with the SCons + +option, +because individual worker threads spawned +by SCons interfere with each other +when they start changing directory. + + + + +Any additional keyword arguments supplied +when a Builder object is created +(that is, when the Builder() function is called) +will be set in the executing construction +environment when the Builder object is called. +The canonical example here would be +to set a construction variable to +the repository of a source code system. + +Any additional keyword arguments supplied +when a Builder +object +is called +will only be associated with the target +created by that particular Builder call +(and any other files built as a +result of the call). + +These extra keyword arguments are passed to the +following functions: +command generator functions, +function Actions, +and emitter functions. + +
+ +Action Objects + +The +Builder() +function will turn its +action +keyword argument into an appropriate +internal Action object. +You can also explicity create Action objects +using the +Action() +global function, +which can then be passed to the +Builder() +function. +This can be used to configure +an Action object more flexibly, +or it may simply be more efficient +than letting each separate Builder object +create a separate Action +when multiple +Builder objects need to do the same thing. + +The +Action() +global function +returns an appropriate object for the action +represented by the type of the first argument: + + + + Action + +If the first argument is already an Action object, +the object is simply returned. + + + + + String + +If the first argument is a string, +a command-line Action is returned. +Note that the command-line string +may be preceded by an +@ +(at-sign) +to suppress printing of the specified command line, +or by a +- +(hyphen) +to ignore the exit status from the specified command: + + +Action('$CC -c -o $TARGET $SOURCES') + +# Doesn't print the line being executed. +Action('@build $TARGET $SOURCES') + +# Ignores return value +Action('-build $TARGET $SOURCES') + + + + + + + + + + + + + + List + +If the first argument is a list, +then a list of Action objects is returned. +An Action object is created as necessary +for each element in the list. +If an element +within +the list is itself a list, +the internal list is the +command and arguments to be executed via +the command line. +This allows white space to be enclosed +in an argument by defining +a command in a list within a list: + + +Action([['cc', '-c', '-DWHITE SPACE', '-o', '$TARGET', '$SOURCES']]) + + + + + + Function + +If the first argument is a Python function, +a function Action is returned. +The Python function must take three keyword arguments, +target +(a Node object representing the target file), +source +(a Node object representing the source file) +and +env +(the construction environment +used for building the target file). +The +target +and +source +arguments may be lists of Node objects if there is +more than one target file or source file. +The actual target and source file name(s) may +be retrieved from their Node objects +via the built-in Python str() function: + + +target_file_name = str(target) +source_file_names = map(lambda x: str(x), source) + + +The function should return +0 +or +None +to indicate a successful build of the target file(s). +The function may raise an exception +or return a non-zero exit status +to indicate an unsuccessful build. + + +def build_it(target = None, source = None, env = None): + # build the target from the source + return 0 + +a = Action(build_it) + + +If the action argument is not one of the above, +None is returned. + + + + + +The second argument is optional and is used to define the output +which is printed when the Action is actually performed. +In the absence of this parameter, +or if it's an empty string, +a default output depending on the type of the action is used. +For example, a command-line action will print the executed command. +The argument must be either a Python function or a string. + +In the first case, +it's a function that returns a string to be printed +to describe the action being executed. +The function may also be specified by the +strfunction= +keyword argument. +Like a function to build a file, +this function must take three keyword arguments: +target +(a Node object representing the target file), +source +(a Node object representing the source file) +and +env +(a construction environment). +The +target +and +source +arguments may be lists of Node objects if there is +more than one target file or source file. + +In the second case, you provide the string itself. +The string may also be specified by the +cmdstr= +keyword argument. +The string typically contains variables, notably +$TARGET(S) and $SOURCE(S), or consists of just a single +variable, which is optionally defined somewhere else. +SCons itself heavily uses the latter variant. + +Examples: + + +def build_it(target, source, env): + # build the target from the source + return 0 + +def string_it(target, source, env): + return "building '%s' from '%s'" % (target[0], source[0]) + +# Use a positional argument. +f = Action(build_it, string_it) +s = Action(build_it, "building '$TARGET' from '$SOURCE'") + +# Alternatively, use a keyword argument. +f = Action(build_it, strfunction=string_it) +s = Action(build_it, cmdstr="building '$TARGET' from '$SOURCE'") + +# You can provide a configurable variable. +l = Action(build_it, '$STRINGIT') + + +The third and succeeding arguments, if present, +may either be a construction variable or a list of construction variables +whose values will be included in the signature of the Action +when deciding whether a target should be rebuilt because the action changed. +The variables may also be specified by a +varlist= +keyword parameter; +if both are present, they are combined. +This is necessary whenever you want a target to be rebuilt +when a specific construction variable changes. +This is not often needed for a string action, +as the expanded variables will normally be part of the command line, +but may be needed if a Python function action uses +the value of a construction variable when generating the command line. + + +def build_it(target, source, env): + # build the target from the 'XXX' construction variable + open(target[0], 'w').write(env['XXX']) + return 0 + +# Use positional arguments. +a = Action(build_it, '$STRINGIT', ['XXX']) + +# Alternatively, use a keyword argument. +a = Action(build_it, varlist=['XXX']) + + +The +Action() +global function +can be passed the following +optional keyword arguments +to modify the Action object's behavior: + + +chdir +The +chdir +keyword argument specifies that +scons will execute the action +after changing to the specified directory. +If the +chdir +argument is +a string or a directory Node, +scons will change to the specified directory. +If the +chdir +argument +is not a string or Node +and is non-zero, +then scons will change to the +target file's directory. + +Note that scons will +not +automatically modify +its expansion of +construction variables like +$TARGET +and +$SOURCE +when using the chdir +keyword argument--that is, +the expanded file names +will still be relative to +the top-level SConstruct directory, +and consequently incorrect +relative to the chdir directory. +Builders created using chdir keyword argument, +will need to use construction variable +expansions like +${TARGET.file} +and +${SOURCE.file} +to use just the filename portion of the +targets and source. + + +a = Action("build < ${SOURCE.file} > ${TARGET.file}", + chdir=1) + + + +exitstatfunc +The +Action() +global function +also takes an +exitstatfunc +keyword argument +which specifies a function +that is passed the exit status +(or return value) +from the specified action +and can return an arbitrary +or modified value. +This can be used, for example, +to specify that an Action object's +return value should be ignored +under special conditions +and SCons should, therefore, +consider that the action always suceeds: + + +def always_succeed(s): + # Always return 0, which indicates success. + return 0 +a = Action("build < ${SOURCE.file} > ${TARGET.file}", + exitstatfunc=always_succeed) + + + +batch_key +The +batch_key +keyword argument can be used +to specify that the Action can create multiple target files +by processing multiple independent source files simultaneously. +(The canonical example is "batch compilation" +of multiple object files +by passing multiple source files +to a single invocation of a compiler +such as Microsoft's Visual C / C++ compiler.) +If the +batch_key +argument is any non-False, non-callable Python value, +the configured Action object will cause +scons +to collect all targets built with the Action object +and configured with the same construction environment +into single invocations of the Action object's +command line or function. +Command lines will typically want to use the +CHANGED_SOURCES +construction variable +(and possibly +CHANGED_TARGETS +as well) +to only pass to the command line those sources that +have actually changed since their targets were built. + +Example: + + +a = Action('build $CHANGED_SOURCES', batch_key=True) + + +The +batch_key +argument may also be +a callable function +that returns a key that +will be used to identify different +"batches" of target files to be collected +for batch building. +A +batch_key +function must take the following arguments: + + + + action + +The action object. + + + + + env + +The construction environment +configured for the target. + + + + + target + +The list of targets for a particular configured action. + + + + + source + +The list of source for a particular configured action. + +The returned key should typically +be a tuple of values derived from the arguments, +using any appropriate logic to decide +how multiple invocations should be batched. +For example, a +batch_key +function may decide to return +the value of a specific construction +variable from the +env +argument +which will cause +scons +to batch-build targets +with matching values of that variable, +or perhaps return the +id() +of the entire construction environment, +in which case +scons +will batch-build +all targets configured with the same construction environment. +Returning +None +indicates that +the particular target should +not +be part of any batched build, +but instead will be built +by a separate invocation of action's +command or function. +Example: + + +def batch_key(action, env, target, source): + tdir = target[0].dir + if tdir.name == 'special': + # Don't batch-build any target + # in the special/ subdirectory. + return None + return (id(action), id(env), tdir) +a = Action('build $CHANGED_SOURCES', batch_key=batch_key) + + + + + + + +Miscellaneous Action Functions + +scons +supplies a number of functions +that arrange for various common +file and directory manipulations +to be performed. +These are similar in concept to "tasks" in the +Ant build tool, +although the implementation is slightly different. +These functions do not actually +perform the specified action +at the time the function is called, +but instead return an Action object +that can be executed at the +appropriate time. +(In Object-Oriented terminology, +these are actually +Action +Factory +functions +that return Action objects.) + +In practice, +there are two natural ways +that these +Action Functions +are intended to be used. + +First, +if you need +to perform the action +at the time the SConscript +file is being read, +you can use the +Execute +global function to do so: + +Execute(Touch('file')) + + +Second, +you can use these functions +to supply Actions in a list +for use by the +Command +method. +This can allow you to +perform more complicated +sequences of file manipulation +without relying +on platform-specific +external commands: +that + +env = Environment(TMPBUILD = '/tmp/builddir') +env.Command('foo.out', 'foo.in', + [Mkdir('$TMPBUILD'), + Copy('$TMPBUILD', '${SOURCE.dir}'), + "cd $TMPBUILD && make", + Delete('$TMPBUILD')]) + + + + + Chmod(dest, mode) + +Returns an Action object that +changes the permissions on the specified +dest +file or directory to the specified +mode. +Examples: + + +Execute(Chmod('file', 0755)) + +env.Command('foo.out', 'foo.in', + [Copy('$TARGET', '$SOURCE'), + Chmod('$TARGET', 0755)]) + + + + + + Copy(dest, src) + +Returns an Action object +that will copy the +src +source file or directory to the +dest +destination file or directory. +Examples: + + +Execute(Copy('foo.output', 'foo.input')) + +env.Command('bar.out', 'bar.in', + Copy('$TARGET', '$SOURCE')) + + + + + + Delete(entry, [must_exist]) + +Returns an Action that +deletes the specified +entry, +which may be a file or a directory tree. +If a directory is specified, +the entire directory tree +will be removed. +If the +must_exist +flag is set, +then a Python error will be thrown +if the specified entry does not exist; +the default is +must_exist=0, +that is, the Action will silently do nothing +if the entry does not exist. +Examples: + + +Execute(Delete('/tmp/buildroot')) + +env.Command('foo.out', 'foo.in', + [Delete('${TARGET.dir}'), + MyBuildAction]) + +Execute(Delete('file_that_must_exist', must_exist=1)) + + + + + + Mkdir(dir) + +Returns an Action +that creates the specified +directory +dir . +Examples: + + +Execute(Mkdir('/tmp/outputdir')) + +env.Command('foo.out', 'foo.in', + [Mkdir('/tmp/builddir'), + Copy('/tmp/builddir/foo.in', '$SOURCE'), + "cd /tmp/builddir && make", + Copy('$TARGET', '/tmp/builddir/foo.out')]) + + + + + + Move(dest, src) + +Returns an Action +that moves the specified +src +file or directory to +the specified +dest +file or directory. +Examples: + + +Execute(Move('file.destination', 'file.source')) + +env.Command('output_file', 'input_file', + [MyBuildAction, + Move('$TARGET', 'file_created_by_MyBuildAction')]) + + + + + + Touch(file) + +Returns an Action +that updates the modification time +on the specified +file. +Examples: + + +Execute(Touch('file_to_be_touched')) + +env.Command('marker', 'input_file', + [MyBuildAction, + Touch('$TARGET')]) + + + + + + + +Variable Substitution + +Before executing a command, +scons +performs construction variable interpolation on the strings that make up +the command line of builders. +Variables are introduced by a +$ +prefix. +Besides construction variables, scons provides the following +variables for each command execution: + + + + CHANGED_SOURCES + +The file names of all sources of the build command +that have changed since the target was last built. + + + + + CHANGED_TARGETS + +The file names of all targets that would be built +from sources that have changed since the target was last built. + + + + + SOURCE + +The file name of the source of the build command, +or the file name of the first source +if multiple sources are being built. + + + + + SOURCES + +The file names of the sources of the build command. + + + + + TARGET + +The file name of the target being built, +or the file name of the first target +if multiple targets are being built. + + + + + TARGETS + +The file names of all targets being built. + + + + + UNCHANGED_SOURCES + +The file names of all sources of the build command +that have +not +changed since the target was last built. + + + + + UNCHANGED_TARGETS + +The file names of all targets that would be built +from sources that have +not +changed since the target was last built. + +(Note that the above variables are reserved +and may not be set in a construction environment.) + + + + + +For example, given the construction variable CC='cc', targets=['foo'], and +sources=['foo.c', 'bar.c']: + + +action='$CC -c -o $TARGET $SOURCES' + + +would produce the command line: + + +cc -c -o foo foo.c bar.c + + +Variable names may be surrounded by curly braces ({}) +to separate the name from the trailing characters. +Within the curly braces, a variable name may have +a Python slice subscript appended to select one +or more items from a list. +In the previous example, the string: + + +${SOURCES[1]} + + +would produce: + + +bar.c + + +Additionally, a variable name may +have the following special +modifiers appended within the enclosing curly braces +to modify the interpolated string: + + + + base + +The base path of the file name, +including the directory path +but excluding any suffix. + + + + + dir + +The name of the directory in which the file exists. + + + + + file + +The file name, +minus any directory portion. + + + + + filebase + +Just the basename of the file, +minus any suffix +and minus the directory. + + + + + suffix + +Just the file suffix. + + + + + abspath + +The absolute path name of the file. + + + + + posix + +The POSIX form of the path, +with directories separated by +/ +(forward slashes) +not backslashes. +This is sometimes necessary on Windows systems +when a path references a file on other (POSIX) systems. + + + + + srcpath + +The directory and file name to the source file linked to this file through +VariantDir(). +If this file isn't linked, +it just returns the directory and filename unchanged. + + + + + srcdir + +The directory containing the source file linked to this file through +VariantDir(). +If this file isn't linked, +it just returns the directory part of the filename. + + + + + rsrcpath + +The directory and file name to the source file linked to this file through +VariantDir(). +If the file does not exist locally but exists in a Repository, +the path in the Repository is returned. +If this file isn't linked, it just returns the +directory and filename unchanged. + + + + + rsrcdir + +The Repository directory containing the source file linked to this file through +VariantDir(). +If this file isn't linked, +it just returns the directory part of the filename. + + + + + +For example, the specified target will +expand as follows for the corresponding modifiers: + + +$TARGET => sub/dir/file.x +${TARGET.base} => sub/dir/file +${TARGET.dir} => sub/dir +${TARGET.file} => file.x +${TARGET.filebase} => file +${TARGET.suffix} => .x +${TARGET.abspath} => /top/dir/sub/dir/file.x + +SConscript('src/SConscript', variant_dir='sub/dir') +$SOURCE => sub/dir/file.x +${SOURCE.srcpath} => src/file.x +${SOURCE.srcdir} => src + +Repository('/usr/repository') +$SOURCE => sub/dir/file.x +${SOURCE.rsrcpath} => /usr/repository/src/file.x +${SOURCE.rsrcdir} => /usr/repository/src + + +Note that curly braces braces may also be used +to enclose arbitrary Python code to be evaluated. +(In fact, this is how the above modifiers are substituted, +they are simply attributes of the Python objects +that represent TARGET, SOURCES, etc.) +See the section "Python Code Substitution" below, +for more thorough examples of +how this can be used. + +Lastly, a variable name +may be a callable Python function +associated with a +construction variable in the environment. +The function should +take four arguments: +target +- a list of target nodes, +source +- a list of source nodes, +env +- the construction environment, +for_signature +- a Boolean value that specifies +whether the function is being called +for generating a build signature. +SCons will insert whatever +the called function returns +into the expanded string: + + +def foo(target, source, env, for_signature): + return "bar" + +# Will expand $BAR to "bar baz" +env=Environment(FOO=foo, BAR="$FOO baz") + + +You can use this feature to pass arguments to a +Python function by creating a callable class +that stores one or more arguments in an object, +and then uses them when the +__call__() +method is called. +Note that in this case, +the entire variable expansion must +be enclosed by curly braces +so that the arguments will +be associated with the +instantiation of the class: + + +class foo(object): + def __init__(self, arg): + self.arg = arg + + def __call__(self, target, source, env, for_signature): + return self.arg + " bar" + +# Will expand $BAR to "my argument bar baz" +env=Environment(FOO=foo, BAR="${FOO('my argument')} baz") + + + +The special pseudo-variables +$( +and +$) +may be used to surround parts of a command line +that may change +without +causing a rebuild--that is, +which are not included in the signature +of target files built with this command. +All text between +$( +and +$) +will be removed from the command line +before it is added to file signatures, +and the +$( +and +$) +will be removed before the command is executed. +For example, the command line: + + +echo Last build occurred $( $TODAY $). > $TARGET + + + +would execute the command: + + +echo Last build occurred $TODAY. > $TARGET + + + +but the command signature added to any target files would be: + + +echo Last build occurred . > $TARGET + + + + +Python Code Substitution + +Any python code within +${-} +pairs gets evaluated by python 'eval', with the python globals set to +the current environment's set of construction variables. +So in the following case: + +env['COND'] = 0 +env.Command('foo.out', 'foo.in', + + +the command executed will be either + +echo FOO > foo.out + +or + +echo BAR > foo.out + +according to the current value of env['COND'] when the command is +executed. The evaluation occurs when the target is being +built, not when the SConscript is being read. So if env['COND'] is changed +later in the SConscript, the final value will be used. + +Here's a more interesting example. Note that all of COND, FOO, and +BAR are environment variables, and their values are substituted into +the final command. FOO is a list, so its elements are interpolated +separated by spaces. + + +env=Environment() +env['COND'] = 0 +env['FOO'] = ['foo1', 'foo2'] +env['BAR'] = 'barbar' +env.Command('foo.out', 'foo.in', + 'echo ${COND==1 and FOO or BAR} > $TARGET') + +# Will execute this: +# echo foo1 foo2 > foo.out + + +SCons uses the following rules when converting construction variables into +command lines: + + + + String + +When the value is a string it is interpreted as a space delimited list of +command line arguments. + + + + + List + +When the value is a list it is interpreted as a list of command line +arguments. Each element of the list is converted to a string. + + + + + Other + +Anything that is not a list or string is converted to a string and +interpreted as a single command line argument. + + + + + Newline + +Newline characters (\n) delimit lines. The newline parsing is done after +all other parsing, so it is not possible for arguments (e.g. file names) to +contain embedded newline characters. This limitation will likely go away in +a future version of SCons. + + + + + + +Scanner Objects + +You can use the +Scanner +function to define +objects to scan +new file types for implicit dependencies. +The +Scanner +function accepts the following arguments: + + + + function + +This can be either: +1) a Python function that will process +the Node (file) +and return a list of File Nodes +representing the implicit +dependencies (file names) found in the contents; +or: +2) a dictionary that maps keys +(typically the file suffix, but see below for more discussion) +to other Scanners that should be called. + +If the argument is actually a Python function, +the function must take three or four arguments: + + def scanner_function(node, env, path): + + def scanner_function(node, env, path, arg=None): + +The +node +argument is the internal +SCons node representing the file. +Use +str(node) +to fetch the name of the file, and +node.get_contents() +to fetch contents of the file. +Note that the file is +not +guaranteed to exist before the scanner is called, +so the scanner function should check that +if there's any chance that the scanned file +might not exist +(for example, if it's built from other files). + +The +env +argument is the construction environment for the scan. +Fetch values from it using the +env.Dictionary() +method. + +The +path +argument is a tuple (or list) +of directories that can be searched +for files. +This will usually be the tuple returned by the +path_function +argument (see below). + +The +arg +argument is the argument supplied +when the scanner was created, if any. + + + + + name + +The name of the Scanner. +This is mainly used +to identify the Scanner internally. + + + + + argument + +An optional argument that, if specified, +will be passed to the scanner function +(described above) +and the path function +(specified below). + + + + + skeys + +An optional list that can be used to +determine which scanner should be used for +a given Node. +In the usual case of scanning for file names, +this argument will be a list of suffixes +for the different file types that this +Scanner knows how to scan. +If the argument is a string, +then it will be expanded +into a list by the current environment. + + + + + path_function + +A Python function that takes four or five arguments: +a construction environment, +a Node for the directory containing +the SConscript file in which +the first target was defined, +a list of target nodes, +a list of source nodes, +and an optional argument supplied +when the scanner was created. +The +path_function +returns a tuple of directories +that can be searched for files to be returned +by this Scanner object. +(Note that the +FindPathDirs() +function can be used to return a ready-made +path_function +for a given construction variable name, +instead of having to write your own function from scratch.) + + + + + node_class + +The class of Node that should be returned +by this Scanner object. +Any strings or other objects returned +by the scanner function +that are not of this class +will be run through the +node_factory +function. + + + + + node_factory + +A Python function that will take a string +or other object +and turn it into the appropriate class of Node +to be returned by this Scanner object. + + + + + scan_check + +An optional Python function that takes two arguments, +a Node (file) and a construction environment, +and returns whether the +Node should, in fact, +be scanned for dependencies. +This check can be used to eliminate unnecessary +calls to the scanner function when, +for example, the underlying file +represented by a Node does not yet exist. + + + + + recursive + +An optional flag that +specifies whether this scanner should be re-invoked +on the dependency files returned by the scanner. +When this flag is not set, +the Node subsystem will +only invoke the scanner on the file being scanned, +and not (for example) also on the files +specified by the #include lines +in the file being scanned. +recursive +may be a callable function, +in which case it will be called with a list of +Nodes found and +should return a list of Nodes +that should be scanned recursively; +this can be used to select a specific subset of +Nodes for additional scanning. + + + + +Note that +scons +has a global +SourceFileScanner +object that is used by +the +Object(), +SharedObject(), +and +StaticObject() +builders to decide +which scanner should be used +for different file extensions. +You can using the +SourceFileScanner.add_scanner() +method to add your own Scanner object +to the +scons +infrastructure +that builds target programs or +libraries from a list of +source files of different types: + + +def xyz_scan(node, env, path): + contents = node.get_text_contents() + # Scan the contents and return the included files. + +XYZScanner = Scanner(xyz_scan) + +SourceFileScanner.add_scanner('.xyz', XYZScanner) + +env.Program('my_prog', ['file1.c', 'file2.f', 'file3.xyz']) + + + +
+ +SYSTEM-SPECIFIC BEHAVIOR +SCons and its configuration files are very portable, +due largely to its implementation in Python. +There are, however, a few portability +issues waiting to trap the unwary. + +.C file suffix +SCons handles the upper-case +.C +file suffix differently, +depending on the capabilities of +the underlying system. +On a case-sensitive system +such as Linux or UNIX, +SCons treats a file with a +.C +suffix as a C++ source file. +On a case-insensitive system +such as Windows, +SCons treats a file with a +.C +suffix as a C source file. + + +.F file suffix +SCons handles the upper-case +.F +file suffix differently, +depending on the capabilities of +the underlying system. +On a case-sensitive system +such as Linux or UNIX, +SCons treats a file with a +.F +suffix as a Fortran source file +that is to be first run through +the standard C preprocessor. +On a case-insensitive system +such as Windows, +SCons treats a file with a +.F +suffix as a Fortran source file that should +not +be run through the C preprocessor. + + +Windows: Cygwin Tools and Cygwin Python vs. Windows Pythons +Cygwin supplies a set of tools and utilities +that let users work on a +Windows system using a more POSIX-like environment. +The Cygwin tools, including Cygwin Python, +do this, in part, +by sharing an ability to interpret UNIX-like path names. +For example, the Cygwin tools +will internally translate a Cygwin path name +like /cygdrive/c/mydir +to an equivalent Windows pathname +of C:/mydir (equivalent to C:\mydir). + +Versions of Python +that are built for native Windows execution, +such as the python.org and ActiveState versions, +do not have the Cygwin path name semantics. +This means that using a native Windows version of Python +to build compiled programs using Cygwin tools +(such as gcc, bison, and flex) +may yield unpredictable results. +"Mixing and matching" in this way +can be made to work, +but it requires careful attention to the use of path names +in your SConscript files. + +In practice, users can sidestep +the issue by adopting the following rules: +When using gcc, +use the Cygwin-supplied Python interpreter +to run SCons; +when using Microsoft Visual C/C++ +(or some other Windows compiler) +use the python.org or ActiveState version of Python +to run SCons. + + +Windows: scons.bat file +On Windows systems, +SCons is executed via a wrapper +scons.bat +file. +This has (at least) two ramifications: + +First, Windows command-line users +that want to use variable assignment +on the command line +may have to put double quotes +around the assignments: + + +scons "FOO=BAR" "BAZ=BLEH" + + +Second, the Cygwin shell does not +recognize this file as being the same +as an +scons +command issued at the command-line prompt. +You can work around this either by +executing +scons.bat +from the Cygwin command line, +or by creating a wrapper shell +script named +scons . + + + +MinGW + +The MinGW bin directory must be in your PATH environment variable or the +PATH variable under the ENV construction variable for SCons +to detect and use the MinGW tools. When running under the native Windows +Python interpreter, SCons will prefer the MinGW tools over the Cygwin +tools, if they are both installed, regardless of the order of the bin +directories in the PATH variable. If you have both MSVC and MinGW +installed and you want to use MinGW instead of MSVC, +then you must explicitly tell SCons to use MinGW by passing + + +tools=['mingw'] + + +to the Environment() function, because SCons will prefer the MSVC tools +over the MinGW tools. + + + + +EXAMPLES +To help you get started using SCons, +this section contains a brief overview of some common tasks. + + +Basic Compilation From a Single Source File + + +env = Environment() +env.Program(target = 'foo', source = 'foo.c') + + +Note: Build the file by specifying +the target as an argument +("scons foo" or "scons foo.exe"). +or by specifying a dot ("scons ."). + + + +Basic Compilation From Multiple Source Files + + +env = Environment() +env.Program(target = 'foo', source = Split('f1.c f2.c f3.c')) + + + + +Setting a Compilation Flag + + +env = Environment(CCFLAGS = '-g') +env.Program(target = 'foo', source = 'foo.c') + + + + +Search The Local Directory For .h Files + +Note: You do +not +need to set CCFLAGS to specify -I options by hand. +SCons will construct the right -I options from CPPPATH. + + +env = Environment(CPPPATH = ['.']) +env.Program(target = 'foo', source = 'foo.c') + + + + +Search Multiple Directories For .h Files + + +env = Environment(CPPPATH = ['include1', 'include2']) +env.Program(target = 'foo', source = 'foo.c') + + + + +Building a Static Library + + +env = Environment() +env.StaticLibrary(target = 'foo', source = Split('l1.c l2.c')) +env.StaticLibrary(target = 'bar', source = ['l3.c', 'l4.c']) + + + + +Building a Shared Library + + +env = Environment() +env.SharedLibrary(target = 'foo', source = ['l5.c', 'l6.c']) +env.SharedLibrary(target = 'bar', source = Split('l7.c l8.c')) + + + + +Linking a Local Library Into a Program + + +env = Environment(LIBS = 'mylib', LIBPATH = ['.']) +env.Library(target = 'mylib', source = Split('l1.c l2.c')) +env.Program(target = 'prog', source = ['p1.c', 'p2.c']) + + + + +Defining Your Own Builder Object + +Notice that when you invoke the Builder, +you can leave off the target file suffix, +and SCons will add it automatically. + + +bld = Builder(action = 'pdftex < $SOURCES > $TARGET' + suffix = '.pdf', + src_suffix = '.tex') +env = Environment(BUILDERS = {'PDFBuilder' : bld}) +env.PDFBuilder(target = 'foo.pdf', source = 'foo.tex') + +# The following creates "bar.pdf" from "bar.tex" +env.PDFBuilder(target = 'bar', source = 'bar') + + +Note also that the above initialization +overwrites the default Builder objects, +so the Environment created above +can not be used call Builders like env.Program(), +env.Object(), env.StaticLibrary(), etc. + + + +Adding Your Own Builder Object to an Environment + + +bld = Builder(action = 'pdftex < $SOURCES > $TARGET' + suffix = '.pdf', + src_suffix = '.tex') +env = Environment() +env.Append(BUILDERS = {'PDFBuilder' : bld}) +env.PDFBuilder(target = 'foo.pdf', source = 'foo.tex') +env.Program(target = 'bar', source = 'bar.c') + + +You also can use other Pythonic techniques to add +to the BUILDERS construction variable, such as: + + +env = Environment() +env['BUILDERS]['PDFBuilder'] = bld + + + + +Defining Your Own Scanner Object + +The following example shows an extremely simple scanner (the +kfile_scan() +function) +that doesn't use a search path at all +and simply returns the +file names present on any +include +lines in the scanned file. +This would implicitly assume that all included +files live in the top-level directory: + + +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) + +def kfile_scan(node, env, path, arg): + contents = node.get_text_contents() + includes = include_re.findall(contents) + return env.File(includes) + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + argument = None, + skeys = ['.k']) +scanners = Environment().Dictionary('SCANNERS') +env = Environment(SCANNERS = scanners + [kscan]) + +env.Command('foo', 'foo.k', 'kprocess < $SOURCES > $TARGET') + +bar_in = File('bar.in') +env.Command('bar', bar_in, 'kprocess $SOURCES > $TARGET') +bar_in.target_scanner = kscan + + +It is important to note that you +have to return a list of File nodes from the scan function, simple +strings for the file names won't do. As in the examples we are showing here, +you can use the +File() +function of your current Environment in order to create nodes on the fly from +a sequence of file names with relative paths. + +Here is a similar but more complete example that searches +a path of directories +(specified as the +MYPATH +construction variable) +for files that actually exist: + + +import re +import os +include_re = re.compile(r'^include\s+(\S+)$', re.M) + +def my_scan(node, env, path, arg): + contents = node.get_text_contents() + includes = include_re.findall(contents) + if includes == []: + return [] + results = [] + for inc in includes: + for dir in path: + file = str(dir) + os.sep + inc + if os.path.exists(file): + results.append(file) + break + return env.File(results) + +scanner = Scanner(name = 'myscanner', + function = my_scan, + argument = None, + skeys = ['.x'], + path_function = FindPathDirs('MYPATH') + ) +scanners = Environment().Dictionary('SCANNERS') +env = Environment(SCANNERS = scanners + [scanner], + MYPATH = ['incs']) + +env.Command('foo', 'foo.x', 'xprocess < $SOURCES > $TARGET') + + +The +FindPathDirs() +function used in the previous example returns a function +(actually a callable Python object) +that will return a list of directories +specified in the +$MYPATH +construction variable. It lets SCons detect the file +incs/foo.inc +, even if +foo.x +contains the line +include foo.inc +only. +If you need to customize how the search path is derived, +you would provide your own +path_function +argument when creating the Scanner object, +as follows: + + +# MYPATH is a list of directories to search for files in +def pf(env, dir, target, source, arg): + top_dir = Dir('#').abspath + results = [] + if 'MYPATH' in env: + for p in env['MYPATH']: + results.append(top_dir + os.sep + p) + return results + +scanner = Scanner(name = 'myscanner', + function = my_scan, + argument = None, + skeys = ['.x'], + path_function = pf + ) + + + + +Creating a Hierarchical Build + +Notice that the file names specified in a subdirectory's +SConscript +file are relative to that subdirectory. + + +SConstruct: + + env = Environment() + env.Program(target = 'foo', source = 'foo.c') + + SConscript('sub/SConscript') + +sub/SConscript: + + env = Environment() + # Builds sub/foo from sub/foo.c + env.Program(target = 'foo', source = 'foo.c') + + SConscript('dir/SConscript') + +sub/dir/SConscript: + + env = Environment() + # Builds sub/dir/foo from sub/dir/foo.c + env.Program(target = 'foo', source = 'foo.c') + + + + +Sharing Variables Between SConscript Files + +You must explicitly Export() and Import() variables that +you want to share between SConscript files. + + +SConstruct: + + env = Environment() + env.Program(target = 'foo', source = 'foo.c') + + Export("env") + SConscript('subdirectory/SConscript') + +subdirectory/SConscript: + + Import("env") + env.Program(target = 'foo', source = 'foo.c') + + + + +Building Multiple Variants From the Same Source + +Use the variant_dir keyword argument to +the SConscript function to establish +one or more separate variant build directory trees +for a given source directory: + + +SConstruct: + + cppdefines = ['FOO'] + Export("cppdefines") + SConscript('src/SConscript', variant_dir='foo') + + cppdefines = ['BAR'] + Export("cppdefines") + SConscript('src/SConscript', variant_dir='bar') + +src/SConscript: + + Import("cppdefines") + env = Environment(CPPDEFINES = cppdefines) + env.Program(target = 'src', source = 'src.c') + + +Note the use of the Export() method +to set the "cppdefines" variable to a different +value each time we call the SConscript function. + + + +Hierarchical Build of Two Libraries Linked With a Program + + +SConstruct: + + env = Environment(LIBPATH = ['#libA', '#libB']) + Export('env') + SConscript('libA/SConscript') + SConscript('libB/SConscript') + SConscript('Main/SConscript') + +libA/SConscript: + + Import('env') + env.Library('a', Split('a1.c a2.c a3.c')) + +libB/SConscript: + + Import('env') + env.Library('b', Split('b1.c b2.c b3.c')) + +Main/SConscript: + + Import('env') + e = env.Copy(LIBS = ['a', 'b']) + e.Program('foo', Split('m1.c m2.c m3.c')) + + +The '#' in the LIBPATH directories specify that they're relative to the +top-level directory, so they don't turn into "Main/libA" when they're +used in Main/SConscript. + +Specifying only 'a' and 'b' for the library names +allows SCons to append the appropriate library +prefix and suffix for the current platform +(for example, 'liba.a' on POSIX systems, +'a.lib' on Windows). + + + +Customizing construction variables from the command line. + +The following would allow the C compiler to be specified on the command +line or in the file custom.py. + + +vars = Variables('custom.py') +vars.Add('CC', 'The C compiler.') +env = Environment(variables=vars) +Help(vars.GenerateHelpText(env)) + + +The user could specify the C compiler on the command line: + + +scons "CC=my_cc" + + +or in the custom.py file: + + +CC = 'my_cc' + + +or get documentation on the options: + + +$ scons -h + +CC: The C compiler. + default: None + actual: cc + + + + + +Using Microsoft Visual C++ precompiled headers + +Since windows.h includes everything and the kitchen sink, it can take quite +some time to compile it over and over again for a bunch of object files, so +Microsoft provides a mechanism to compile a set of headers once and then +include the previously compiled headers in any object file. This +technology is called precompiled headers. The general recipe is to create a +file named "StdAfx.cpp" that includes a single header named "StdAfx.h", and +then include every header you want to precompile in "StdAfx.h", and finally +include "StdAfx.h" as the first header in all the source files you are +compiling to object files. For example: + +StdAfx.h: + +#include <windows.h> +#include <my_big_header.h> + + +StdAfx.cpp: + +#include <StdAfx.h> + + +Foo.cpp: + +#include <StdAfx.h> + +/* do some stuff */ + + +Bar.cpp: + +#include <StdAfx.h> + +/* do some other stuff */ + + +SConstruct: + +env=Environment() +env['PCHSTOP'] = 'StdAfx.h' +env['PCH'] = env.PCH('StdAfx.cpp')[0] +env.Program('MyApp', ['Foo.cpp', 'Bar.cpp']) + + +For more information see the document for the PCH builder, and the PCH and +PCHSTOP construction variables. To learn about the details of precompiled +headers consult the MSDN documention for /Yc, /Yu, and /Yp. + + + +Using Microsoft Visual C++ external debugging information + +Since including debugging information in programs and shared libraries can +cause their size to increase significantly, Microsoft provides a mechanism +for including the debugging information in an external file called a PDB +file. SCons supports PDB files through the PDB construction +variable. + +SConstruct: + +env=Environment() +env['PDB'] = 'MyApp.pdb' +env.Program('MyApp', ['Foo.cpp', 'Bar.cpp']) + + +For more information see the document for the PDB construction variable. + + + + +ENVIRONMENT + + + SCONS_LIB_DIR + +Specifies the directory that contains the SCons Python module directory +(e.g. /home/aroach/scons-src-0.01/src/engine). + + + + + SCONSFLAGS + +A string of options that will be used by scons in addition to those passed +on the command line. + + + + + + +SEE ALSO +scons +User Manual, +scons +Design Document, +scons +source code. + + + +AUTHORS +Steven Knight <knight@baldmt.com> + +Anthony Roach <aroach@electriceyeball.com> + +
+
-- cgit v1.2.3