diff options
author | Steven Knight <knight@baldmt.com> | 2003-10-13 13:20:28 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-10-13 13:20:28 (GMT) |
commit | cc0afd7c6d7b051c440eb92c3bfa40142925811e (patch) | |
tree | d3dd96c9b87047e6c7d4087f17b6749079b7f1a1 /src | |
parent | cbb331ea63305207c070c77a7c7403d23b049f9d (diff) | |
download | SCons-cc0afd7c6d7b051c440eb92c3bfa40142925811e.zip SCons-cc0afd7c6d7b051c440eb92c3bfa40142925811e.tar.gz SCons-cc0afd7c6d7b051c440eb92c3bfa40142925811e.tar.bz2 |
More Environment method conversions:
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 17 | ||||
-rw-r--r-- | src/engine/SCons/Action.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/ActionTests.py | 7 | ||||
-rw-r--r-- | src/engine/SCons/Defaults.py | 13 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 69 | ||||
-rw-r--r-- | src/engine/SCons/EnvironmentTests.py | 136 | ||||
-rw-r--r-- | src/engine/SCons/Script/SConscript.py | 53 |
7 files changed, 235 insertions, 66 deletions
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 |