summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/engine/SCons/Builder.py15
-rw-r--r--src/engine/SCons/Defaults.py2
-rw-r--r--src/engine/SCons/Environment.py13
-rw-r--r--src/engine/SCons/EnvironmentTests.py12
-rw-r--r--src/engine/SCons/Node/__init__.py3
-rw-r--r--test/ENV.py58
6 files changed, 99 insertions, 4 deletions
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()