From 1740dba381b84692daa6b8e01eb4a52bf61330de Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Fri, 28 Sep 2001 20:27:29 +0000 Subject: Add support for the ENV construction variable. --- src/engine/SCons/Builder.py | 15 +++++++++- src/engine/SCons/Defaults.py | 2 ++ src/engine/SCons/Environment.py | 13 +++++++- src/engine/SCons/EnvironmentTests.py | 12 +++++++- src/engine/SCons/Node/__init__.py | 3 +- test/ENV.py | 58 ++++++++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 test/ENV.py diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 72b01cf..2852b3a 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -94,7 +94,20 @@ class CommandAction(ActionBase): if print_actions: self.show(cmd) if execute_actions: - os.system(cmd) + pid = os.fork() + if not pid: + # Child process. + args = string.split(cmd) + try: + ENV = kw['ENV'] + except: + import SCons.Defaults + ENV = SCons.Defaults.ENV + os.execvpe(args[0], args, ENV) + else: + # Parent process. + os.waitpid(pid, 0) + class FunctionAction(ActionBase): """Class for Python function actions.""" diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 7b5e83d..0f6ffda 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -20,3 +20,5 @@ Program = SCons.Builder.Builder(name = 'Program', action = 'cc -o %(target)s %(source)s') Builders = [Object, Program] + +ENV = { 'PATH' : '/usr/local/bin:/bin:/usr/bin' } diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 508392b..c7c32dd 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -61,6 +61,9 @@ class Environment: else: import SCons.Defaults kw['BUILDERS'] = SCons.Defaults.Builders[:] + if not kw.has_key('ENV'): + import SCons.Defaults + kw['ENV'] = SCons.Defaults.ENV.copy() self._dict.update(copy.deepcopy(kw)) class BuilderWrapper: @@ -74,8 +77,16 @@ class Environment: def __call__(self, target = None, source = None): return self.builder(self.env, target, source) + # This allows a Builder to be executed directly + # through the Environment to which it's attached. + # In practice, we shouldn't need this, because + # builders actually get executed through a Node. + # But we do have a unit test for this, and can't + # yet rule out that it would be useful in the + # future, so leave it for now. def execute(self, **kw): - apply(self.builder.execute, (), kw) + kw['env'] = self + apply(self.builder.execute, (), kw) for b in kw['BUILDERS']: setattr(self, b.name, BuilderWrapper(self, b)) diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 0488173..c503fe2 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -16,7 +16,7 @@ class Builder: def __init__(self, name = None): self.name = name - def execute(self, target = None, source = None): + def execute(self, target = None, **kw): built_it[target] = 1 @@ -94,6 +94,16 @@ class EnvironmentTestCase(unittest.TestCase): assert xxx == 'x' assert zzz == 'z' assert env.Dictionary().has_key('BUILDERS') + assert env.Dictionary().has_key('ENV') + + def test_ENV(self): + """Test setting the external ENV in Environments + """ + env = Environment() + assert env.Dictionary().has_key('ENV') + + env = Environment(ENV = { 'PATH' : '/foo:/bar' }) + assert env.Dictionary('ENV')['PATH'] == '/foo:/bar' def test_Environment(self): """Test construction Environments creation diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 8609c57..4f414ec 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -25,7 +25,8 @@ class Node: def build(self): sources_str = string.join(map(lambda x: str(x), self.sources)) - self.builder.execute(target = str(self), source = sources_str) + self.builder.execute(ENV = self.env.Dictionary('ENV'), + target = str(self), source = sources_str) def builder_set(self, builder): self.builder = builder diff --git a/test/ENV.py b/test/ENV.py new file mode 100644 index 0000000..b3d7efa --- /dev/null +++ b/test/ENV.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('bin1', 'bin2') + +bin1 = test.workpath('bin1') +bin2 = test.workpath('bin2') +bin1_build_py = test.workpath('bin1', 'build.py') +bin2_build_py = test.workpath('bin2', 'build.py') + +test.write('SConstruct', """ +import os +bin1_path = r'%s' + os.pathsep + os.environ['PATH'] +bin2_path = r'%s' + os.pathsep + os.environ['PATH'] +Bld = Builder(name = 'Bld', action = "build.py %%(target)s %%(source)s") +bin1 = Environment(ENV = {'PATH' : bin1_path}, BUILDERS = [Bld]) +bin2 = Environment(ENV = {'PATH' : bin2_path}, BUILDERS = [Bld]) +bin1.Bld(target = 'bin1.out', source = 'input') +bin2.Bld(target = 'bin2.out', source = 'input') +""" % (bin1, bin2)) + +test.write(bin1_build_py, +"""#!/usr/bin/env python +import sys +contents = open(sys.argv[2], 'r').read() +file = open(sys.argv[1], 'w') +file.write("bin1/build.py\\n") +file.write(contents) +file.close() +""") +os.chmod(bin1_build_py, 0755) + +test.write(bin2_build_py, +"""#!/usr/bin/env python +import sys +contents = open(sys.argv[2], 'r').read() +file = open(sys.argv[1], 'w') +file.write("bin2/build.py\\n") +file.write(contents) +file.close() +""") +os.chmod(bin2_build_py, 0755) + +test.write('input', "input file\n") + +#test.run(arguments = '.') +test.run(arguments = 'bin1.out bin2.out') + +test.fail_test(test.read('bin1.out') != "bin1/build.py\ninput file\n") +test.fail_test(test.read('bin2.out') != "bin2/build.py\ninput file\n") + +test.pass_test() -- cgit v0.12