mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 10:33:28 +00:00
a100968232
Bug: https://github.com/dart-lang/sdk/issues/54306 Change-Id: I3abfac0765721246b59451152d322a111d685644 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346022 Commit-Queue: William Hesse <whesse@google.com> Reviewed-by: William Hesse <whesse@google.com> Auto-Submit: Alexander Thomas <athom@google.com>
282 lines
7.9 KiB
Python
282 lines
7.9 KiB
Python
# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
# for details. All rights reserved. Use of this source code is governed by a
|
|
# BSD-style license that can be found in the LICENSE file.
|
|
|
|
# This file contains a set of utilities functions used by other Python-based
|
|
# scripts.
|
|
|
|
import os
|
|
import platform
|
|
import queue
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import threading
|
|
import time
|
|
|
|
from io import StringIO
|
|
from subprocess import getoutput
|
|
|
|
# Try to guess the host operating system.
|
|
def GuessOS():
|
|
id = platform.system()
|
|
if id == "Linux":
|
|
return "linux"
|
|
elif id == "Darwin":
|
|
return "macos"
|
|
elif id == "Windows" or id == "Microsoft":
|
|
# On Windows Vista platform.system() can return "Microsoft" with some
|
|
# versions of Python, see http://bugs.python.org/issue1082 for details.
|
|
return "win32"
|
|
elif id == 'FreeBSD':
|
|
return 'freebsd'
|
|
elif id == 'OpenBSD':
|
|
return 'openbsd'
|
|
elif id == 'SunOS':
|
|
return 'solaris'
|
|
else:
|
|
return None
|
|
|
|
|
|
# Try to guess the host architecture.
|
|
def GuessArchitecture():
|
|
id = platform.machine()
|
|
if id.startswith('arm'):
|
|
return 'arm'
|
|
elif (not id) or (not re.match('(x|i[3-6])86', id) is None):
|
|
return 'ia32'
|
|
elif id == 'i86pc':
|
|
return 'ia32'
|
|
else:
|
|
return None
|
|
|
|
|
|
# Try to guess the number of cpus on this machine.
|
|
def GuessCpus():
|
|
if os.path.exists("/proc/cpuinfo"):
|
|
return int(
|
|
getoutput(
|
|
"GREP_OPTIONS= grep -E '^processor' /proc/cpuinfo | wc -l"))
|
|
if os.path.exists("/usr/bin/hostinfo"):
|
|
return int(
|
|
getoutput(
|
|
'/usr/bin/hostinfo | GREP_OPTIONS= grep "processors are logically available." | awk "{ print \\$1 }"'
|
|
))
|
|
win_cpu_count = os.getenv("NUMBER_OF_PROCESSORS")
|
|
if win_cpu_count:
|
|
return int(win_cpu_count)
|
|
return int(os.getenv("DART_NUMBER_OF_CORES", 2))
|
|
|
|
|
|
# Returns true if we're running under Windows.
|
|
def IsWindows():
|
|
return GuessOS() == 'win32'
|
|
|
|
|
|
# Reads a text file into an array of strings - one for each
|
|
# line. Strips comments in the process.
|
|
def ReadLinesFrom(name):
|
|
result = []
|
|
for line in open(name):
|
|
if '#' in line:
|
|
line = line[:line.find('#')]
|
|
line = line.strip()
|
|
if len(line) == 0:
|
|
continue
|
|
result.append(line)
|
|
return result
|
|
|
|
|
|
# Filters out all arguments until the next '--' argument
|
|
# occurs.
|
|
def ListArgCallback(option, opt_str, value, parser):
|
|
if value is None:
|
|
value = []
|
|
|
|
for arg in parser.rargs:
|
|
if arg[:2].startswith('--'):
|
|
break
|
|
value.append(arg)
|
|
|
|
del parser.rargs[:len(value)]
|
|
setattr(parser.values, option.dest, value)
|
|
|
|
|
|
# Filters out all argument until the first non '-' or the
|
|
# '--' argument occurs.
|
|
def ListDashArgCallback(option, opt_str, value, parser):
|
|
if value is None:
|
|
value = []
|
|
|
|
for arg in parser.rargs:
|
|
if arg[:2].startswith('--') or arg[0] != '-':
|
|
break
|
|
value.append(arg)
|
|
|
|
del parser.rargs[:len(value)]
|
|
setattr(parser.values, option.dest, value)
|
|
|
|
|
|
# Mapping table between build mode and build configuration.
|
|
BUILD_MODES = {
|
|
'debug': 'Debug',
|
|
'release': 'Release',
|
|
}
|
|
|
|
# Mapping table between OS and build output location.
|
|
BUILD_ROOT = {
|
|
'linux': os.path.join('out'),
|
|
'freebsd': os.path.join('out'),
|
|
'macos': os.path.join('xcodebuild'),
|
|
}
|
|
|
|
|
|
def GetBuildMode(mode):
|
|
global BUILD_MODES
|
|
return BUILD_MODES[mode]
|
|
|
|
|
|
def GetBuildConf(mode, arch):
|
|
return GetBuildMode(mode) + arch.upper()
|
|
|
|
|
|
def GetBuildRoot(host_os, mode=None, arch=None, sanitizer=None):
|
|
global BUILD_ROOT
|
|
if mode:
|
|
return os.path.join(BUILD_ROOT[host_os],
|
|
GetBuildConf(mode, arch, sanitizer))
|
|
else:
|
|
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.
|
|
|
|
Exceptions:
|
|
Raises Error if the subprocess returns an error code.
|
|
Raises ValueError if called with invalid arguments.
|
|
"""
|
|
if verbose:
|
|
sys.stderr.write("command %s\n" % command)
|
|
stdin = None
|
|
if input:
|
|
stdin = subprocess.PIPE
|
|
try:
|
|
process = subprocess.Popen(
|
|
args=command,
|
|
stdin=stdin,
|
|
bufsize=1,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
except OSError as e:
|
|
if not isinstance(command, str):
|
|
command = ' '.join(command)
|
|
if printErrorInfo:
|
|
sys.stderr.write("Command failed: '%s'\n" % command)
|
|
raise Error(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:
|
|
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:
|
|
if not isinstance(command, str):
|
|
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 Error("Command failed: %s" % command)
|
|
if debug:
|
|
sys.stderr.write("output: %s\n" % out)
|
|
return out
|
|
|
|
|
|
def Main(argv):
|
|
print("GuessOS() -> ", GuessOS())
|
|
print("GuessArchitecture() -> ", GuessArchitecture())
|
|
print("GuessCpus() -> ", GuessCpus())
|
|
print("IsWindows() -> ", IsWindows())
|
|
|
|
|
|
class Error(Exception):
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
Main(sys.argv)
|