diff options
| author | Steven Knight <knight@baldmt.com> | 2003-04-23 03:54:48 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2003-04-23 03:54:48 (GMT) |
| commit | 6a62c2995bb3d60005b839a5c5a1285ecd5aa859 (patch) | |
| tree | f3d9a137283b24eb6202f5ee13bb79f0075ef1d5 /src/engine/SCons/Platform | |
| parent | 78d494e47d685a52b47ba9e071025be152086c74 (diff) | |
| download | SCons-6a62c2995bb3d60005b839a5c5a1285ecd5aa859.zip SCons-6a62c2995bb3d60005b839a5c5a1285ecd5aa859.tar.gz SCons-6a62c2995bb3d60005b839a5c5a1285ecd5aa859.tar.bz2 | |
Add SConf infrastructure (Autoconf functionality). (Chrisoph Wiedemann)
Diffstat (limited to 'src/engine/SCons/Platform')
| -rw-r--r-- | src/engine/SCons/Platform/posix.py | 121 | ||||
| -rw-r--r-- | src/engine/SCons/Platform/win32.py | 50 |
2 files changed, 163 insertions, 8 deletions
diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index 777b928..fd78de4 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -32,11 +32,13 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import SCons.Util -import string import os -import sys import os.path +import popen2 +import string +import sys + +import SCons.Util def escape(arg): "escape shell special characters" @@ -49,7 +51,7 @@ def escape(arg): return '"' + arg + '"' -def env_spawn(sh, escape, cmd, args, env): +def _get_env_command(sh, escape, cmd, args, env): if env: s = 'env -i ' for key in env.keys(): @@ -58,7 +60,10 @@ def env_spawn(sh, escape, cmd, args, env): s = s + escape(string.join(args)) else: s = string.join(args) + return s +def env_spawn(sh, escape, cmd, args, env): + s = _get_env_command( sh, escape, cmd, args, env) stat = os.system(s) if stat & 0xff: return stat | 0x80 @@ -82,7 +87,110 @@ def fork_spawn(sh, escape, cmd, args, env): if stat & 0xff: return stat | 0x80 return stat >> 8 - + +def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr): + # spawn using Popen3 combined with the env command + # the command name and the command's stdout is written to stdout + # the command's stderr is written to stderr + s = _get_env_command( sh, escape, cmd, args, env) + # write the command line out + if stdout != None: + stdout.write(string.join(args) + '\n') + proc = popen2.Popen3(s, 1) + # process stdout + if stdout != None: + #for line in proc.fromchild.xreadlines(): + # stdout.write(line) + while 1: + line = proc.fromchild.readline() + if not line: + break + stdout.write(line) + # process stderr + if stderr != None: + #for line in proc.childerr.xreadlines(): + # stderr.write(line) + while 1: + line = proc.childerr.readline() + if not line: + break + stderr.write(line) + stat = proc.wait() + if stat & 0xff: + return stat | 0x80 + return stat >> 8 + +def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr): + # spawn using fork / exec and providing a pipe for the command's + # stdout / stderr stream + if stdout != stderr: + (rFdOut, wFdOut) = os.pipe() + (rFdErr, wFdErr) = os.pipe() + else: + (rFdOut, wFdOut) = os.pipe() + rFdErr = rFdOut + wFdErr = wFdOut + # write the command line out + if stdout != None: + stdout.write(string.join(args) + '\n') + # do the fork + pid = os.fork() + if not pid: + # Child process + os.close( rFdOut ) + if rFdOut != rFdErr: + os.close( rFdErr ) + os.dup2( wFdOut, 1 ) # is there some symbolic way to do that ? + os.dup2( wFdErr, 2 ) + os.close( wFdOut ) + if stdout != stderr: + os.close( wFdErr ) + exitval = 127 + args = [sh, '-c', string.join(args)] + try: + os.execvpe(sh, args, env) + except OSError, e: + exitval = exitvalmap[e[0]] + stderr.write("scons: %s: %s\n" % (cmd, e[1])) + os._exit(exitval) + else: + # Parent process + pid, stat = os.waitpid(pid, 0) + os.close( wFdOut ) + if stdout != stderr: + os.close( wFdErr ) + childOut = os.fdopen( rFdOut ) + if stdout != stderr: + childErr = os.fdopen( rFdErr ) + else: + childErr = childOut + # process stdout + if stdout != None: + #for line in childOut.xreadlines(): + # stdout.write(line) + while 1: + line = childOut.readline() + if not line: + break + stdout.write(line) + # process stderr + if stderr != None: + #for line in childErr.xreadlines(): + # stderr.write(line) + while 1: + line = childErr.readline() + if not line: + break + stdout.write(line) + os.close( rFdOut ) + if stdout != stderr: + os.close( rFdErr ) + if stat & 0xff: + return stat | 0x80 + return stat >> 8 + + + def generate(env): # If the env command exists, then we can use os.system() @@ -91,8 +199,10 @@ def generate(env): # threads (i.e. -j) and is more efficient than forking Python. if env.Detect('env'): spawn = env_spawn + pspawn = piped_env_spawn else: spawn = fork_spawn + pspawn = piped_fork_spawn if not env.has_key('ENV'): env['ENV'] = {} @@ -109,6 +219,7 @@ def generate(env): env['SHLIBSUFFIX'] = '.so' env['LIBPREFIXES'] = '$LIBPREFIX' env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ] + env['PSPAWN'] = pspawn env['SPAWN'] = spawn env['SHELL'] = 'sh' env['ESCAPE'] = escape diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 4286e24..d97e61e 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -32,11 +32,14 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import SCons.Util import os import os.path +import popen2 import string import sys +import tempfile + +import SCons.Util class TempFileMunge: """A callable class. You can set an Environment variable to this, @@ -57,8 +60,6 @@ class TempFileMunge: (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= 2048: return self.cmd else: - import tempfile - # In Cygwin, we want to use rm to delete the temporary file, # because del does not exist in the sh shell. rm = env.Detect('rm') or 'del' @@ -84,6 +85,48 @@ class TempFileMunge: # you had better have cmd or command.com in your PATH when you run # scons. +def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): + if not sh: + sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n") + return 127 + else: + # NOTE: This is just a big, big hack. What we do is simply pipe the + # output to a temporary file and then write it to the streams. + # I DO NOT know the effect of adding these to a command line that + # already has indirection symbols. + tmpFile = os.path.normpath(tempfile.mktemp()) + args.append(">" + str(tmpFile)) + args.append("2>&1") + if stdout != None: + # ToDo: use the printaction instead of that + stdout.write(string.join(args) + "\n") + try: + try: + args = [sh, '/C', escape(string.join(args)) ] + ret = os.spawnve(os.P_WAIT, sh, args, env) + except OSError, e: + ret = exitvalmap[e[0]] + stderr.write("scons: %s: %s\n" % (cmd, e[1])) + try: + input = open( tmpFile, "r" ) + while 1: + line = input.readline() + if not line: + break + if stdout != None: + stdout.write(line) + if stderr != None and stderr != stdout: + stderr.write(line) + finally: + input.close() + finally: + try: + os.remove( tmpFile ) + except OSError: + # What went wrong here ?? + pass + return ret + def spawn(sh, escape, cmd, args, env): if not sh: sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n") @@ -157,6 +200,7 @@ def generate(env): env['SHLIBSUFFIX'] = '.dll' env['LIBPREFIXES'] = [ '$LIBPREFIX', '$SHLIBPREFIX' ] env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ] + env['PSPAWN'] = piped_spawn env['SPAWN'] = spawn env['SHELL'] = cmd_interp env['TEMPFILE'] = TempFileMunge |
