| Index: runtime/tools/utils.py
|
| diff --git a/runtime/tools/utils.py b/runtime/tools/utils.py
|
| index 7cf34bee553af2f9b10a63867971a8b966873b72..72312c59302352770a3679d3d7dae88ff22881f9 100644
|
| --- a/runtime/tools/utils.py
|
| +++ b/runtime/tools/utils.py
|
| @@ -5,10 +5,16 @@
|
| # This file contains a set of utilities functions used by other Python-based
|
| # scripts.
|
|
|
| +import commands
|
| +import os
|
| import platform
|
| +import Queue
|
| import re
|
| -import os
|
| -import commands
|
| +import StringIO
|
| +import subprocess
|
| +import sys
|
| +import threading
|
| +import time
|
|
|
|
|
| # Try to guess the host operating system.
|
| @@ -128,12 +134,116 @@ def GetBuildConf(mode, arch):
|
| return GetBuildMode(mode) + arch.upper()
|
|
|
|
|
| -def GetBuildRoot(target_os, mode=None, arch=None):
|
| +def GetBuildRoot(host_os, mode=None, arch=None):
|
| global BUILD_ROOT
|
| if mode:
|
| - return os.path.join(BUILD_ROOT[target_os], GetBuildConf(mode, arch))
|
| + return os.path.join(BUILD_ROOT[host_os], GetBuildConf(mode, arch))
|
| else:
|
| - return BUILD_ROOT[target_os]
|
| + return BUILD_ROOT[host_os]
|
| +
|
| +
|
| +def RunCommand(command, input=None, pollFn=None, outStream=None, errStream=None,
|
| + killOnEarlyReturn=True, verbose=False, debug=False,
|
| + printErrorInfo=False):
|
| + """
|
| + Run a command, with optional input and polling function.
|
| +
|
| + Args:
|
| + command: list of the command and its arguments.
|
| + input: optional string of input to feed to the command, it should be
|
| + short enough to fit in an i/o pipe buffer.
|
| + pollFn: if present will be called occasionally to check if the command
|
| + should be finished early. If pollFn() returns true then the command
|
| + will finish early.
|
| + outStream: if present, the stdout output of the command will be written to
|
| + outStream.
|
| + errStream: if present, the stderr output of the command will be written to
|
| + errStream.
|
| + killOnEarlyReturn: if true and pollFn returns true, then the subprocess will
|
| + be killed, otherwise the subprocess will be detached.
|
| + verbose: if true, the command is echoed to stderr.
|
| + debug: if true, prints debugging information to stderr.
|
| + printErrorInfo: if true, prints error information when the subprocess
|
| + returns a non-zero exit code.
|
| + Returns: the output of the subprocess.
|
| +
|
| + Raises an exception if the subprocess returns an error code.
|
| + """
|
| + if verbose:
|
| + sys.stderr.write("command %s\n" % command)
|
| + stdin = None
|
| + if input is not None:
|
| + stdin = subprocess.PIPE
|
| + try:
|
| + process = subprocess.Popen(args=command,
|
| + stdin=stdin,
|
| + bufsize=1,
|
| + stdout=subprocess.PIPE,
|
| + stderr=subprocess.PIPE)
|
| + except Exception as e:
|
| + if not isinstance(command, basestring):
|
| + command = ' '.join(command)
|
| + if printErrorInfo:
|
| + sys.stderr.write("Command failed: '%s'\n" % command)
|
| + raise e
|
| +
|
| + def StartThread(out):
|
| + queue = Queue.Queue()
|
| + def EnqueueOutput(out, queue):
|
| + for line in iter(out.readline, b''):
|
| + queue.put(line)
|
| + out.close()
|
| + thread = threading.Thread(target=EnqueueOutput, args=(out, queue))
|
| + thread.daemon = True
|
| + thread.start()
|
| + return queue
|
| + outQueue = StartThread(process.stdout)
|
| + errQueue = StartThread(process.stderr)
|
| +
|
| + def ReadQueue(queue, out, out2):
|
| + try:
|
| + while True:
|
| + line = queue.get(False)
|
| + out.write(line)
|
| + if out2 != None:
|
| + out2.write(line)
|
| + except Queue.Empty:
|
| + pass
|
| +
|
| + outBuf = StringIO.StringIO()
|
| + errorBuf = StringIO.StringIO()
|
| + if input != None:
|
| + process.stdin.write(input)
|
| + while True:
|
| + returncode = process.poll()
|
| + if returncode != None:
|
| + break
|
| + ReadQueue(errQueue, errorBuf, errStream)
|
| + ReadQueue(outQueue, outBuf, outStream)
|
| + if pollFn != None and pollFn():
|
| + returncode = 0
|
| + if killOnEarlyReturn:
|
| + process.kill()
|
| + break
|
| + time.sleep(0.1)
|
| + # Drain queue
|
| + ReadQueue(errQueue, errorBuf, errStream)
|
| + ReadQueue(outQueue, outBuf, outStream)
|
| +
|
| + out = outBuf.getvalue();
|
| + error = errorBuf.getvalue();
|
| + if returncode != 0:
|
| + if not isinstance(command, basestring):
|
| + command = ' '.join(command)
|
| + if printErrorInfo:
|
| + sys.stderr.write("Command failed: '%s'\n" % command)
|
| + sys.stderr.write(" stdout: '%s'\n" % out)
|
| + sys.stderr.write(" stderr: '%s'\n" % error)
|
| + sys.stderr.write(" returncode: %d\n" % returncode)
|
| + raise Exception("Command failed: %s" % command)
|
| + if debug:
|
| + sys.stderr.write("output: %s\n" % out)
|
| + return out
|
|
|
|
|
| def Main(argv):
|
|
|