so subsequent calls to
.BR Export ()
will over-write previous exports that have the same name.
-Multiple variable names should be passed to
+Multiple variable names can be passed to
.BR Export ()
-as separate arguments. Examples:
+as separate arguments or as a list. A dictionary can be used to map
+variables to a different name when exported. Both local variables and
+global variables can be exported.
+Examples:
.ES
env = Environment()
Export("env")
package = 'my_name'
-# Make env and package available for all SConscript files to Import().
+# Make env and package available for all SConscript files:.
Export("env", "package")
+
+# Make env and package available for all SConscript files:
+Export(["env", "package"])
+
+# Make env available using the name debug:.
+Export({"debug":env})
.EE
.IP
Variables exported by
.BR SConscript ()
have precedence.
-Multiple variable names should be passed to
+Multiple variable names can be passed to
.BR Import ()
-as separate arguments.
+as separate arguments or as a list. The variable "*" can be used
+to import all variables.
Examples:
.ES
Import("env")
Import("env", "variable")
+Import(["env", "variable"])
+Import("*")
.EE
.TP
The optional
.I exports
-argument provides a list of variable names to export to
+argument provides a list of variable names or a dictionary of
+named values to export to
.IR script ". "
These variables are locally exported only to the specified
.IR script ,
- Add a standalone "Alias" function (separate from an Environment).
+ - Make Export() work for local variables.
+
+ - Support passing a dictionary to Export().
+
+ - Support Import('*') to import everything that's been Export()ed.
+
From Greg Spencer:
- Support the C preprocessor #import statement.
a, b = string.split(arg, '=', 2)
arguments[a] = b
+def get_calling_namespaces():
+ """Return the locals and globals for the function that called
+ into this module in the current callstack."""
+ try: 1/0
+ except: frame = sys.exc_info()[2].tb_frame
+
+ while frame.f_globals.get("__name__") == __name__: frame = frame.f_back
+
+ return frame.f_locals, frame.f_globals
+
+
+def compute_exports(exports):
+ """Compute a dictionary of exports given one of the parameters
+ to the Export() function or the exports argument to SConscript()."""
+ exports = SCons.Util.argmunge(exports)
+ loc, glob = get_calling_namespaces()
+
+ retval = {}
+ try:
+ for export in exports:
+ if SCons.Util.is_Dict(export):
+ retval.update(export)
+ else:
+ try:
+ retval[export] = loc[export]
+ except KeyError:
+ retval[export] = glob[export]
+ except KeyError, x:
+ raise SCons.Errors.UserError, "Export of non-existant variable '%s'"%x
+
+ return retval
+
+
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 SCons.Util.is_List(exports):
- 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
-
+ self.exports = compute_exports(exports) # exports from the calling SConscript
# the SConstruct/SConscript call stack:
stack = []
return SCons.Node.FS.find_file(file, nodes)
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
+ for var in vars:
+ global_exports.update(compute_exports(var))
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]
+ var = SCons.Util.argmunge(var)
+ for v in var:
+ if 'v' == '*':
+ stack[-1].globals.update(global_exports)
+ stack[-1].globals.update(stack[-1].exports[v])
else:
- stack[-1].globals[v] = global_exports[v]
+ 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
stdout = test.wrap_stdout(read_str = 'SConstruct %s\nSConscript %s\n' % (wpath, wpath),
build_str = 'scons: "." is up to date.\n'))
+# Test exporting all global variables as a list of keys:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+Export(globals().keys())
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test exporting all global variables as a list of keys in SConscript call:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+SConscript('SConscript', globals().keys())
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test exporting all global variables as a dictionary:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+Export(globals())
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test exporting all global variables as dictionary in SConscript call:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+SConscript('SConscript', globals())
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test export of local variables:
+test.write("SConstruct", """
+def f():
+ x = 'x'
+ y = 'zoom'
+ Export('x', 'y')
+
+f()
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test export of local variables in SConscript call:
+test.write("SConstruct", """
+def f():
+ x = 'x'
+ y = 'zoom'
+ SConscript('SConscript', ['x', 'y'])
+f()
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test export of local variables as a dictionary:
+test.write("SConstruct", """
+def f():
+ x = 'x'
+ y = 'zoom'
+ Export(locals())
+
+f()
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test importing all variables:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+Export('x')
+SConscript('SConscript', 'y')
+""")
+
+test.write("SConscript", """
+Import('*')
+assert x == 'x'
+assert y == 'zoom'
+""")
test.pass_test()