or
.I sconstruct
(in that order) in the current directory and reads its
-configuration from the first file found. An alternate file name may be
+configuration from the first file found.
+An alternate file name may be
specified via the
.B -f
option. If the specified file is not
will internally change its working
directory (chdir) to the directory containing the file.
-The configuration file specifies the files to be built, and
-(optionally) the rules to build those files. Reasonable default
+The configuration files
+(generically referred to as
+.I SConscript
+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 simple software
+programs, object files, libraries), so that for most software
projects, only the target and input files need be specified.
+.B 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.
+.BR scons ,
+however, reads all of the SConscript files
+.I before
+it begins building any targets.
+To make this obvious,
+.B scons
+prints the following messages about what it is doing:
+
+.ES
+$ scons foo.out
+scons: Reading SConscript files ...
+scons: done reading SConscript files.
+scons: Building targets ...
+cp foo.in foo.out
+scons: done building targets.
+$
+.EE
+
+These status messages may be suppressed using the
+.B -Q
+option.
+
.B scons
can scan known input files automatically for dependency
information (for example, #include statements
Targets may be omitted from the command line,
in which case the targets specified
-in the configuration file(s) as
+in the SConscript file(s) as
.B Default
targets will be built:
scons
.EE
-Specifying "cleanup" targets in configuration files is not
+Specifying "cleanup" targets in SConscript files is not
necessary. The
.B -c
flag removes all files
builds four targets in parallel, for example.
-Values of variables to be passed to the configuration file(s)
+Values of variables to be passed to the SConscript file(s)
may be specified on the command line:
.ES
These variables are available in SConscript files
through the ARGUMENTS dictionary,
-and can be used in the configuration file(s) to modify
+and can be used in the SConscript file(s) to modify
the build in any way:
.ES
.\" .B scons
.\" can maintain a cache of target (derived) files that can
.\" be shared between multiple builds. When caching is enabled in a
-.\" configuration file, any target files built by
+.\" SConscript file, any target files built by
.\" .B scons
.\" will be copied
.\" to the cache. If an up-to-date target file is found in the cache, it
.\" --cache-disable, --no-cache
.\" Disable caching. Will neither retrieve files from cache nor flush
.\" files to cache. Has no effect if use of caching is not specified
-.\" in a configuration file.
+.\" in an SConscript file.
.\"
.\" .TP
.\" --cache-force, --cache-populate
.TP
-e, --environment-overrides
Variables from the execution environment override construction
-variables from the configuration files.
+variables from the SConscript files.
.TP
.RI -f " file" ", --file=" file ", --makefile=" file ", --sconstruct=" file
Use
.I file
-as the initial configuration
-file. If
+as the initial SConscript file.
+If
.I file
is in another directory,
.B scons
.TP
-h, --help
Print a local help message for this build, if one is defined in
-the configuration file(s), plus a line that describes the
+the SConscript file(s), plus a line that describes the
.B -H
option for command-line option help. If no local help message
is defined, prints the standard help message about command-line
.\" -p
.\" Print the data base (construction environments,
.\" Builder and Scanner objects) that are defined
-.\" after reading the configuration files.
+.\" after reading the SConscript files.
.\" After printing, a normal build is performed
.\" as usual, as specified by other command-line options.
.\" This also prints version information
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.
+.TP
+-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.
.\" .TP
.\" -r, -R, --no-builtin-rules, --no-builtin-variables
-s, --silent, --quiet
Silent. Do not print commands that are executed to rebuild
target files.
+Also suppresses SCons status messages.
.TP
-S, --no-keep-going, --stop
.\" .SS Python Basics
.\" XXX Adding this in the future would be a help.
.SS Construction Environments
-A construction environment is the basic means by which the configuration
+A construction environment is the basic means by which the SConscript
files communicate build information to
.BR scons .
A new construction environment is created using the
compiler.
.B scons
provides a mechanism for overridding construction variables from the
-command line or a text based configuration file through an Options
+command line or a text-based SConscript file through an Options
object. To create an Options object, call the Options() function:
.TP
Help(opts.GenerateHelpText(env))
.EE
-The text based configuration file is executed as a Python script, and the
+The text based SConscript file is executed as a Python script, and the
global variables are queried for customizable construction
variables. Example:
.B scons
also provides various additional functions,
not associated with a construction environment,
-that configuration files can use:
+that SConscript files can use:
.TP
.RI BuildDir( build_dir ", " src_dir ", [" duplicate ])
This tells
.B scons
to export a list of variables from the current
-configuration file to all other configuration files. The exported variables
+SConscript file to all other SConscript files. The exported variables
are kept in a global collection, so subsequent exports
will over-write previous exports that have the same name.
Multiple variable names should be passed to
.RI Import( vars )
This tells
.B scons
-to import a list of variables into the current configuration file. This
+to import a list of variables into the current SConscript file. This
will import variables that were exported with
.BR Export ()
or in the
.RI Return( vars )
This tells
.B scons
-what variable(s) to use as the return value(s) of the current configuration
-file. These variables will be returned to the "calling" configuration file
+what variable(s) to use as the return value(s) of the current SConscript
+file. These variables will be returned to the "calling" SConscript file
as the return value(s) of
.BR SConscript ().
Multiple variable names should be passed to
.B scons
to execute
.I script
-as a configuration file. The optional
+as a SConscript (configuration) file. The optional
.I exports
argument provides a list of variable names to export to
.IR script ". "
.B scons
to change its working directory (chdir)
to the directory in which each subsidiary
-configure (SConscript) file lives.
+SConscript file lives.
Note that you may enable and disable
this ability by calling
SConscriptChdir()
def execute(self):
if self.targets[0].get_state() == SCons.Node.up_to_date:
if self.top:
- print 'scons: "%s" is up to date.' % str(self.targets[0])
+ display('scons: "%s" is up to date.' % str(self.targets[0]))
else:
try:
self.targets[0].prepare()
"""An SCons clean task."""
def show(self):
if self.targets[0].builder or self.targets[0].side_effect:
- print "Removed " + str(self.targets[0])
+ display("Removed " + str(self.targets[0]))
def remove(self):
if self.targets[0].builder or self.targets[0].side_effect:
print "scons: Could not remove '%s':" % str(t), e.strerror
else:
if removed:
- print "Removed " + str(t)
+ display("Removed " + str(t))
execute = remove
max_drift = None
repositories = []
+#
+def print_it(text):
+ print text
+
+display = print_it
+
# Exceptions for this module
class PrintHelp(Exception):
pass
Option(func = opt_implicit_cache,
long = ['implicit-cache'],
- help = "Cache implicit dependencies")
+ help = "Cache implicit (scanned) dependencies.")
def opt_implicit_deps_changed(opt, arg):
import SCons.Node
Option(func = opt_implicit_deps_changed,
long = ['implicit-deps-changed'],
- help = "Ignore the cached implicit deps.")
+ help = "Ignore the cached implicit dependencies.")
def opt_implicit_deps_unchanged(opt, arg):
import SCons.Node
Option(func = opt_implicit_deps_unchanged,
long = ['implicit-deps-unchanged'],
- help = "Ignore changes in implicit deps.")
+ help = "Ignore changes in implicit dependencies.")
def opt_j(opt, arg):
global num_jobs
long = ['profile'], arg = 'FILE',
help = "Profile SCons and put results in FILE.")
+ def opt_Q(opt, arg):
+ global display
+ def dont_print_it(text):
+ pass
+ display = dont_print_it
+
+ Option(func = opt_Q,
+ short = 'Q',
+ help = "Don't print SCons progress messages.")
+
def opt_q(opt, arg):
global task_class
task_class = QuestionTask
- Option(func = opt_q, future = 1,
+ Option(func = opt_q,
short = 'q', long = ['question'],
help = "Don't build; exit status says if up to date.")
help = "Build dependencies in random order.")
def opt_s(opt, arg):
+ global display
+ def dont_print_it(text):
+ pass
+ display = dont_print_it
SCons.Action.print_actions = None
Option(func = opt_s,
else:
script_dir = ''
if script_dir:
- print "scons: Entering directory %s" % script_dir
+ display("scons: Entering directory %s" % script_dir)
os.chdir(script_dir)
else:
raise UserError, "No SConstruct file found."
for rep in repositories:
SCons.Node.FS.default_fs.Repository(rep)
- print "scons: Reading SConscript files ..."
+ display("scons: Reading SConscript files ...")
try:
start_time = time.time()
for script in scripts:
global sconscript_time
sconscript_time = time.time() - start_time
except PrintHelp, text:
- print "scons: done reading SConscript files."
+ display("scons: done reading SConscript files.")
print text
print "Use scons -H for help about command-line options."
sys.exit(0)
- print "scons: done reading SConscript files."
+ display("scons: done reading SConscript files.")
SCons.Node.FS.default_fs.chdir(SCons.Node.FS.default_fs.Top)
calc = SCons.Sig.default_calc
- print "scons: Building targets ..."
+ display("scons: Building targets ...")
taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, calc)
jobs = SCons.Job.Jobs(num_jobs, taskmaster)
try:
jobs.run()
finally:
- print "scons: done building targets."
+ display("scons: done building targets.")
SCons.Sig.write()
def main():
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright (c) 2001, 2002 Steven Knight
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import string
+import sys
+import TestSCons
+
+python = sys.executable
+
+test = TestSCons.TestSCons()
+
+test.write('build.py', r"""
+import sys
+file = open(sys.argv[1], 'wb')
+file.write("build.py: %s\n" % sys.argv[1])
+file.close()
+""")
+
+test.write('SConstruct', """
+MyBuild = Builder(action = r'%s build.py $TARGET')
+env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
+env.MyBuild(target = 'f1.out', source = 'f1.in')
+env.MyBuild(target = 'f2.out', source = 'f2.in')
+""" % python)
+
+test.write('f1.in', "f1.in\n")
+test.write('f2.in', "f2.in\n")
+
+test.run(arguments = '-Q f1.out f2.out', stdout = """\
+%s build.py f1.out
+%s build.py f2.out
+""" % (python, python))
+test.fail_test(not os.path.exists(test.workpath('f1.out')))
+test.fail_test(not os.path.exists(test.workpath('f2.out')))
+
+test.pass_test()