summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2001-12-20 04:40:12 (GMT)
committerSteven Knight <knight@baldmt.com>2001-12-20 04:40:12 (GMT)
commit8526ba0bb9938ddf3ceca8ca917c77f7b1505f55 (patch)
tree724169956a0e4bef7a271ad4b46d8dca4cee3d2b /src/engine
parent98bdd799b0c61d2bf1004a9dc39976e4a31abc9c (diff)
downloadSCons-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.in1
-rw-r--r--src/engine/SCons/SConscript.py177
-rw-r--r--src/engine/SCons/SConscriptTests.py28
-rw-r--r--src/engine/SCons/Script.py92
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):