Public feed
#528965
import os, sys, string, tempfile, timeimport logginglog = logging.getLogger('')if sys.platform in ['win32', 'Cygwin']: from SCons.Platform.win32 import piped_spawn import scons.win32 import win32process import win32event import win32file import win32com import subprocess# This is used to comply with the SCons call backdef execute(sh, escape, cmd, args, env): if 0: log.debug(" ") log.debug("execute: %s, %s, %s, %s" % ( sh, escape, cmd, [str(x) for x in args] )) log.debug(os.getcwd()) log.debug(" ") del args[0] _spawn(cmd, args, env)def win_escape(args, env): #Quote command-line arguments for DOS/Windows conventions: just #wraps every argument which contains blanks in double quotes, and #returns a new argument list. args = [ (str(x)).encode('ascii', 'replace') for x in args] for i in range(len(args)): arg = args[i] arg = arg.replace('#', '') arg = unquote(arg) # if it starts with a /? or -? and we're on windows, it's a switch as well if arg[:8] == '/LIBPATH': switch = arg[:9] value = arg[9:] arg = switch + quote(value) elif arg[:3] == '/Fo': switch = arg[:3] value = arg[3:] arg = switch + quote(value) elif arg[:1] == '/': switch = arg[:2] value = arg[2:] arg = switch + quote(value) args[i] = arg return argsdef quote(s): if s.find(' ') != -1 or s[:2].lower() == 'c:': s = '"' + s +'"' return sdef unquote(s): while s[0] in ["'", '"'] and s[-1] in ["'", '"']: s = s[1:-1] return s# This you can call directlydef _spawn(cmd, args, env): debug = True log.debug("platform: %s" % sys.platform) if sys.platform in ['win32', 'Cygwin']: path = ['.', 'C:\WINDOWS\temp'] path += [ scons.win32.paths_vs8['bin'] ] path += [ scons.win32.paths_vs8['swig'] ] path += [ scons.win32.paths_vs8['gsoap_win'] ] path += string.split(os.environ['PATH'], ";") env['PATH'] = path ret = launchWithoutConsole(cmd, args, env, debug) return retdef launchWithoutConsole(cmd, args, env, debug=False): """Launches 'command' windowless and waits until finished""" filename = None if not os.path.isabs(cmd): cmd = findExecutable(cmd, env['PATH']) args = win_escape(args, env) #if " " in cmd: # cmd = quote(cmd.strip()) startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW if os.path.basename(cmd.lower()) in ['cl', 'cl.exe', 'link', 'link.exe']: filename, args = UseArgumentsFile(args) log.debug(" ") log.debug('='*80) log.debug(" ") log.debug("pwd: %s" % os.getcwd()) log.debug("cmd: %s" % string.join([cmd]+args, " ")) log.debug(" ") log.debug(" ") proc = subprocess.Popen([cmd] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo, shell = True) data, err = proc.communicate() rv = proc.wait() if rv: if err: log.debug("retcode: %d" % rv) if ' warning ' in err: log.warn("error: %s" % str(err)) else: log.error("error: %s" % str(err)) log.debug('='*80) log.debug(' ') log.debug(' ') # output from the program display_data( data.splitlines() ) display_data( err.splitlines() ) if filename: os.unlink(filename)def display_data(lines): import re if not lines: return rawstr = \ r"""(?P<file>.*?)[(](?P<lineno>.*?)[)]..?(?P<code>.*?)[:](?P<desc>.*)[:](?P<error>.*)$""" pat = re.compile(rawstr, re.IGNORECASE| re.DOTALL) output = [] for line in lines: line = line.strip() match = pat.search(line) if match: # Retrieve group(s) by name file = match.group('file') lineno = match.group('lineno') code = match.group('code') desc = match.group('desc') error = match.group('error') text = "%s:%s: %s: %s: %s" % (file, lineno, code, desc, error) output.append(text) # skip the echo of the command line elif line[:2] == 'cl' or \ line[:4] == 'link' or \ line[:9] == 'Microsoft' or \ line[:9] == 'Copyright' or \ line.strip() == "": continue else: output.append(line.strip()) for line in output: if line: log.error( line )def UseArgumentsFile(args): # compile arguments can get very lengthy and msdos can only handle 256 characters... # so we need to put the arguments into a file and pass the file as an argument # Use only for cl, and link import tempfile newargs = [] fileargs = [] for arg in args: # if it's /c or /Fo, let's keep those on the commandline if arg[:2] == '/c' or arg[:3] == '/Fo': newargs.append( arg ) # if it's a switch, let's put it in the file elif arg[:1] == '/' or arg[:1] == '-': fileargs.append( arg ) # if it's an object file, put it on it's own line... elif arg[-4:] == 'obj"': fileargs.append( os.linesep+arg ) else: newargs.append( arg ) log.debug( "*"*80 ) log.debug( "new args: " + str(newargs) ) log.debug( "*"*80 ) log.debug( "file args: " + str(fileargs) ) log.debug( "*"*80 ) # make it a string... data = string.join( fileargs, " " ) log.debug("temp file data: %s" % data) # write it out to a temp file filename = tempfile.mktemp(dir='.') log.debug("filename: %s" % filename) file = open(filename, 'w') file.write(data) file.close() # add this file as an argument to the compiler/linker args.insert(0, "@%s" % filename) return (filename, args)def findExecutable(cmd, paths): tmp = cmd if sys.platform in ['win32', 'Cygwin']: if cmd[-4:] not in ['.exe', '.bat', '.cmd']: cmd = cmd+'.exe' for path in paths: log.debug("looking for %s in %s" % (cmd, path)) tmp = os.path.join(str(path), cmd) tmp = os.path.normpath( tmp ) if os.path.exists(tmp): return tmp log.error("Couldn't find the executable %s" % cmd) return cmd