Add common subproc function and modify routines to use it
authorGregNoel <GregNoel@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 12 Sep 2008 08:50:56 +0000 (08:50 +0000)
committerGregNoel <GregNoel@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 12 Sep 2008 08:50:56 +0000 (08:50 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@3389 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Action.py
src/engine/SCons/Environment.py
src/engine/SCons/Tool/g++.py
src/engine/SCons/Tool/gcc.py

index b15857418d704128903100180f23941da73311ba..f1de15c958657ba6be3e5ff257b43ca0ef1e045d 100644 (file)
@@ -103,6 +103,7 @@ import os
 import os.path
 import string
 import sys
+import subprocess
 
 from SCons.Debug import logInstanceCreation
 import SCons.Errors
@@ -118,8 +119,6 @@ print_actions = 1
 execute_actions = 1
 print_actions_presub = 0
 
-default_ENV = None
-
 def rfile(n):
     try:
         return n.rfile()
@@ -493,6 +492,64 @@ def _string_from_cmd_list(cmd_list):
         cl.append(arg)
     return string.join(cl)
 
+# this function is still in draft mode.  We're going to need something like
+# it in the long run as more and more places use it, but I'm sure it'll have
+# to be tweaked to get the full desired functionality.
+default_ENV = None
+# one special arg, 'error', to tell what to do with exceptions.
+def _subproc(env, cmd, error = 'ignore', **kw):
+    """Do setup for a subprocess.Popen() call"""
+
+    # If the env has no ENV, get a default
+    try:
+        ENV = env['ENV']
+    except KeyError:
+        global default_ENV
+        if default_ENV is None:
+            # Unbelievably expensive.  What it really should do
+            # is run the platform setup to get the default ENV.
+            # Fortunately, it should almost never happen.
+            default_ENV = SCons.Environment.Environment(tools=[])['ENV']
+        ENV = default_ENV
+    
+    # Ensure that the ENV values are all strings:
+    new_env = {}
+    # It's a string 99.44% of the time, so optimize this
+    is_String = SCons.Util.is_String
+    for key, value in ENV.items():
+        if is_String(value):
+            new_env[key] = value
+        elif SCons.Util.is_List(value):
+            # If the value is a list, then we assume it is a
+            # path list, because that's a pretty common list-like
+            # value to stick in an environment variable:
+            value = SCons.Util.flatten_sequence(value)
+            ENV[key] = string.join(map(str, value), os.pathsep)
+        else:
+            # If it isn't a string or a list, then we just coerce
+            # it to a string, which is the proper way to handle
+            # Dir and File instances and will produce something
+            # reasonable for just about everything else:
+            ENV[key] = str(value)
+    kw['env'] = new_env
+
+    try:
+        #FUTURE return subprocess.Popen(cmd, **kw)
+        return apply(subprocess.Popen, (cmd,), kw)
+    except EnvironmentError, e:
+        if error == 'raise': raise
+        # return a dummy Popen instance that only returns error
+        class popen:
+            def __init__(self, e): self.exception = e
+            def communicate(): return ('','')
+            def wait(): return -self.exception.errno
+            stdin = None
+            class f:
+                def read(self): return ''
+                def readline(self): return ''
+            stdout = stderr = f()
+        return popen(e)
+
 class CommandAction(_ActionAction):
     """Class for command-execution actions."""
     def __init__(self, cmd, cmdstr=None, *args, **kw):
index 1a4f5f567526341a848c7b09843a9a214c9cec3e..f416bb07c3d6ffb300847d76cc442dd69f9ed261 100644 (file)
@@ -534,13 +534,9 @@ class SubstitutionEnvironment:
         # if the command is a list, assume it's been quoted
         # othewise force a shell
         if not SCons.Util.is_List(command): kw['shell'] = True
-        # a SubstutionEnvironment has no ENV, so only add it
-        # to the args if it exists
-        e = self._dict.get('ENV')
-        if e: kw['env'] = e
         # run constructed command
-        #FUTURE p = subprocess.Popen(command, **kw)
-        p = apply(subprocess.Popen, (command,), kw)
+        #FUTURE p = Scons.Action._subproc(env, command, **kw)
+        p = apply(Scons.Action._subproc, (env, command), kw)
         out = p.stdout.read()
         p.stdout.close()
         err = p.stderr.read()
index 0745c03fd014f27a3a2b9b51a714e6a5bc7fee91..f8f5b34e521e90fd9abad36f38dcd83bd68446c1 100644 (file)
@@ -63,13 +63,9 @@ def generate(env):
         env['SHOBJSUFFIX'] = '.pic.o'
     # determine compiler version
     if env['CXX']:
-        try:
-            pipe = subprocess.Popen([env['CXX'], '--version'],
-                                    env=env['ENV'],
-                                    stderr = subprocess.PIPE,
-                                    stdout = subprocess.PIPE)
-        except OSError:
-           return
+        pipe = SCons.Action._subproc(env, [env['CXX'], '--version'],
+                                     stderr = subprocess.PIPE,
+                                     stdout = subprocess.PIPE)
         # -dumpversion was added in GCC 3.0.  As long as we're supporting
         # GCC versions older than that, we should use --version and a
         # regular expression.
index 4e81ba847a6dcac4e188600701eddd6927ff4cef..232d64aa8d72976f53b746c5bba09a804a435db3 100644 (file)
@@ -53,13 +53,9 @@ def generate(env):
         env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
     # determine compiler version
     if env['CC']:
-        try:
-            pipe = subprocess.Popen([env['CC'], '--version'],
-                                    env=env['ENV'],
-                                    stderr = subprocess.PIPE,
-                                    stdout = subprocess.PIPE)
-        except OSError:
-           return
+        pipe = SCons.Action._subproc(env, [env['CC'], '--version'],
+                                     stderr = subprocess.PIPE,
+                                     stdout = subprocess.PIPE)
         # -dumpversion was added in GCC 3.0.  As long as we're supporting
         # GCC versions older than that, we should use --version and a
         # regular expression.