Commits

Anonymous committed c9f2c0f

Add support for the ENV construction variable.

Comments (0)

Files changed (6)

src/engine/SCons/Builder.py

 	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."""

src/engine/SCons/Defaults.py

 				action = 'cc -o %(target)s %(source)s')
 
 Builders = [Object, Program]
+
+ENV = { 'PATH' : '/usr/local/bin:/bin:/usr/bin' }

src/engine/SCons/Environment.py

 	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:
 	    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))

src/engine/SCons/EnvironmentTests.py

     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
 
 
 	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

src/engine/SCons/Node/__init__.py

 
     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
+#!/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()