Add support for the ENV construction variable.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 28 Sep 2001 20:27:29 +0000 (20:27 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 28 Sep 2001 20:27:29 +0000 (20:27 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@72 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Builder.py
src/engine/SCons/Defaults.py
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Node/__init__.py
test/ENV.py [new file with mode: 0644]

index 72b01cf2434aa349787170ab449e7750b2742d6a..2852b3a3e75368d2ea574300b4e5463e18662186 100644 (file)
@@ -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."""
index 7b5e83da2a333473d7241b798b4f4efb8fe77dfd..0f6ffdaa4d3b91d9bbf2da2285ad2f7e1646dde0 100644 (file)
@@ -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' }
index 508392ba254c082fdd18ba8f7118c07557fd4dfb..c7c32dd4a11dcfc2a7e26467d3ff49b530d66252 100644 (file)
@@ -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))
index 0488173114a7e26a442696944710299cc27e9195..c503fe23ba4609ede298cc7be024184f334bf824 100644 (file)
@@ -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
index 8609c57e2302b9e09351b1fa59bfecc3dd2edb26..4f414ec934824d5c421c68b25af060b73a783fc9 100644 (file)
@@ -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 (file)
index 0000000..b3d7efa
--- /dev/null
@@ -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()