diff options
| author | Steven Knight <knight@baldmt.com> | 2001-12-20 04:40:12 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2001-12-20 04:40:12 (GMT) |
| commit | 8526ba0bb9938ddf3ceca8ca917c77f7b1505f55 (patch) | |
| tree | 724169956a0e4bef7a271ad4b46d8dca4cee3d2b /src/engine | |
| parent | 98bdd799b0c61d2bf1004a9dc39976e4a31abc9c (diff) | |
| download | SCons-8526ba0bb9938ddf3ceca8ca917c77f7b1505f55.zip SCons-8526ba0bb9938ddf3ceca8ca917c77f7b1505f55.tar.gz SCons-8526ba0bb9938ddf3ceca8ca917c77f7b1505f55.tar.bz2 | |
Fix Export(), add Import() and Return()
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/MANIFEST.in | 1 | ||||
| -rw-r--r-- | src/engine/SCons/SConscript.py | 177 | ||||
| -rw-r--r-- | src/engine/SCons/SConscriptTests.py | 28 | ||||
| -rw-r--r-- | src/engine/SCons/Script.py | 92 |
4 files changed, 223 insertions, 75 deletions
diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index c22aebc..ad38b18 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -10,6 +10,7 @@ SCons/Node/FS.py SCons/Scanner/__init__.py SCons/Scanner/C.py SCons/Scanner/Prog.py +SCons/SConscript.py SCons/Script.py SCons/Sig/__init__.py SCons/Sig/MD5.py diff --git a/src/engine/SCons/SConscript.py b/src/engine/SCons/SConscript.py new file mode 100644 index 0000000..1479c7a --- /dev/null +++ b/src/engine/SCons/SConscript.py @@ -0,0 +1,177 @@ +"""engine.SCons.SConscript + +This module defines the Python API provided to SConscript and SConstruct +files. + +""" + +# +# Copyright (c) 2001 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__ = "src/engine/SCons/SConscript.py __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Errors +import SCons.Builder +import SCons.Defaults +import SCons.Node +import SCons.Node.FS +import SCons.Environment +import string +import sys + +default_targets = [] +help_option = None + +# global exports set by Export(): +global_exports = {} + +class Frame: + """A frame on the SConstruct/SConscript call stack""" + def __init__(self, exports): + self.globals = BuildDefaultGlobals() + self.retval = None + self.prev_dir = SCons.Node.FS.default_fs.getcwd() + self.exports = {} # exports from the calling SConscript + + try: + if type(exports) == type([]): + for export in exports: + self.exports[export] = stack[-1].globals[export] + else: + for export in string.split(exports): + self.exports[export] = stack[-1].globals[export] + except KeyError, x: + raise SCons.Errors.UserError, "Export of non-existant variable '%s'"%x + + +# the SConstruct/SConscript call stack: +stack = [] + +# For documentation on the methods in this file, see the scons man-page + +def Return(*vars): + retval = [] + try: + for var in vars: + for v in string.split(var): + retval.append(stack[-1].globals[v]) + except KeyError, x: + raise SCons.Errors.UserError, "Return of non-existant variable '%s'"%x + + if len(retval) == 1: + stack[-1].retval = retval[0] + else: + stack[-1].retval = tuple(retval) + +def SConscript(script, exports=[]): + retval = () + + # push: + stack.append(Frame(exports)) + + # call: + if script == "-": + exec sys.stdin in stack[-1].globals + else: + f = SCons.Node.FS.default_fs.File(script) + if f.exists(): + file = open(str(f), "r") + SCons.Node.FS.default_fs.chdir(f.dir) + exec file in stack[-1].globals + else: + sys.stderr.write("Ignoring missing SConscript '%s'\n" % f.path) + + + # pop: + frame = stack.pop() + SCons.Node.FS.default_fs.chdir(frame.prev_dir) + + return frame.retval + +def Default(*targets): + for t in targets: + if isinstance(t, SCons.Node.Node): + default_targets.append(t) + else: + for s in string.split(t): + default_targets.append(s) + +def Help(text): + global help_option + if help_option == 'h': + print text + print "Use scons -H for help about command-line options." + sys.exit(0) + +def BuildDir(build_dir, src_dir): + SCons.Node.FS.default_fs.BuildDir(build_dir, src_dir) + +def GetBuildPath(files): + nodes = SCons.Util.scons_str2nodes(files, + SCons.Node.FS.default_fs.Entry) + ret = map(str, nodes) + if len(ret) == 1: + return ret[0] + return ret + +def Export(*vars): + try: + for var in vars: + for v in string.split(var): + global_exports[v] = stack[-1].globals[v] + except KeyError, x: + raise SCons.Errors.UserError, "Export of non-existant variable '%s'"%x + +def Import(*vars): + try: + for var in vars: + for v in string.split(var): + if stack[-1].exports.has_key(v): + stack[-1].globals[v] = stack[-1].exports[v] + else: + stack[-1].globals[v] = global_exports[v] + except KeyError,x: + raise SCons.Errors.UserError, "Import of non-existant variable '%s'"%x + +def BuildDefaultGlobals(): + """ + Create a dictionary containing all the default globals for + SConscruct and SConscript files. + """ + + globals = {} + globals['Builder'] = SCons.Builder.Builder + globals['Environment'] = SCons.Environment.Environment + globals['Object'] = SCons.Defaults.Object + globals['Program'] = SCons.Defaults.Program + globals['Library'] = SCons.Defaults.Library + globals['CScan'] = SCons.Defaults.CScan + globals['SConscript'] = SConscript + globals['Default'] = Default + globals['Help'] = Help + globals['BuildDir'] = BuildDir + globals['GetBuildPath'] = GetBuildPath + globals['Export'] = Export + globals['Import'] = Import + globals['Return'] = Return + return globals diff --git a/src/engine/SCons/SConscriptTests.py b/src/engine/SCons/SConscriptTests.py new file mode 100644 index 0000000..d44af5c --- /dev/null +++ b/src/engine/SCons/SConscriptTests.py @@ -0,0 +1,28 @@ +# +# Copyright (c) 2001 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__ = "src/engine/SCons/SConscriptTests.py __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.SConscript + +# all of the SConscript.py tests are in test/SConscript.py diff --git a/src/engine/SCons/Script.py b/src/engine/SCons/Script.py index 1298a9e..e35e03d 100644 --- a/src/engine/SCons/Script.py +++ b/src/engine/SCons/Script.py @@ -58,15 +58,8 @@ from SCons.Errors import * import SCons.Sig import SCons.Sig.MD5 from SCons.Taskmaster import Taskmaster -import SCons.Util - -# -# Modules and classes that we don't use directly in this script, but -# which we want available for use in SConstruct and SConscript files. -# -from SCons.Environment import Environment -from SCons.Builder import Builder -from SCons.Defaults import * +import SCons.Builder +import SCons.SConscript # @@ -104,9 +97,7 @@ class CleanTask(SCons.Taskmaster.Task): # Global variables -default_targets = [] include_dirs = [] -help_option = None num_jobs = 1 scripts = [] task_class = BuildTask # default action is to build targets @@ -115,6 +106,7 @@ calc = None ignore_errors = 0 keep_going_on_error = 0 + # utility functions def _scons_syntax_error(e): @@ -161,40 +153,6 @@ def _scons_other_errors(): -def SConscript(sconscript, export={}): - global scripts - scripts.append( (SCons.Node.FS.default_fs.File(sconscript), export) ) - -def Default(*targets): - for t in targets: - if isinstance(t, SCons.Node.Node): - default_targets.append(t) - else: - for s in string.split(t): - default_targets.append(s) - -def Help(text): - global help_option - if help_option == 'h': - print text - print "Use scons -H for help about command-line options." - sys.exit(0) - -def BuildDir(build_dir, src_dir): - SCons.Node.FS.default_fs.BuildDir(build_dir, src_dir) - -def GetBuildPath(files): - nodes = SCons.Util.scons_str2nodes(files, - SCons.Node.FS.default_fs.Entry) - ret = map(str, nodes) - if len(ret) == 1: - return ret[0] - return ret - -def Export(**kw): - # A convenient shorthand to pass exports to the SConscript function. - return kw - # # After options are initialized, the following variables are # filled in: @@ -392,26 +350,21 @@ def options_init(): def opt_f(opt, arg): global scripts - if arg == '-': - scripts.append( ( arg, {} ) ) - else: - scripts.append( (SCons.Node.FS.default_fs.File(arg), {}) ) + scripts.append(arg) Option(func = opt_f, short = 'f', long = ['file', 'makefile', 'sconstruct'], arg = 'FILE', help = "Read FILE as the top-level SConstruct file.") def opt_help(opt, arg): - global help_option - help_option = 'h' + SCons.SConscript.help_option = 'h' Option(func = opt_help, short = 'h', long = ['help'], help = "Print defined help message, or this one.") def opt_help_options(opt, arg): - global help_option - help_option = 'H' + SCons.SConscript.help_option = 'H' Option(func = opt_help_options, short = 'H', long = ['help-options'], @@ -584,7 +537,7 @@ def UsageString(): def _main(): - global scripts, help_option, num_jobs, task_class, calc + global scripts, num_jobs, task_class, calc targets = [] @@ -618,18 +571,18 @@ def _main(): if not scripts: for file in ['SConstruct', 'Sconstruct', 'sconstruct']: if os.path.isfile(file): - scripts.append( (SCons.Node.FS.default_fs.File(file), {}) ) + scripts.append(file) break - if help_option == 'H': + if SCons.SConscript.help_option == 'H': print UsageString() sys.exit(0) if not scripts: - if help_option == 'h': - # There's no SConstruct, but they specified either -h or - # -H. Give them the options usage now, before we fail - # trying to read a non-existent SConstruct file. + if SCons.SConscript.help_option == 'h': + # There's no SConstruct, but they specified -h. + # Give them the options usage now, before we fail + # trying to read a non-existent SConstruct file. print UsageString() sys.exit(0) else: @@ -637,30 +590,19 @@ def _main(): sys.path = include_dirs + sys.path - while scripts: - f, exports = scripts.pop(0) - script_env = copy.copy(globals()) - script_env.update(exports) - if f == "-": - exec sys.stdin in script_env - else: - if f.exists(): - file = open(str(f), "r") - SCons.Node.FS.default_fs.chdir(f.dir) - exec file in script_env - else: - sys.stderr.write("Ignoring missing SConscript '%s'\n" % f.path) + for script in scripts: + SCons.SConscript.SConscript(script) SCons.Node.FS.default_fs.chdir(SCons.Node.FS.default_fs.Top) - if help_option == 'h': + if SCons.SConscript.help_option == 'h': # They specified -h, but there was no Help() inside the # SConscript files. Give them the options usage. print UsageString() sys.exit(0) if not targets: - targets = default_targets + targets = SCons.SConscript.default_targets def Entry(x): if isinstance(x, SCons.Node.Node): |
