Flutter Engine
The Flutter Engine
utils.py
Go to the documentation of this file.
1# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2# for details. All rights reserved. Use of this source code is governed by a
3# BSD-style license that can be found in the LICENSE file.
4
5# This file contains a set of utilities functions used by other Python-based
6# scripts.
7
8import os
9import platform
10import queue
11import re
12import subprocess
13import sys
14import threading
15import time
16
17from io import StringIO
18from subprocess import getoutput
19
20# Try to guess the host operating system.
21def GuessOS():
22 id = platform.system()
23 if id == "Linux":
24 return "linux"
25 elif id == "Darwin":
26 return "macos"
27 elif id == "Windows" or id == "Microsoft":
28 # On Windows Vista platform.system() can return "Microsoft" with some
29 # versions of Python, see http://bugs.python.org/issue1082 for details.
30 return "win32"
31 elif id == 'FreeBSD':
32 return 'freebsd'
33 elif id == 'OpenBSD':
34 return 'openbsd'
35 elif id == 'SunOS':
36 return 'solaris'
37 else:
38 return None
39
40
41# Try to guess the host architecture.
43 id = platform.machine()
44 if id.startswith('arm'):
45 return 'arm'
46 elif (not id) or (not re.match('(x|i[3-6])86', id) is None):
47 return 'ia32'
48 elif id == 'i86pc':
49 return 'ia32'
50 else:
51 return None
52
53
54# Try to guess the number of cpus on this machine.
56 if os.path.exists("/proc/cpuinfo"):
57 return int(
58 getoutput(
59 "GREP_OPTIONS= grep -E '^processor' /proc/cpuinfo | wc -l"))
60 if os.path.exists("/usr/bin/hostinfo"):
61 return int(
62 getoutput(
63 '/usr/bin/hostinfo | GREP_OPTIONS= grep "processors are logically available." | awk "{ print \\$1 }"'
64 ))
65 win_cpu_count = os.getenv("NUMBER_OF_PROCESSORS")
66 if win_cpu_count:
67 return int(win_cpu_count)
68 return int(os.getenv("DART_NUMBER_OF_CORES", 2))
69
70
71# Returns true if we're running under Windows.
73 return GuessOS() == 'win32'
74
75
76# Reads a text file into an array of strings - one for each
77# line. Strips comments in the process.
78def ReadLinesFrom(name):
79 result = []
80 for line in open(name):
81 if '#' in line:
82 line = line[:line.find('#')]
83 line = line.strip()
84 if len(line) == 0:
85 continue
86 result.append(line)
87 return result
88
89
90# Filters out all arguments until the next '--' argument
91# occurs.
92def ListArgCallback(option, opt_str, value, parser):
93 if value is None:
94 value = []
95
96 for arg in parser.rargs:
97 if arg[:2].startswith('--'):
98 break
99 value.append(arg)
100
101 del parser.rargs[:len(value)]
102 setattr(parser.values, option.dest, value)
103
104
105# Filters out all argument until the first non '-' or the
106# '--' argument occurs.
107def ListDashArgCallback(option, opt_str, value, parser):
108 if value is None:
109 value = []
110
111 for arg in parser.rargs:
112 if arg[:2].startswith('--') or arg[0] != '-':
113 break
114 value.append(arg)
115
116 del parser.rargs[:len(value)]
117 setattr(parser.values, option.dest, value)
118
119
120# Mapping table between build mode and build configuration.
121BUILD_MODES = {
122 'debug': 'Debug',
123 'release': 'Release',
124}
125
126# Mapping table between OS and build output location.
127BUILD_ROOT = {
128 'linux': os.path.join('out'),
129 'freebsd': os.path.join('out'),
130 'macos': os.path.join('xcodebuild'),
131}
132
133
134def GetBuildMode(mode):
135 global BUILD_MODES
136 return BUILD_MODES[mode]
137
138
139def GetBuildConf(mode, arch):
140 return GetBuildMode(mode) + arch.upper()
141
142
143def GetBuildRoot(host_os, mode=None, arch=None, sanitizer=None):
144 global BUILD_ROOT
145 if mode:
146 return os.path.join(BUILD_ROOT[host_os],
147 GetBuildConf(mode, arch, sanitizer))
148 else:
149 return BUILD_ROOT[host_os]
150
151
152def RunCommand(command,
153 input=None,
154 pollFn=None,
155 outStream=None,
156 errStream=None,
157 killOnEarlyReturn=True,
158 verbose=False,
159 debug=False,
160 printErrorInfo=False):
161 """
162 Run a command, with optional input and polling function.
163
164 Args:
165 command: list of the command and its arguments.
166 input: optional string of input to feed to the command, it should be
167 short enough to fit in an i/o pipe buffer.
168 pollFn: if present will be called occasionally to check if the command
169 should be finished early. If pollFn() returns true then the command
170 will finish early.
171 outStream: if present, the stdout output of the command will be written to
172 outStream.
173 errStream: if present, the stderr output of the command will be written to
174 errStream.
175 killOnEarlyReturn: if true and pollFn returns true, then the subprocess will
176 be killed, otherwise the subprocess will be detached.
177 verbose: if true, the command is echoed to stderr.
178 debug: if true, prints debugging information to stderr.
179 printErrorInfo: if true, prints error information when the subprocess
180 returns a non-zero exit code.
181 Returns: the output of the subprocess.
182
183 Exceptions:
184 Raises Error if the subprocess returns an error code.
185 Raises ValueError if called with invalid arguments.
186 """
187 if verbose:
188 sys.stderr.write("command %s\n" % command)
189 stdin = None
190 if input:
191 stdin = subprocess.PIPE
192 try:
193 process = subprocess.Popen(
194 args=command,
195 stdin=stdin,
196 bufsize=1,
197 stdout=subprocess.PIPE,
198 stderr=subprocess.PIPE)
199 except OSError as e:
200 if not isinstance(command, str):
201 command = ' '.join(command)
202 if printErrorInfo:
203 sys.stderr.write("Command failed: '%s'\n" % command)
204 raise Error(e)
205
206 def StartThread(out):
207 queue = queue.Queue()
208
209 def EnqueueOutput(out, queue):
210 for line in iter(out.readline, b''):
211 queue.put(line)
212 out.close()
213
214 thread = threading.Thread(target=EnqueueOutput, args=(out, queue))
215 thread.daemon = True
216 thread.start()
217 return queue
218
219 outQueue = StartThread(process.stdout)
220 errQueue = StartThread(process.stderr)
221
222 def ReadQueue(queue, out, out2):
223 try:
224 while True:
225 line = queue.get(False)
226 out.write(line)
227 if out2 != None:
228 out2.write(line)
229 except queue.Empty:
230 pass
231
232 outBuf = StringIO.StringIO()
233 errorBuf = StringIO.StringIO()
234 if input:
235 process.stdin.write(input)
236 while True:
237 returncode = process.poll()
238 if returncode != None:
239 break
240 ReadQueue(errQueue, errorBuf, errStream)
241 ReadQueue(outQueue, outBuf, outStream)
242 if pollFn != None and pollFn():
243 returncode = 0
244 if killOnEarlyReturn:
245 process.kill()
246 break
247 time.sleep(0.1)
248 # Drain queue
249 ReadQueue(errQueue, errorBuf, errStream)
250 ReadQueue(outQueue, outBuf, outStream)
251
252 out = outBuf.getvalue()
253 error = errorBuf.getvalue()
254 if returncode:
255 if not isinstance(command, str):
256 command = ' '.join(command)
257 if printErrorInfo:
258 sys.stderr.write("Command failed: '%s'\n" % command)
259 sys.stderr.write(" stdout: '%s'\n" % out)
260 sys.stderr.write(" stderr: '%s'\n" % error)
261 sys.stderr.write(" returncode: %d\n" % returncode)
262 raise Error("Command failed: %s" % command)
263 if debug:
264 sys.stderr.write("output: %s\n" % out)
265 return out
266
267
268def Main(argv):
269 print("GuessOS() -> ", GuessOS())
270 print("GuessArchitecture() -> ", GuessArchitecture())
271 print("GuessCpus() -> ", GuessCpus())
272 print("IsWindows() -> ", IsWindows())
273
274
275class Error(Exception):
276 pass
277
278
279if __name__ == "__main__":
280 import sys
281 Main(sys.argv)
def print(*args, **kwargs)
Definition: run_tests.py:49
def GuessOS()
Definition: utils.py:21
def ListArgCallback(option, opt_str, value, parser)
Definition: utils.py:92
def IsWindows()
Definition: utils.py:72
def GetBuildConf(mode, arch)
Definition: utils.py:139
def RunCommand(command, input=None, pollFn=None, outStream=None, errStream=None, killOnEarlyReturn=True, verbose=False, debug=False, printErrorInfo=False)
Definition: utils.py:160
def GuessArchitecture()
Definition: utils.py:42
def ListDashArgCallback(option, opt_str, value, parser)
Definition: utils.py:107
def GetBuildMode(mode)
Definition: utils.py:134
def GuessCpus()
Definition: utils.py:55
def Main(argv)
Definition: utils.py:268
def ReadLinesFrom(name)
Definition: utils.py:78
def GetBuildRoot(host_os, mode=None, arch=None, sanitizer=None)
Definition: utils.py:143
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741