From cc0afd7c6d7b051c440eb92c3bfa40142925811e Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Mon, 13 Oct 2003 13:20:28 +0000 Subject: More Environment method conversions: --- doc/man/scons.1 | 68 +++++++++++++++-- src/CHANGES.txt | 17 +++-- src/engine/SCons/Action.py | 6 -- src/engine/SCons/ActionTests.py | 7 -- src/engine/SCons/Defaults.py | 13 +--- src/engine/SCons/Environment.py | 69 ++++++++++++++++- src/engine/SCons/EnvironmentTests.py | 136 ++++++++++++++++++++++++++++++++++ src/engine/SCons/Script/SConscript.py | 53 ++++++------- test/Alias.py | 2 +- test/Configure.py | 14 ++-- test/Scanner.py | 33 ++++++++- test/Value.py | 2 +- 12 files changed, 337 insertions(+), 83 deletions(-) diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 633f317..9b11f6b 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -1897,20 +1897,24 @@ can be converted into an Action object '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.RI Alias( alias ) +.RI Alias( alias ", [" targets ]) .TP -.RI env.Alias( alias ", " targets ) -Creates a phony target that -expands to one or more other targets. +.RI env.Alias( alias ", [" targets ]) +Creates one or more phony targets that +expand to one or more other targets. Returns the Node object representing the alias, which exists outside of any file system. This Node object, or the alias name, may be used as a dependency of any other target, -including another alias. Alias can be called multiple times for the same +including another alias. +.B Alias +can be called multiple times for the same alias to add additional targets to the alias. .ES Alias('install') +Alias('install', '/usr/bin') +Alias(['install', 'install-lib'], '/usr/local/lib') env.Alias('install', ['/usr/local/bin', '/usr/local/lib']) env.Alias('install', ['/usr/local/man']) @@ -2258,6 +2262,16 @@ env.Command('baz.out', 'baz.in', '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.RI Configure( env ", [" custom_tests ", " conf_dir ", " log_file ]) +.TP +.RI env.Configure([ custom_tests ", " conf_dir ", " log_file ]) +Creates a Configure object for integrated +functionality similar to GNU autoconf. +See the section "Configure Contexts," +below, for a complete explanation of the arguments and behavior. + +'\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .RI env.Copy([ key = val ", ...])" Return a separate copy of a construction environment. If there are any keyword arguments specified, @@ -2591,6 +2605,25 @@ options from a SConscript file. See for a description of the options available. '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +'\".TP +'\".RI GlobalBuilders( flag ) +'\"When +'\".B flag +'\"is non-zero, +'\"adds the names of the default builders +'\"(Program, Library, etc.) +'\"to the global name space +'\"so they can be called without an explicit construction environment. +'\"(This is the default.) +'\"When +'\".B +'\"flag is zero, +'\"the names of the default builders are removed +'\"from the global name space +'\"so that an explicit construction environment is required +'\"to call all builders. + +'\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .RI Help( text ) .TP @@ -2964,6 +2997,17 @@ Return(["foo", "bar"]) .EE '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP +.RI Scanner( function ", [" argument ", " keys ", " path_function ", " node_class ", " node_factory ", " scan_check ", " recursive ]) +.TP +.RI env.Scanner( function ", [" argument ", " keys ", " path_function ", " node_class ", " node_factory ", " scan_check ", " recursive ]) +Creates a Scanner object for +the specified +.IR function . +See the section "Scanner Objects," +below, for a complete explanation of the arguments and behavior. + +'\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP env.SCCS() A factory function that @@ -3122,16 +3166,19 @@ SConscript(dirs=['sub3', 'sub4'], name='MySConscript') '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .RI SConscriptChdir( value ) +.TP +.RI env.SConscriptChdir( value ) By default, .B scons changes its working directory to the directory in which each subsidiary SConscript file lives. This behavior may be disabled -by specifying: +by specifying either: .ES SConscriptChdir(0) +env.SConscriptChdir(0) .EE .IP in which case @@ -3148,9 +3195,10 @@ SConscriptChdir() multiple times: .ES +env = Environment() SConscriptChdir(0) SConscript('foo/SConscript') # will not chdir to foo -SConscriptChdir(1) +env.SConscriptChdir(1) SConscript('bar/SConscript') # will chdir to bar .EE @@ -3468,6 +3516,8 @@ env.Tool('gcc') '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .RI Value( value ) +.TP +.RI env.Value( value ) Returns a Node object representing the specified Python value. Value nodes can be used as dependencies of targets. If the result of calling @@ -4993,7 +5043,7 @@ method: env2 = env.Copy(CC="cl.exe") .EE -.SS Configure contexts +.SS Configure Contexts .B scons supports @@ -5011,6 +5061,8 @@ The following methods can be used to perform checks: .TP .RI Configure( env ", [" custom_tests ", " conf_dir ", " log_file ]) +.TP +.RI env.Configure([ custom_tests ", " conf_dir ", " log_file ]) This creates a configure context, which can be used to perform checks. .I env specifies the environment for building the tests. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 1706903..1ab7499 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -80,13 +80,14 @@ RELEASE X.XX - XXX - Support arbitrary expansion of construction variables within file and directory arguments to Builder calls and Environment methods. - - Add Environment-method versions of the following global - functions: Action(), AddPostAction(), AddPreAction(), Builder(), - BuildDir(), CacheDir(), Clean(), Default(), EnsurePythonVersion(), - EnsureSConsVersion(), Environment(), Exit(), Export(), FindFile(), - GetBuildPath(), GetOption(), Help(), Import(), Literal(), - Local(), Platform(), Repository(), SConsignFile(), SetOption(), - SourceSignatures(), Split(), TargetSignatures(), Tool(). + - Add Environment-method versions of the following global functions: + Action(), AddPostAction(), AddPreAction(), Alias(), Builder(), + BuildDir(), CacheDir(), Clean(), Configure(), Default(), + EnsurePythonVersion(), EnsureSConsVersion(), Environment(), + Exit(), Export(), FindFile(), GetBuildPath(), GetOption(), Help(), + Import(), Literal(), Local(), Platform(), Repository(), Scanner(), + SConscriptChdir(), SConsignFile(), SetOption(), SourceSignatures(), + Split(), TargetSignatures(), Tool(), Value(). - Add the following global functions that correspond to the same-named Environment methods: AlwaysBuild(), Command(), Depends(), Ignore(), @@ -115,6 +116,8 @@ RELEASE X.XX - XXX - Allow the Environment.WhereIs() method to take explicit path and pathext arguments (like the underlying SCons.Util.WhereIs() function). + - Remove the long-obsolete {Get,Set}CommandHandler() functions. + From Clark McGrew: - Generalize the action for .tex files so that it will decide whether diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index c9186a4..633bb06 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -53,12 +53,6 @@ def rfile(n): except AttributeError: return n -def SetCommandHandler(func, escape = lambda x: x): - raise SCons.Errors.UserError("SetCommandHandler() is no longer supported, use the SPAWN and ESCAPE construction variables.") - -def GetCommandHandler(): - raise SCons.Errors.UserError("GetCommandHandler() is no longer supported, use the SPAWN construction variable.") - def _actionAppend(act1, act2): # This function knows how to slap two actions together. # Mainly, it handles ListActions by concatenating into diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index be14357..53aa00a 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -616,13 +616,6 @@ class CommandActionTestCase(unittest.TestCase): def is_literal(self): return 1 - try: - SCons.Action.SetCommandHandler(func) - except SCons.Errors.UserError: - pass - else: - assert 0, "should have gotten user error" - a = SCons.Action.CommandAction(["xyzzy"]) a([], [], Environment(SPAWN = func)) assert t.executed == [ 'xyzzy' ] diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 798abb3..aaa1aba 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -46,8 +46,6 @@ import types import SCons.Action import SCons.Builder import SCons.Environment -import SCons.Node.Alias -import SCons.Node.FS import SCons.Scanner.C import SCons.Scanner.Fortran import SCons.Scanner.Prog @@ -69,15 +67,6 @@ def DefaultEnvironment(*args, **kw): _default_env._calc_module = SCons.Sig.default_module return _default_env - -def alias_builder(env, target, source): - pass - -Alias = SCons.Builder.Builder(action = alias_builder, - target_factory = SCons.Node.Alias.default_ans.Alias, - source_factory = SCons.Node.FS.default_fs.Entry, - multi = 1) - CScan = SCons.Scanner.C.CScan() FortranScan = SCons.Scanner.Fortran.FortranScan() @@ -264,7 +253,7 @@ class NullCmdGenerator: return self.cmd ConstructionEnvironment = { - 'BUILDERS' : { 'Alias' : Alias }, + 'BUILDERS' : {}, 'SCANNERS' : [CScan, FortranScan], 'PDFPREFIX' : '', 'PDFSUFFIX' : '.pdf', diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 36be2e4..f8ff6c3 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -48,7 +48,9 @@ import SCons.Builder import SCons.Defaults import SCons.Errors import SCons.Node +import SCons.Node.Alias import SCons.Node.FS +import SCons.Node.Python import SCons.Platform import SCons.Sig import SCons.Sig.MD5 @@ -87,6 +89,14 @@ installAction = SCons.Action.Action(installFunc, installString) InstallBuilder = SCons.Builder.Builder(action=installAction) +def alias_builder(env, target, source): + pass + +AliasBuilder = SCons.Builder.Builder(action = alias_builder, + target_factory = SCons.Node.Alias.default_ans.Alias, + source_factory = SCons.Node.FS.default_fs.Entry, + multi = 1) + def our_deepcopy(x): """deepcopy lists and dictionaries, and just copy the reference for everything else.""" @@ -201,6 +211,7 @@ class Base: options=None, **kw): self.fs = SCons.Node.FS.default_fs + self.ans = SCons.Node.Alias.default_ans self.lookup_list = SCons.Node.arg2nodes_lookups self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment) @@ -374,6 +385,7 @@ class Base: mode = SCons.Util.SUBST_CMD nkw = {} for k, v in kw.items(): + k = SCons.Util.scons_subst(k, self, mode, target, source) if SCons.Util.is_String(v): v = SCons.Util.scons_subst(v, self, mode, target, source) nkw[k] = v @@ -705,6 +717,32 @@ class Base: n.add_post_action(action) return nodes + def Alias(self, target, *source, **kw): + if not SCons.Util.is_List(target): + target = [target] + tlist = [] + for t in target: + if not isinstance(t, SCons.Node.Alias.Alias): + t = self.arg2nodes(self.subst(t), self.ans.Alias)[0] + tlist.append(t) + try: + s = kw['source'] + except KeyError: + try: + s = source[0] + except IndexError: + s = None + if s: + if not SCons.Util.is_List(s): + s = [s] + s = filter(None, s) + s = self.arg2nodes(s, self.fs.Entry) + for t in tlist: + AliasBuilder(self, t, s) + if len(tlist) == 1: + tlist = tlist[0] + return tlist + def AlwaysBuild(self, *targets): tlist = [] for t in targets: @@ -734,7 +772,7 @@ class Base: if not isinstance(target, SCons.Node.Node): target = self.subst(target) - target = SCons.Node.FS.default_fs.Entry(target, create=1) + target = self.fs.Entry(target, create=1) if not SCons.Util.is_List(files): files = [files] @@ -751,13 +789,24 @@ class Base: except KeyError: CleanTargets[target] = nodes + def Configure(self, *args, **kw): + nargs = [self] + if args: + nargs = nargs + self.subst_list(args)[0] + nkw = self.subst_kw(kw) + try: + nkw['custom_tests'] = self.subst_kw(nkw['custom_tests']) + except KeyError: + pass + return apply(SCons.SConf.SConf, nargs, nkw) + def Command(self, target, source, action): """Builds the supplied target files from the supplied source files using the supplied action. Action may be any type that the Builder constructor will accept for an action.""" bld = SCons.Builder.Builder(action=action, - source_factory=SCons.Node.FS.default_fs.Entry) + source_factory=self.fs.Entry) return bld(self, target, source) def Default(self, *targets): @@ -834,7 +883,7 @@ class Base: tgt = [] for dnode in dnodes: for src in sources: - target = SCons.Node.FS.default_fs.File(src.name, dnode) + target = self.fs.File(src.name, dnode) tgt.append(InstallBuilder(self, target, src)) if len(tgt) == 1: tgt = tgt[0] @@ -882,6 +931,15 @@ class Base: dirs = self.arg2nodes(list(dirs), self.fs.Dir) apply(self.fs.Repository, dirs, kw) + def Scanner(self, *args, **kw): + nargs = [] + for arg in args: + if SCons.Util.is_String(arg): + arg = self.subst(arg) + nargs.append(arg) + nkw = self.subst_kw(kw) + return apply(SCons.Scanner.Base, nargs, nkw) + def SConsignFile(self, name=".sconsign.dbm"): name = self.subst(name) if not os.path.isabs(name): @@ -957,6 +1015,11 @@ class Base: else: raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type + def Value(self, value): + """ + """ + return SCons.Node.Python.Value(value) + # The entry point that will be used by the external world # to refer to a construction environment. This allows the wrapper # interface to extend a construction environment for its own purposes diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 360eb4c..49d6ac7 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -308,6 +308,36 @@ class EnvironmentTestCase(unittest.TestCase): assert lst[0][0] == 'test', lst[0][0] assert lst[0][1] == 'baz', lst[0][1] + # Test not calling callables in the Environment + if 0: + # This will take some serious surgery to subst() and + # subst_list(), so just leave these tests out until we can + # do that. + def bar(arg): + pass + + env = Environment(BAR=bar, FOO='$BAR') + + subst = env.subst('$BAR', call=None) + assert subst is bar, subst + + subst = env.subst('$FOO', call=None) + assert subst is bar, subst + + subst = env.subst_list('$BAR', call=None) + assert subst is bar, subst + + subst = env.subst_list('$FOO', call=None) + assert subst is bar, subst + + def test_subst_kw(self): + """Test substituting construction variables within dictionaries""" + env = Environment(AAA = 'a', BBB = 'b') + kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'}) + assert len(kw) == 2, kw + assert kw['a'] == 'aaa', kw['a'] + assert kw['bbb'] == 'b', kw['bbb'] + def test_Builder_calls(self): """Test Builder calls through different environments """ @@ -1191,6 +1221,49 @@ class EnvironmentTestCase(unittest.TestCase): assert str(n[0]) == 'ggg', n[0] assert str(n[1]) == 'bbb', n[1] + def test_Alias(self): + """Test the Alias() method""" + env = Environment(FOO='kkk', BAR='lll', EA='export_alias') + + tgt = env.Alias('new_alias') + assert str(tgt) == 'new_alias', tgt + assert tgt.sources == [], tgt.sources + + tgt = env.Alias('None_alias', None) + assert str(tgt) == 'None_alias', tgt + assert tgt.sources == [], tgt.sources + + tgt = env.Alias('empty_list', []) + assert str(tgt) == 'empty_list', tgt + assert tgt.sources == [], tgt.sources + + tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ]) + assert str(tgt) == 'export_alias', tgt + assert len(tgt.sources) == 2, map(str, tgt.sources) + assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources) + assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources) + + n = env.Alias(tgt, source = ['$BAR', 'asrc4']) + assert n is tgt, n + assert len(tgt.sources) == 4, map(str, tgt.sources) + assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources) + assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources) + + n = env.Alias('$EA', 'asrc5') + assert n is tgt, n + assert len(tgt.sources) == 5, map(str, tgt.sources) + assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources) + + t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7']) + assert str(t1) == 't1', t1 + assert str(t2) == 't2', t2 + assert len(t1.sources) == 2, map(str, t1.sources) + assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources) + assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources) + assert len(t2.sources) == 2, map(str, t2.sources) + assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources) + assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources) + def test_AlwaysBuild(self): """Test the AlwaysBuild() method""" env = Environment(FOO='fff', BAR='bbb') @@ -1323,6 +1396,32 @@ class EnvironmentTestCase(unittest.TestCase): assert 'foo1.in' in map(lambda x: x.path, t.sources) assert 'foo2.in' in map(lambda x: x.path, t.sources) + def test_Configure(self): + """Test the Configure() method""" + # Configure() will write to a local temporary file. + test = TestCmd.TestCmd(workdir = '') + save = os.getcwd() + + try: + os.chdir(test.workpath()) + + env = Environment(FOO = 'xyzzy') + + def func(arg): + pass + + c = env.Configure() + assert not c is None, c + c.Finish() + + c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func}) + assert not c is None, c + assert hasattr(c, 'foo') + assert hasattr(c, 'xyzzy') + c.Finish() + finally: + os.chdir(save) + def test_Default(self): """Test the Default() method""" env = Environment(FOO = 'fff', BAR = 'bbb') @@ -1592,6 +1691,26 @@ class EnvironmentTestCase(unittest.TestCase): expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo'] assert env.fs.list == expect, env.fs.list + def test_Scanner(self): + """Test the Scanner() method""" + def scan(node, env, target, arg): + pass + + env = Environment(FOO = scan) + + s = env.Scanner('foo') + assert not s is None, s + + s = env.Scanner(function = 'foo') + assert not s is None, s + + if 0: + s = env.Scanner('$FOO') + assert not s is None, s + + s = env.Scanner(function = '$FOO') + assert not s is None, s + def test_SConsignFile(self): """Test the SConsignFile() method""" import SCons.Sig @@ -1750,6 +1869,23 @@ class EnvironmentTestCase(unittest.TestCase): env.TargetSignatures('$C') assert env._build_signature == 0, env._build_signature + def test_Value(self): + """Test creating a Value() object + """ + env = Environment() + v1 = env.Value('a') + assert v1.value == 'a', v1.value + + value2 = 'a' + v2 = env.Value(value2) + assert v2.value == value2, v2.value + assert v2.value is value2, v2.value + + assert not v1 is v2 + assert v1.value == v2.value + + + def test_Environment_global_variable(type): """Test setting Environment variable to an Environment.Base subclass""" class MyEnv(SCons.Environment.Base): diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index aed43f5..92cd68d 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -39,13 +39,12 @@ import SCons.Errors import SCons.Node import SCons.Node.Alias import SCons.Node.FS -import SCons.Node.Python +import SCons.Options import SCons.Platform import SCons.SConf import SCons.Script import SCons.Tool import SCons.Util -import SCons.Options import os import os.path @@ -68,10 +67,6 @@ global_exports = {} # chdir flag sconscript_chdir = 1 -def SConscriptChdir(flag): - global sconscript_chdir - sconscript_chdir = flag - def _scons_add_args(alist): global arguments for arg in alist: @@ -365,17 +360,17 @@ class SConsEnvironment(SCons.Environment.Base): src_dir, fname = os.path.split(str(files[0])) else: if not isinstance(src_dir, SCons.Node.Node): - src_dir = SCons.Node.FS.default_fs.Dir(src_dir) + src_dir = self.fs.Dir(src_dir) fn = files[0] if not isinstance(fn, SCons.Node.Node): - fn = SCons.Node.FS.default_fs.File(fn) + fn = self.fs.File(fn) if fn.is_under(src_dir): # Get path relative to the source directory. fname = fn.get_path(src_dir) else: # Fast way to only get the terminal path component of a Node. fname = fn.get_path(fn.dir) - SCons.Node.FS.default_fs.BuildDir(build_dir, src_dir, duplicate) + self.fs.BuildDir(build_dir, src_dir, duplicate) files = [os.path.join(str(build_dir), fname)] return (files, exports) @@ -446,6 +441,10 @@ class SConsEnvironment(SCons.Environment.Base): return apply(_SConscript, [self.fs,] + files, {'exports' : exports}) + def SConscriptChdir(self, flag): + global sconscript_chdir + sconscript_chdir = flag + def SetOption(self, name, value): name = self.subst(name) SCons.Script.ssoptions.set(name, value) @@ -455,6 +454,9 @@ class SConsEnvironment(SCons.Environment.Base): # SCons.Environment.Environment = SConsEnvironment +def Options(files=None, args=arguments): + return SCons.Options.Options(files, args) + def SetBuildSignatureType(type): SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "The SetBuildSignatureType() function has been deprecated;\n" +\ @@ -467,10 +469,6 @@ def SetContentSignatureType(type): "\tuse the SourceSignatures() function instead.") SCons.Defaults.DefaultEnvironment().SourceSignatures(type) -class Options(SCons.Options.Options): - def __init__(self, files=None, args=arguments): - SCons.Options.Options.__init__(self, files, args) - def GetJobs(): SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "The GetJobs() function has been deprecated;\n" +\ @@ -490,13 +488,6 @@ def ParseConfig(env, command, function=None): "\tuse the env.ParseConfig() method instead.") return env.ParseConfig(command, function) - -def Alias(name): - alias = SCons.Node.Alias.default_ans.lookup(name) - if alias is None: - alias = SCons.Node.Alias.default_ans.Alias(name) - return alias - # _DefaultEnvironmentProxy = None @@ -557,12 +548,14 @@ GlobalDefaultEnvironmentFunctions = [ 'Help', 'Import', 'SConscript', + 'SConscriptChdir', 'SetOption', # Methods from the Environment.Base class. 'Action', 'AddPostAction', 'AddPreAction', + 'Alias', 'AlwaysBuild', 'BuildDir', 'Builder', @@ -583,13 +576,17 @@ GlobalDefaultEnvironmentFunctions = [ 'Local', 'Precious', 'Repository', + 'Scanner', 'SConsignFile', 'SideEffect', 'SourceCode', 'SourceSignatures', 'Split', 'TargetSignatures', + 'Value', +] +GlobalDefaultBuilders = [ # Supported builders. 'CFile', 'CXXFile', @@ -616,7 +613,7 @@ GlobalDefaultEnvironmentFunctions = [ 'Zip', ] -for name in GlobalDefaultEnvironmentFunctions: +for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders: GlobalDict[name] = DefaultEnvironmentCall(name) def BuildDefaultGlobals(): @@ -626,23 +623,17 @@ def BuildDefaultGlobals(): """ globals = {} + globals['ARGUMENTS'] = arguments + globals['Configure'] = SCons.SConf.SConf + globals['Options'] = Options globals['Platform'] = SCons.Platform.Platform + globals['Return'] = Return globals['Tool'] = SCons.Tool.Tool globals['WhereIs'] = SCons.Util.WhereIs # Functions we're in the process of converting to Environment methods. - globals['Alias'] = Alias - globals['ARGUMENTS'] = arguments - globals['Configure'] = SCons.SConf.SConf globals['CScan'] = SCons.Defaults.CScan globals['DefaultEnvironment'] = SCons.Defaults.DefaultEnvironment - globals['GetCommandHandler'] = SCons.Action.GetCommandHandler - globals['Options'] = Options - globals['Return'] = Return - globals['SConscriptChdir'] = SConscriptChdir - globals['Scanner'] = SCons.Scanner.Base - globals['SetCommandHandler'] = SCons.Action.SetCommandHandler - globals['Value'] = SCons.Node.Python.Value # Deprecated functions, leave these here for now. globals['GetJobs'] = GetJobs diff --git a/test/Alias.py b/test/Alias.py index ea94652..2a14c02 100644 --- a/test/Alias.py +++ b/test/Alias.py @@ -54,7 +54,7 @@ SConscript('sub2/SConscript', "env") foo = Alias('foo') foo2 = env.Alias('foo', ['f2.out', 'sub1']) assert foo == foo2 -bar = env.Alias('bar', ['sub2', 'f3.out']) +bar = Alias('bar', ['sub2', 'f3.out']) env.Alias('blat', ['sub2', 'f3.out']) env.Alias('blat', ['f2.out', 'sub1']) env.Depends('f1.out', 'bar') diff --git a/test/Configure.py b/test/Configure.py index 3bad086..9170469 100644 --- a/test/Configure.py +++ b/test/Configure.py @@ -116,7 +116,7 @@ Checking for C++ header file vector... yes env = Environment() import os env['ENV']['PATH'] = os.environ['PATH'] -conf = Configure(env) +conf = env.Configure() r1 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error r2 = conf.CheckLib( 'no_c_library_SAFFDG' ) # leads to link error env = conf.Finish() @@ -182,11 +182,11 @@ Checking for C header file no_std_c_header.h... no test.write( 'SConstruct', """ -env = Environment() +env = Environment(LOGFILE='build/config.log') import os env['ENV']['PATH'] = os.environ['PATH'] BuildDir( 'build', '.' ) -conf = Configure(env, conf_dir='build/config.tests', log_file='build/config.log') +conf = env.Configure(conf_dir='build/config.tests', log_file='$LOGFILE') r1 = conf.CheckCHeader( 'math.h' ) r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error env = conf.Finish() @@ -243,11 +243,15 @@ def CustomTest(context): context.Result(ret) return ret -env = Environment() +env = Environment(FOO='fff') env.Append( CPPPATH='local' ) import os env['ENV']['PATH'] = os.environ['PATH'] -conf = Configure( env, custom_tests = {'CustomTest' : CustomTest} ) +conf = Configure( env, custom_tests = {'CustomTest' : CustomTest, + '$FOO' : CustomTest} ) +if hasattr(conf, 'fff'): + conf.Message('$FOO should not have been expanded!') + Exit(1) if not conf.CheckCHeader( 'math.h' ): Exit(1) if conf.CheckCHeader( 'no_std_c_header.h' ): diff --git a/test/Scanner.py b/test/Scanner.py index 42ef18d..b11805e 100644 --- a/test/Scanner.py +++ b/test/Scanner.py @@ -70,15 +70,29 @@ kscan = Scanner(name = 'kfile', function = kfile_scan, argument = None, skeys = ['.k']) + +env = Environment(K2SCAN=kfile_scan) + +k2scan = env.Scanner(name = 'k2', + # We'd like to do the following, but it will take + # some major surgery to subst() and subst_list(), + # so comment it out for now. + # function = '$K2SCAN', + function = kfile_scan, + argument = None, + skeys = ['.k2']) + scanners = Environment().Dictionary('SCANNERS') -env = Environment(SCANNERS = scanners + [kscan]) +env = Environment(SCANNERS = scanners + [kscan, k2scan]) env.Command('foo', 'foo.k', r'%s build.py $SOURCES $TARGET') +env.Command('junk', 'junk.k2', r'%s build.py $SOURCES $TARGET') + bar_in = File('bar.in') env.Command('bar', bar_in, r'%s build.py $SOURCES $TARGET') bar_in.source_scanner = kscan -""" % (python, python)) +""" % (python, python, python)) test.write('foo.k', """foo.k 1 line 1 @@ -94,6 +108,13 @@ bar.in 1 line 3 include zzz """) +test.write('junk.k2', +"""include yyy +junk.k2 1 line 2 +junk.k2 1 line 3 +include zzz +""") + test.write('xxx', "xxx 1\n") test.write('yyy', "yyy 1\n") @@ -106,6 +127,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 1\nyyy 1\nfoo.k 1 line 4 test.fail_test(test.read('bar') != "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n") +test.fail_test(test.read('junk') != "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") + test.up_to_date(arguments = '.') test.write('xxx', "xxx 2\n") @@ -116,6 +139,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 2\nyyy 1\nfoo.k 1 line 4 test.fail_test(test.read('bar') != "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n") +test.fail_test(test.read('junk') != "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") + test.write('yyy', "yyy 2\n") test.run(arguments = '.') @@ -124,6 +149,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4 test.fail_test(test.read('bar') != "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n") +test.fail_test(test.read('junk') != "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") + test.write('zzz', "zzz 2\n") test.run(arguments = '.') @@ -132,6 +159,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4 test.fail_test(test.read('bar') != "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 2\n") +test.fail_test(test.read('junk') != "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 2\n") + test.up_to_date(arguments = 'foo') test.pass_test() diff --git a/test/Value.py b/test/Value.py index 11fb72a..5f723bf 100644 --- a/test/Value.py +++ b/test/Value.py @@ -54,7 +54,7 @@ def create(target, source, env): env = Environment() env['BUILDERS']['B'] = Builder(action = create) env.B('f1.out', Value(P)) -env.B('f2.out', Value(L)) +env.B('f2.out', env.Value(L)) env.B('f3.out', Value(C)) """ % source_signature) -- cgit v0.12