20SCRIPT_DIR = os.path.dirname(sys.argv[0])
21DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR,
'..'))
22AVAILABLE_ARCHS = utils.ARCH_FAMILY.keys()
25usage: %%prog [options] [targets]
27This script invokes ninja to build Dart.
31 parser = argparse.ArgumentParser(
32 description=
'Runs GN (if necessary) followed by ninja',
33 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
35 config_group = parser.add_argument_group(
'Configuration Related Arguments')
36 gn_py.AddCommonConfigurationArgs(config_group)
38 gn_group = parser.add_argument_group(
'GN Related Arguments')
39 gn_py.AddCommonGnOptionArgs(gn_group)
41 other_group = parser.add_argument_group(
'Other Arguments')
42 gn_py.AddOtherArgs(other_group)
44 other_group.add_argument(
"-j",
46 help=
'Ninja -j option for RBE builds.',
47 default=200
if sys.platform ==
'win32' else 1000)
48 other_group.add_argument(
"-l",
50 help=
'Ninja -l option for RBE builds.',
52 other_group.add_argument(
"--no-start-rbe",
53 help=
"Don't try to start rbe",
56 other_group.add_argument(
58 help=
"Check that a second invocation of Ninja has nothing to do",
62 parser.add_argument(
'build_targets', nargs=
'*')
74 notification_delay =
float(
75 os.getenv(
'DART_BUILD_NOTIFICATION_DELAY', sys.float_info.max))
76 if (time.time() - start) < notification_delay:
80 message =
'Build succeeded.'
82 message =
'Build failed.'
86 if HOST_OS ==
'macos':
88 script =
'display notification "%s" with title "%s" sound name "Glass"' % (
90 command =
"osascript -e '%s' &" % script
91 elif HOST_OS ==
'linux':
93 icon =
'dialog-information'
96 command =
"notify-send -i '%s' '%s' '%s' &" % (icon, message, title)
97 elif HOST_OS ==
'win32':
103 "powershell -command \""
104 "[reflection.assembly]::loadwithpartialname('System.Windows.Forms')"
106 "[reflection.assembly]::loadwithpartialname('System.Drawing')"
108 "$n = new-object system.windows.forms.notifyicon;"
109 "$n.icon = [system.drawing.systemicons]::information;"
110 "$n.visible = $true;"
111 "$n.showballoontip(%d, '%s', '%s', "
112 "[system.windows.forms.tooltipicon]::%s);\"") % (
124 args_gn = os.path.join(out_dir,
'args.gn')
125 return 'use_rbe = true' in open(args_gn,
'r').
read()
135 global rbe_started, bootstrap_path
137 rbe_dir =
'buildtools/reclient'
138 with open(os.path.join(out_dir,
'args.gn'),
'r')
as fp:
140 if 'rbe_dir' in line:
142 rbe_dir = words[2][1:-1]
143 bootstrap_path = os.path.join(rbe_dir,
'bootstrap')
144 bootstrap_command = [bootstrap_path]
145 process = subprocess.Popen(bootstrap_command, env=env)
147 if process.returncode != 0:
148 print(
'Failed to start RBE')
155 global rbe_started, bootstrap_path
157 bootstrap_command = [bootstrap_path,
'--shutdown']
158 process = subprocess.Popen(bootstrap_command, env=env)
168 command = [
'buildtools/ninja/ninja',
'-C', out_dir]
172 if options.no_start_rbe
or StartRBE(out_dir, env):
174 command += [(
'-j%s' % str(options.j))]
175 command += [(
'-l%s' % str(options.l))]
179 return (build_config, command, using_rbe)
183 start_time = time.time()
185 process = subprocess.Popen(args, env=env, stdin=
None)
187 if process.returncode != 0:
197 args = args + [
'-n',
'-d',
'explain']
199 process = subprocess.Popen(args,
201 stdout=subprocess.PIPE,
202 stderr=subprocess.PIPE,
204 out, err = process.communicate()
206 if process.returncode != 0:
208 if 'ninja: no work to do' not in out.decode(
'utf-8'):
209 print(err.decode(
'utf-8'))
216 with io.open(
'tools/bots/test_matrix.json', encoding=
'utf-8')
as fd:
217 config = json.loads(fd.read())
219 for k, v
in config[
'sanitizer_options'].items():
221 symbolizer_path = config[
'sanitizer_symbolizer'].
get(HOST_OS,
None)
223 symbolizer_path = str(os.path.join(DART_ROOT, symbolizer_path))
224 env[
'ASAN_SYMBOLIZER_PATH'] = symbolizer_path
225 env[
'LSAN_SYMBOLIZER_PATH'] = symbolizer_path
226 env[
'MSAN_SYMBOLIZER_PATH'] = symbolizer_path
227 env[
'TSAN_SYMBOLIZER_PATH'] = symbolizer_path
228 env[
'UBSAN_SYMBOLIZER_PATH'] = symbolizer_path
235 for (build_config, args, rbe)
in configs:
239 rbe_builds.append([env, args])
244 active_rbe_builds = []
245 for (env, args)
in rbe_builds:
247 process = subprocess.Popen(args, env=env)
248 active_rbe_builds.append([args, process])
249 while active_rbe_builds:
251 for rbe_build
in active_rbe_builds:
252 (args, process) = rbe_build
253 if process.poll()
is not None:
255 active_rbe_builds.remove(rbe_build)
256 if process.returncode != 0:
257 for (_, to_kill)
in active_rbe_builds:
261 if options.check_clean:
262 for (build_config, args, rbe)
in configs:
270 starttime = time.time()
273 options = parser.parse_args()
275 targets = options.build_targets
277 if not gn_py.ProcessOptions(options):
284 env = dict(os.environ)
295 if sys.platform ==
'darwin':
296 env.pop(
'CPATH',
None)
297 env.pop(
'LIBRARY_PATH',
None)
298 env.pop(
'SDKROOT',
None)
301 gn_py.RunGnOnConfiguredConfigurations(options, env)
305 for target_os
in options.os:
306 for mode
in options.mode:
307 for arch
in options.arch:
308 for sanitizer
in options.sanitizer:
313 exit_code =
Build(configs, env, options)
315 endtime = time.time()
320 print(
"The build took %.3f seconds" % (endtime - starttime))
324if __name__ ==
'__main__':
static bool read(SkStream *stream, void *buffer, size_t amount)
def BuildOneConfig(options, targets, target_os, mode, arch, sanitizer, env)
def StartRBE(out_dir, env)
def NotifyBuildDone(build_config, success, start)
def RunOneBuildCommand(build_config, args, env)
def Build(configs, env, options)
def CheckCleanBuild(build_config, args, env)
def SanitizerEnvironmentVariables()
const myers::Point & get(const myers::Segment &)
def print(*args, **kwargs)
def GetBuildConf(mode, arch)
def GetBuildRoot(host_os, mode=None, arch=None, sanitizer=None)
static SkString join(const CommandLineFlags::StringArray &)