summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Platform
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-04-23 03:54:48 (GMT)
committerSteven Knight <knight@baldmt.com>2003-04-23 03:54:48 (GMT)
commit6a62c2995bb3d60005b839a5c5a1285ecd5aa859 (patch)
treef3d9a137283b24eb6202f5ee13bb79f0075ef1d5 /src/engine/SCons/Platform
parent78d494e47d685a52b47ba9e071025be152086c74 (diff)
downloadSCons-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.py121
-rw-r--r--src/engine/SCons/Platform/win32.py50
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