blob: 208b3806645ccc39ebab55219afcd06c31e64b1e [file] [log] [blame]
Brian Silvermana29ebf92014-04-23 13:08:49 -05001#!/usr/bin/python3
2
3import argparse
4import sys
5import subprocess
6import re
7import os
8import os.path
9import string
10import shutil
11import errno
12
Brian Silvermanbe6cfe22014-04-27 08:06:27 -050013def aos_path():
14 return os.path.join(os.path.dirname(__file__), '..')
15
16def get_ip(device):
17 FILENAME = os.path.normpath(os.path.join(aos_path(), '..', 'output', 'ip_base.txt'))
18 if not os.access(FILENAME, os.R_OK):
19 os.makedirs(os.path.dirname(FILENAME), exist_ok=True)
20 with open(FILENAME, 'w') as f:
21 f.write('10.9.71')
22 with open(FILENAME, 'r') as f:
23 base = f.readline()
24 if device == 'prime':
25 return base + '.179'
26 elif device == 'robot':
27 return base + '.2'
28 else:
29 raise Exception('Unknown device %s to get an IP address for.' % device)
30
Brian Silvermana9b1e5c2014-04-30 18:08:04 -070031def user_output(message):
32 print('build.py: ' + message, file=sys.stderr)
33
Brian Silvermana29ebf92014-04-23 13:08:49 -050034class Processor(object):
35 class UnknownPlatform(Exception):
36 def __init__(self, message):
37 self.message = message
38
Brian Silvermanb3d50542014-04-23 14:28:55 -050039 class Platform(object):
40 def outdir(self):
41 return os.path.join(
Brian Silvermanbe6cfe22014-04-27 08:06:27 -050042 aos_path(), '..', 'output', self.outname())
Brian Silvermanb3d50542014-04-23 14:28:55 -050043 def build_ninja(self):
44 return os.path.join(self.outdir(), 'build.ninja')
45
Brian Silvermanbe6cfe22014-04-27 08:06:27 -050046 def do_deploy(self, dry_run, command):
47 real_command = (('echo',) + command) if dry_run else command
48 subprocess.check_call(real_command, stdin=open(os.devnull, 'r'))
Brian Silvermana29ebf92014-04-23 13:08:49 -050049
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -070050 # TODO(brians): Verify that this (and its callers) catch everything from a
51 # fresh install.
52 def do_check_installed(self, other_packages):
53 all_packages = () + other_packages
54 try:
55 result = subprocess.check_output(
56 ('dpkg-query', '--show') + all_packages,
57 stdin=open(os.devnull, 'r'),
58 stderr=subprocess.STDOUT)
59 except subprocess.CalledProcessError as e:
60 user_output('Some packages not installed:\n'
61 + e.output.decode('utf-8').rstrip())
62 exit(1)
63
Brian Silvermana29ebf92014-04-23 13:08:49 -050064class CRIOProcessor(Processor):
Brian Silvermanb3d50542014-04-23 14:28:55 -050065 class Platform(Processor.Platform):
Brian Silvermana4aff562014-05-02 17:43:50 -070066 def __init__(self, debug, wind_base):
Brian Silvermanb3d50542014-04-23 14:28:55 -050067 super(CRIOProcessor.Platform, self).__init__()
68
69 self.debug = debug
Brian Silvermana4aff562014-05-02 17:43:50 -070070 self.wind_base = wind_base
Brian Silvermanb3d50542014-04-23 14:28:55 -050071
72 def __repr__(self):
73 return 'CRIOProcessor.Platform(debug=%s)' % self.debug
74 def __str__(self):
75 return 'crio%s' % ('-debug' if self.debug else '')
76
77 def outname(self):
78 return 'crio-debug' if self.debug else 'crio'
79 def os(self):
80 return 'vxworks'
81 def gyp_platform(self):
82 return 'crio'
83 def architecture(self):
84 return 'ppc'
85 def compiler(self):
86 return 'gcc'
87
Brian Silvermane48c09a2014-04-30 18:04:58 -070088 # TODO(brians): test this
Brian Silvermanbe6cfe22014-04-27 08:06:27 -050089 def deploy(self, dry_run):
90 self.do_deploy(dry_run,
91 ('ncftpput', get_ip('robot'), '/',
92 os.path.join(self.outdir(), 'lib', 'FRC_UserProgram.out')))
93
Brian Silvermana4aff562014-05-02 17:43:50 -070094 def build_env(self):
95 return {'WIND_BASE': self.wind_base}
96
Brian Silvermana29ebf92014-04-23 13:08:49 -050097 def __init__(self):
98 super(CRIOProcessor, self).__init__()
99
100 if 'WIND_BASE' in os.environ:
101 self.wind_base = os.environ['WIND_BASE']
102 else:
103 self.wind_base = '/usr/local/powerpc-wrs-vxworks/wind_base'
104
105 def parse_platforms(self, string):
Brian Silvermanb3d50542014-04-23 14:28:55 -0500106 if string is None or string == 'crio':
Brian Silvermana4aff562014-05-02 17:43:50 -0700107 return (CRIOProcessor.Platform(False, self.wind_base),)
108 elif string == 'crio-debug' or string == 'debug':
109 return (CRIOProcessor.Platform(True, self.wind_base),)
Brian Silvermanb3d50542014-04-23 14:28:55 -0500110 else:
111 raise Processor.UnknownPlatform('Unknown cRIO platform "%s".' % string)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500112
Brian Silvermanb3d50542014-04-23 14:28:55 -0500113 def extra_gyp_flags(self):
114 return ('-DWIND_BASE=%s' % self.wind_base,)
115
Brian Silvermana29ebf92014-04-23 13:08:49 -0500116 def is_crio(self): return True
117
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700118 def check_installed(self):
119 # TODO(brians): Add powerpc-wrs-vxworks (a new enough version too).
120 self.do_check_installed(
121 ('ncftp',))
122
Brian Silvermana29ebf92014-04-23 13:08:49 -0500123class PrimeProcessor(Processor):
Brian Silvermanb3d50542014-04-23 14:28:55 -0500124 class Platform(Processor.Platform):
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700125 def __init__(self, architecture, compiler, debug, sanitizer):
Brian Silvermanb3d50542014-04-23 14:28:55 -0500126 super(PrimeProcessor.Platform, self).__init__()
127
Brian Silvermana29ebf92014-04-23 13:08:49 -0500128 self.architecture = architecture
129 self.compiler = compiler
130 self.debug = debug
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700131 self.sanitizer = sanitizer
Brian Silvermana29ebf92014-04-23 13:08:49 -0500132
133 def __repr__(self):
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700134 return 'PrimeProcessor.Platform(architecture=%s, compiler=%s, debug=%s' \
135 ', sanitizer=%s)' \
136 % (self.architecture, self.compiler, self.debug, self.sanitizer)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500137 def __str__(self):
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700138 return '%s-%s%s-%s' % (self.architecture, self.compiler,
139 '-debug' if self.debug else '', self.sanitizer)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500140
141 def os(self):
142 return 'linux'
143 def gyp_platform(self):
144 return '%s-%s-%s' % (self.os(), self.architecture, self.compiler)
145
Brian Silvermana29ebf92014-04-23 13:08:49 -0500146 def outname(self):
147 return str(self)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500148
Brian Silvermane48c09a2014-04-30 18:04:58 -0700149 # TODO(brians): test this
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500150 def deploy(self, dry_run):
151 """Downloads code to the prime in a way that avoids clashing too badly with starter
152 """
153 SUM = 'md5sum'
154 TARGET_DIR = '/home/driver/robot_code/bin'
155 TEMP_DIR = '/tmp/aos_downloader'
156 TARGET = 'driver@' + get_ip('prime')
157
158 from_dir = os.path.join(self.outdir(), 'outputs')
159 sums = subprocess.check_output((SUM,) + tuple(os.listdir(from_dir)),
160 stdin=open(os.devnull, 'r'),
161 cwd=from_dir)
162 to_download = subprocess.check_output(
163 ('ssh', TARGET,
164 """rm -rf {TMPDIR} && mkdir {TMPDIR} && cd {TO_DIR}
165 && echo '{SUMS}' | {SUM} --check --quiet
166 |& grep -F FAILED | sed 's/^\\(.*\\): FAILED.*"'$'"/\\1/g'""".format(
167 TMPDIR=TEMP_DIR, TO_DIR=TARGET_DIR, SUMS=sums, SUM=SUM)))
168 if not to_download:
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700169 user_output("Nothing to download")
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500170 return
171 self.do_deploy(
172 dry_run,
173 ('scp', '-o', 'Compression yes') + to_download
174 + (('%s:%s' % (TARGET, TEMP_DIR)),))
175 if not dry_run:
176 subprocess.check_call(
177 ('ssh', TARGET,
178 """mv {TMPDIR}/* {TO_DIR}
179 && echo 'Done moving new executables into place'
180 && ionice -c 3 bash -c 'sync && sync && sync'""".format(
181 TMPDIR=TEMP_DIR, TO_DIR=TARGET_DIR)))
182
Brian Silvermana4aff562014-05-02 17:43:50 -0700183 def build_env(self):
184 r = {}
185 if self.compiler == 'clang':
186 r['LD_LIBRARY_PATH'] = '/opt/clang-3.5/lib64'
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700187 if self.sanitizer == 'address':
Brian Silvermana4aff562014-05-02 17:43:50 -0700188 r['ASAN_SYMBOLIZER_PATH'] = '/opt/clang-3.5/bin/llvm-symbolizer'
189 r['ASAN_OPTIONS'] = 'detect_leaks=1:check_initialization_order=1:strict_init_order=1'
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700190 elif self.sanitizer == 'memory':
191 r['MSAN_SYMBOLIZER_PATH'] = '/opt/clang-3.5/bin/llvm-symbolizer'
Brian Silvermana4aff562014-05-02 17:43:50 -0700192 return r
193
Brian Silvermana29ebf92014-04-23 13:08:49 -0500194 ARCHITECTURES = ['arm', 'amd64']
195 COMPILERS = ['clang', 'gcc']
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700196 # TODO(brians): memory doesn't really work because we don't have everything
197 # instrumented. Print out a warning or something.
198 SANITIZERS = ['address', 'undefined', 'integer', 'memory', 'thread', 'none']
199 PIC_SANITIZERS = ['memory', 'thread']
Brian Silvermana29ebf92014-04-23 13:08:49 -0500200
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500201 def __init__(self, is_test, is_deploy):
Brian Silvermana29ebf92014-04-23 13:08:49 -0500202 super(Processor, self).__init__()
203
204 platforms = []
205 for architecture in PrimeProcessor.ARCHITECTURES:
206 for compiler in PrimeProcessor.COMPILERS:
207 for debug in [True, False]:
208 platforms.append(
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700209 PrimeProcessor.Platform(architecture, compiler, debug, 'none'))
210 for sanitizer in PrimeProcessor.SANITIZERS:
211 if sanitizer != 'none':
212 platforms.append(
213 PrimeProcessor.Platform('amd64', 'clang', True, sanitizer))
Brian Silvermana29ebf92014-04-23 13:08:49 -0500214 self.platforms = frozenset(platforms)
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500215 if is_test:
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700216 self.default_platforms = self.select_platforms(architecture='amd64',
217 debug=True)
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500218 elif is_deploy:
219 # TODO(brians): Switch to deploying the code built with clang.
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700220 self.default_platforms = self.select_platforms(architecture='arm',
221 compiler='gcc',
222 debug=False)
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500223 else:
224 self.default_platforms = self.select_platforms(debug=False)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500225
Brian Silvermanb3d50542014-04-23 14:28:55 -0500226 def extra_gyp_flags(self):
227 return ()
Brian Silvermana29ebf92014-04-23 13:08:49 -0500228 def is_crio(self): return False
229
230 def parse_platforms(self, string):
231 if string is None:
232 return self.default_platforms
233 r = self.default_platforms
234 for part in string.split(','):
235 if part[0] == '+':
236 r = r | self.select_platforms_string(part[1:])
237 elif part[0] == '-':
238 r = r - self.select_platforms_string(part[1:])
239 elif part[0] == '=':
240 r = self.select_platforms_string(part[1:])
241 else:
Brian Silverman7cd5ad42014-04-27 08:11:30 -0500242 selected = self.select_platforms_string(part)
243 r = r - (self.platforms - selected)
244 if not r:
245 r = selected
Brian Silvermana29ebf92014-04-23 13:08:49 -0500246 return r
247
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700248 def select_platforms(self, architecture=None, compiler=None, debug=None, sanitizer=None):
Brian Silvermana29ebf92014-04-23 13:08:49 -0500249 r = []
250 for platform in self.platforms:
251 if architecture is None or platform.architecture == architecture:
252 if compiler is None or platform.compiler == compiler:
253 if debug is None or platform.debug == debug:
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700254 if sanitizer is None or platform.sanitizer == sanitizer:
255 r.append(platform)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500256 return set(r)
257
258 def select_platforms_string(self, string):
259 r = []
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700260 architecture, compiler, debug, sanitizer = None, None, None, None
Brian Silvermana29ebf92014-04-23 13:08:49 -0500261 for part in string.split('-'):
262 if part in PrimeProcessor.ARCHITECTURES:
263 architecture = part
264 elif part in PrimeProcessor.COMPILERS:
265 compiler = part
266 elif part in ['debug', 'dbg']:
267 debug = True
268 elif part in ['release', 'nodebug', 'ndb']:
269 debug = False
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700270 elif part in PrimeProcessor.SANITIZERS:
271 sanitizer = part
Brian Silvermana29ebf92014-04-23 13:08:49 -0500272 else:
273 raise Processor.UnknownPlatform('Unknown platform string component "%s".' % part)
274 return self.select_platforms(
275 architecture=architecture,
276 compiler=compiler,
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700277 debug=debug,
278 sanitizer=sanitizer)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500279
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700280 def check_installed(self):
281 self.do_check_installed(
282 ('clang-3.5', 'gcc-4.7-arm-linux-gnueabihf',
283 'g++-4.7-arm-linux-gnueabihf', 'openssh-client'))
284
Brian Silvermana29ebf92014-04-23 13:08:49 -0500285def main():
286 class TryParsingAgain(Exception):
287 pass
288
289 class TryAgainArgumentParser(argparse.ArgumentParser):
290 def __init__(self, **kwargs):
291 super(TryAgainArgumentParser, self).__init__(**kwargs)
292
293 def error(self, message):
294 raise TryParsingAgain
295
296 def SetUpParser(parser, args):
297 def AddBuildArgs(parser):
298 parser.add_argument(
299 'target',
300 help='target to build',
301 nargs='*')
302 def AddCommonArgs(parser):
303 parser.add_argument(
304 'platforms',
305 help='platform(s) to act on',
306 nargs='?')
307
308 parser.add_argument('--processor', required=True, help='prime or crio')
309 parser.add_argument('--main_gyp', required=True, help='main .gyp file')
310 subparsers = parser.add_subparsers(dest='action_name')
311
312 build_parser = subparsers.add_parser(
313 'build',
314 help='build the code (default)')
315 AddCommonArgs(build_parser)
316 AddBuildArgs(build_parser)
317
318 clean_parser = subparsers.add_parser(
319 'clean',
320 help='remove all output directories')
321 AddCommonArgs(clean_parser)
322
323 deploy_parser = subparsers.add_parser(
324 'deploy',
325 help='build and download the code')
326 AddCommonArgs(deploy_parser)
327 AddBuildArgs(deploy_parser)
328 deploy_parser.add_argument(
329 '-n', '--dry-run',
330 help="don't actually download anything",
331 action='store_true')
332
Brian Silvermane48c09a2014-04-30 18:04:58 -0700333 tests_parser = subparsers.add_parser(
334 'tests',
335 help='run tests')
336 AddCommonArgs(tests_parser)
337 AddBuildArgs(tests_parser)
338
Brian Silvermana29ebf92014-04-23 13:08:49 -0500339 return parser.parse_args(args)
340
341 try:
342 parser = TryAgainArgumentParser()
343 args = SetUpParser(parser, sys.argv[1:])
344 except TryParsingAgain:
345 parser = argparse.ArgumentParser()
346 REQUIRED_ARGS_END = 5
347 args = SetUpParser(parser, sys.argv[1:REQUIRED_ARGS_END] + ['build'] +
348 sys.argv[(REQUIRED_ARGS_END):])
349
350 if args.processor == 'crio':
351 processor = CRIOProcessor()
352 elif args.processor == 'prime':
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500353 processor = PrimeProcessor(args.action_name == 'tests',
354 args.action_name == 'deploy')
Brian Silvermana29ebf92014-04-23 13:08:49 -0500355 else:
356 parser.exit(status=1, message='Unknown processor "%s".' % args.processor)
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700357 processor.check_installed()
Brian Silvermana29ebf92014-04-23 13:08:49 -0500358
359 if 'target' in args:
360 targets = args.target[:]
361 else:
362 targets = []
363 unknown_platform_error = None
364 try:
365 platforms = processor.parse_platforms(args.platforms)
366 except Processor.UnknownPlatform as e:
367 unknown_platform_error = e.message
368 targets.append(args.platforms)
369 platforms = processor.parse_platforms(None)
370 if not platforms:
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700371 user_output("No platforms selected!")
Brian Silvermana29ebf92014-04-23 13:08:49 -0500372 exit(1)
373
374 def download_externals(argument):
375 subprocess.check_call(
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500376 (os.path.join(aos_path(), 'build', 'download_externals.sh'),
Brian Silvermana29ebf92014-04-23 13:08:49 -0500377 argument),
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500378 stdin=open(os.devnull, 'r'))
Brian Silvermana29ebf92014-04-23 13:08:49 -0500379
380 if processor.is_crio():
381 download_externals('crio')
382 else:
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700383 to_download = set()
Brian Silvermana29ebf92014-04-23 13:08:49 -0500384 for architecture in PrimeProcessor.ARCHITECTURES:
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700385 for sanitizer in PrimeProcessor.PIC_SANITIZERS:
386 if platforms & processor.select_platforms(architecture=architecture,
387 sanitizer=sanitizer):
388 to_download.add(architecture + '-fPIC')
389 if platforms & processor.select_platforms(architecture=architecture,
390 sanitizer='none'):
391 to_download.add(architecture)
392 for download_target in to_download:
393 download_externals(download_target)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500394
395 class ToolsConfig(object):
396 def __init__(self):
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500397 self.variables = {'AOS': aos_path()}
398 with open(os.path.join(aos_path(), 'build', 'tools_config'), 'r') as f:
Brian Silvermana29ebf92014-04-23 13:08:49 -0500399 for line in f:
400 if line[0] == '#':
401 pass
402 elif line.isspace():
403 pass
404 else:
405 new_name, new_value = line.rstrip().split('=')
406 for name, value in self.variables.items():
407 new_value = new_value.replace('${%s}' % name, value)
408 self.variables[new_name] = new_value
409 def __getitem__(self, key):
410 return self.variables[key]
411
412 tools_config = ToolsConfig()
413
414 def handle_clean_error(function, path, excinfo):
415 if issubclass(OSError, excinfo[0]):
416 if excinfo[1].errno == errno.ENOENT:
417 # Who cares if the file we're deleting isn't there?
418 return
419 raise excinfo[1]
420
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700421 def need_to_run_gyp(platform):
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700422 if not os.path.exists(platform.build_ninja()):
423 return True
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700424 dirs = os.listdir(os.path.join(aos_path(), '..'))
Brian Silvermana4aff562014-05-02 17:43:50 -0700425 # Looking through these folders takes a long time and isn't useful.
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700426 dirs.remove('output')
Brian Silvermana4aff562014-05-02 17:43:50 -0700427 dirs.remove('.git')
428 return not not subprocess.check_output(
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700429 ('find',) + tuple(os.path.join(aos_path(), '..', d) for d in dirs)
430 + ('-newer', platform.build_ninja(),
431 '(', '-name', '*.gyp', '-or', '-name', '*.gypi', ')'),
Brian Silvermana4aff562014-05-02 17:43:50 -0700432 stdin=open(os.devnull, 'r'))
433
434 def env(platform):
435 build_env = dict(platform.build_env())
436 build_env['TERM'] = os.environ['TERM']
437 build_env['PATH'] = os.environ['PATH']
438 return build_env
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700439
440 num = 1
Brian Silvermana29ebf92014-04-23 13:08:49 -0500441 for platform in platforms:
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700442 user_output('Building %s (%d/%d)...' % (platform, num, len(platforms)))
Brian Silvermana29ebf92014-04-23 13:08:49 -0500443 if args.action_name == 'clean':
444 shutil.rmtree(platform.outdir(), onerror=handle_clean_error)
445 else:
446 if need_to_run_gyp(platform):
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700447 user_output('Running gyp...')
Brian Silvermana29ebf92014-04-23 13:08:49 -0500448 gyp = subprocess.Popen(
449 (tools_config['GYP'],
450 '--check',
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500451 '--depth=%s' % os.path.join(aos_path(), '..'),
Brian Silvermana29ebf92014-04-23 13:08:49 -0500452 '--no-circular-check',
453 '-f', 'ninja',
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500454 '-I%s' % os.path.join(aos_path(), 'build', 'aos.gypi'),
Brian Silvermana29ebf92014-04-23 13:08:49 -0500455 '-I/dev/stdin', '-Goutput_dir=output',
456 '-DOS=%s' % platform.os(),
457 '-DPLATFORM=%s' % platform.gyp_platform(),
458 '-DARCHITECTURE=%s' % platform.architecture,
459 '-DCOMPILER=%s' % platform.compiler,
Brian Silvermanf0d3c782014-05-02 23:56:32 -0700460 '-DDEBUG=%s' % ('yes' if platform.debug else 'no'),
461 '-DSANITIZER=%s' % platform.sanitizer,
462 '-DSANITIZER_FPIC=%s' % ('-fPIC'
463 if platform.sanitizer in PrimeProcessor.PIC_SANITIZERS
464 else '')) +
Brian Silvermanb3d50542014-04-23 14:28:55 -0500465 processor.extra_gyp_flags() + (args.main_gyp,),
Brian Silvermana29ebf92014-04-23 13:08:49 -0500466 stdin=subprocess.PIPE)
467 gyp.communicate(("""
468{
469 'target_defaults': {
470 'configurations': {
471 '%s': {}
472 }
473 }
474}""" % platform.outname()).encode())
475 if gyp.returncode:
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700476 user_output("Running gyp failed!")
Brian Silvermana29ebf92014-04-23 13:08:49 -0500477 exit(1)
Brian Silvermanb3d50542014-04-23 14:28:55 -0500478 if processor.is_crio():
479 subprocess.check_call(
480 ('sed', '-i',
481 's/nm -gD/nm/g', platform.build_ninja()),
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500482 stdin=open(os.devnull, 'r'))
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700483 user_output('Done running gyp.')
Brian Silvermana29ebf92014-04-23 13:08:49 -0500484 else:
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700485 user_output("Not running gyp.")
Brian Silvermana29ebf92014-04-23 13:08:49 -0500486
487 try:
488 subprocess.check_call(
489 (tools_config['NINJA'],
490 '-C', platform.outdir()) + tuple(targets),
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500491 stdin=open(os.devnull, 'r'),
Brian Silvermana4aff562014-05-02 17:43:50 -0700492 env=env(platform))
Brian Silvermana29ebf92014-04-23 13:08:49 -0500493 except subprocess.CalledProcessError as e:
494 if unknown_platform_error is not None:
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700495 user_output(unknown_platform_error)
Brian Silvermana29ebf92014-04-23 13:08:49 -0500496 raise e
497
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500498 if args.action_name == 'deploy':
499 platform.deploy(args.dry_run)
Brian Silvermane48c09a2014-04-30 18:04:58 -0700500 elif args.action_name == 'tests':
501 dirname = os.path.join(platform.outdir(), 'tests')
502 for f in targets or os.listdir(dirname):
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700503 user_output('Running test %s...' % f)
Brian Silvermana4aff562014-05-02 17:43:50 -0700504 subprocess.check_call(
505 os.path.join(dirname, f),
506 env=env(platform))
Brian Silvermana9b1e5c2014-04-30 18:08:04 -0700507 user_output('Test %s succeeded' % f)
Brian Silvermanbe6cfe22014-04-27 08:06:27 -0500508
Brian Silvermanc2d8e5a2014-05-01 18:33:12 -0700509 user_output('Done building %s (%d/%d)' % (platform, num, len(platforms)))
510 num += 1
Brian Silvermana29ebf92014-04-23 13:08:49 -0500511
512if __name__ == '__main__':
513 main()