OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # Enable 'with' statements in Python 2.5 | 6 # Enable 'with' statements in Python 2.5 |
7 from __future__ import with_statement | 7 from __future__ import with_statement |
8 | 8 |
9 import os.path | 9 import os.path |
10 import platform | 10 import platform |
11 import re | 11 import re |
12 import shutil | 12 import shutil |
13 import subprocess | 13 import subprocess |
14 import sys | 14 import sys |
15 import time | 15 import time |
16 | 16 |
17 from buildbot_lib import ( | 17 from buildbot_lib import ( |
18 BuildContext, BuildStatus, Command, EnsureDirectoryExists, | 18 BuildContext, BuildStatus, Command, EnsureDirectoryExists, GNArch, |
19 ParseStandardCommandLine, RemoveDirectory, RemovePath, | 19 ParseStandardCommandLine, RemoveDirectory, RemovePath, |
20 RemoveGypBuildDirectories, RemoveSconsBuildDirectories, RunBuild, SCons, | 20 RemoveGypBuildDirectories, RemoveSconsBuildDirectories, RunBuild, SCons, |
21 SetupLinuxEnvironment, SetupMacEnvironment, SetupWindowsEnvironment, | 21 SetupLinuxEnvironment, SetupWindowsEnvironment, |
22 SetupAndroidEnvironment, Step, StepLink, StepText, TryToCleanContents, | 22 Step, StepLink, StepText, TryToCleanContents, |
23 RunningOnBuildbot) | 23 RunningOnBuildbot) |
24 | 24 |
25 | 25 |
26 def SetupContextVars(context): | 26 def SetupContextVars(context): |
27 # The branch is set to native_client on the main bots, on the trybots it's | 27 # The branch is set to native_client on the main bots, on the trybots it's |
28 # set to ''. Otherwise, we should assume a particular branch is being used. | 28 # set to ''. Otherwise, we should assume a particular branch is being used. |
29 context['branch'] = os.environ.get('BUILDBOT_BRANCH', 'native_client') | 29 context['branch'] = os.environ.get('BUILDBOT_BRANCH', 'native_client') |
30 context['off_trunk'] = context['branch'] not in ['native_client', ''] | 30 context['off_trunk'] = context['branch'] not in ['native_client', ''] |
31 | 31 |
32 | 32 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 ]) | 71 ]) |
72 # Copy html. | 72 # Copy html. |
73 Command(context, [ | 73 Command(context, [ |
74 sys.executable, gsutil, | 74 sys.executable, gsutil, |
75 'cp', '-R', '-a', 'public-read', | 75 'cp', '-R', '-a', 'public-read', |
76 'html', gs_path, | 76 'html', gs_path, |
77 ], cwd=cov_dir) | 77 ], cwd=cov_dir) |
78 print '@@@STEP_LINK@view@%s@@@' % link_url | 78 print '@@@STEP_LINK@view@%s@@@' % link_url |
79 | 79 |
80 | 80 |
81 def CommandGypBuild(context): | |
82 # Do not use goma when inside a toolchain build, because the | |
83 # freshly-built NaCl compilers will never be available via goma. | |
84 # This sacrifices the benefits of goma for building the trusted | |
85 # code too, but it's not clear how to teach Gyp to use goma for | |
86 # some compilers and not others. | |
87 use_goma = (RunningOnBuildbot() and | |
88 not context['no_goma'] and | |
89 not context['inside_toolchain']) | |
90 | |
91 if use_goma: | |
92 # Since this is for buildbot, it should not be good to use the result | |
93 # generated by the different version compiler. | |
94 os.environ['GOMA_HERMETIC'] = 'fallback' | |
95 else: | |
96 os.environ['GOMA_DISABLED'] = '1' | |
97 | |
98 runtest_py = os.environ.get('RUNTEST') | |
99 alt_runtest_py = '/b/build/scripts/slave/runtest.py' | |
100 if runtest_py is None and os.path.exists(alt_runtest_py): | |
101 runtest_py = alt_runtest_py | |
102 | |
103 # TODO(bradnelson): Figure out why win64 trybots can't upload goma logs. | |
104 buildername = os.environ.get('BUILDBOT_BUILDERNAME', '') | |
105 excluded_os = False | |
106 for name in ['win64', 'vista', 'win7-64', 'win8-64']: | |
107 if name in buildername: | |
108 excluded_os = True | |
109 | |
110 if runtest_py is None or excluded_os: | |
111 # Fallback to direct goma + ninja if not run on bots. | |
112 try: | |
113 if use_goma: | |
114 Command(context, cmd=[ | |
115 sys.executable, '/b/build/goma/goma_ctl.py', 'restart']) | |
116 cmd = ['ninja', '-v', '-k', '0', '-C', '../out/' + context['gyp_mode']] | |
117 if use_goma: | |
118 cmd += ['-j50'] | |
119 Command(context, cmd=cmd) | |
120 finally: | |
121 if use_goma: | |
122 Command(context, cmd=[ | |
123 sys.executable, '/b/build/goma/goma_ctl.py', 'stop']) | |
124 else: | |
125 # Infer the location of compile.py from runtest.py. | |
126 compile_py = os.path.join(os.path.dirname(runtest_py), 'compile.py') | |
127 cmd = [sys.executable, compile_py, '--target', context['gyp_mode'], | |
128 '--src-dir', '../', '--build-tool', 'ninja', | |
129 '--ninja-ensure-up-to-date'] | |
130 if use_goma: | |
131 cmd += ['--compiler', 'goma'] | |
132 cmd += ['--goma-dir', '/b/build/goma'] | |
133 # Verbose and but stop on fail. | |
134 cmd += ['--', '-v', '-k', '0'] | |
135 Command(context, cmd=cmd) | |
136 | |
137 | |
138 def CommandGypGenerate(context): | |
139 Command( | |
140 context, | |
141 cmd=[sys.executable, 'native_client/build/gyp_nacl'], | |
142 cwd='..') | |
143 | |
144 | |
145 def CommandGclientRunhooks(context): | 81 def CommandGclientRunhooks(context): |
146 if context.Windows(): | 82 if context.Windows(): |
147 gclient = 'gclient.bat' | 83 gclient = 'gclient.bat' |
148 else: | 84 else: |
149 gclient = 'gclient' | 85 gclient = 'gclient' |
150 print 'Running gclient runhooks...' | 86 print 'Running gclient runhooks...' |
151 print 'GYP_CROSSCOMPILE=' + context.GetEnv('GYP_CROSSCOMPILE', '') | |
152 print 'GYP_GENERATORS=' + context.GetEnv('GYP_GENERATORS', '') | |
153 print 'GYP_MSVS_VERSION=' + context.GetEnv('GYP_MSVS_VERSION', '') | |
154 print 'GYP_DEFINES=' + context.GetEnv('GYP_DEFINES', '') | |
155 Command(context, cmd=[gclient, 'runhooks', '--force']) | 87 Command(context, cmd=[gclient, 'runhooks', '--force']) |
156 | 88 |
157 | 89 |
158 def DoGNBuild(status, context, force_clang=False, force_arch=None): | 90 def DoGNBuild(status, context, force_clang=False, force_arch=None): |
| 91 if context['no_gn']: |
| 92 return False |
| 93 |
159 use_clang = force_clang or context['clang'] | 94 use_clang = force_clang or context['clang'] |
160 | 95 |
161 # Linux builds (or cross-builds) for every target. Mac builds for | 96 # Linux builds (or cross-builds) for every target. Mac builds for |
162 # x86-32 and x86-64, and can build untrusted code for others. | 97 # x86-32 and x86-64, and can build untrusted code for others. |
163 if context.Windows() and context['arch'] != '64': | 98 if context.Windows() and context['arch'] != '64': |
164 # The GN scripts for MSVC barf for a target_cpu other than x86 or x64 | 99 # The GN scripts for MSVC barf for a target_cpu other than x86 or x64 |
165 # even if we only try to build the untrusted code. Windows does build | 100 # even if we only try to build the untrusted code. Windows does build |
166 # for both x86-32 and x86-64 targets, but the GN Windows MSVC toolchain | 101 # for both x86-32 and x86-64 targets, but the GN Windows MSVC toolchain |
167 # scripts only support x86-64 hosts--and the Windows build of Clang | 102 # scripts only support x86-64 hosts--and the Windows build of Clang |
168 # only has x86-64 binaries--while NaCl's x86-32 testing bots have to be | 103 # only has x86-64 binaries--while NaCl's x86-32 testing bots have to be |
169 # actual x86-32 hosts. | 104 # actual x86-32 hosts. |
170 return False | 105 return False |
171 | 106 |
172 if force_arch is not None: | 107 if force_arch is not None: |
173 arch = force_arch | 108 arch = force_arch |
174 else: | 109 else: |
175 arch = context['arch'] | 110 arch = context['arch'] |
176 | 111 |
| 112 if context.Linux(): |
| 113 # The Linux build uses a sysroot. 'gclient runhooks' installs this |
| 114 # for the default architecture, but this might be a cross-build that |
| 115 # gclient didn't know was going to be done. The script completes |
| 116 # quickly when it's redundant with a previous run. |
| 117 with Step('update_sysroot', status): |
| 118 sysroot_arch = {'arm': 'arm', |
| 119 '32': 'i386', |
| 120 '64': 'amd64', |
| 121 'mips32': 'mips'}[arch] |
| 122 Command(context, cmd=[sys.executable, |
| 123 '../build/linux/sysroot_scripts/install-sysroot.py', |
| 124 '--arch=' + sysroot_arch]) |
| 125 |
177 out_suffix = '_' + arch | 126 out_suffix = '_' + arch |
178 if force_clang: | 127 if force_clang: |
179 out_suffix += '_clang' | 128 out_suffix += '_clang' |
180 gn_out = '../out' + out_suffix | 129 gn_out = '../out' + out_suffix |
181 | 130 |
182 def BoolFlag(cond): | 131 def BoolFlag(cond): |
183 return 'true' if cond else 'false' | 132 return 'true' if cond else 'false' |
184 | 133 |
185 gn_newlib = BoolFlag(not context['use_glibc']) | 134 gn_newlib = BoolFlag(not context['use_glibc']) |
186 gn_glibc = BoolFlag(context['use_glibc']) | 135 gn_glibc = BoolFlag(context['use_glibc']) |
187 | 136 gn_arch_name = GNArch(arch) |
188 gn_arch_name = { | |
189 'arm': 'arm', | |
190 '32': 'x86', | |
191 '64': 'x64' | |
192 }[arch] | |
193 | 137 |
194 gn_gen_args = [ | 138 gn_gen_args = [ |
195 # The Chromium GN definitions might default enable_nacl to false | 139 # The Chromium GN definitions might default enable_nacl to false |
196 # in some circumstances, but various BUILD.gn files involved in | 140 # in some circumstances, but various BUILD.gn files involved in |
197 # the standalone NaCl build assume enable_nacl==true. | 141 # the standalone NaCl build assume enable_nacl==true. |
198 'enable_nacl=true', | 142 'enable_nacl=true', |
199 'target_cpu="%s"' % gn_arch_name, | 143 'target_cpu="%s"' % gn_arch_name, |
200 'is_debug=' + context['gn_is_debug'], | 144 'is_debug=' + context['gn_is_debug'], |
201 'use_gcc_glibc=' + gn_glibc, | 145 'use_gcc_glibc=' + gn_glibc, |
202 'use_clang_newlib=' + gn_newlib, | 146 'use_clang_newlib=' + gn_newlib, |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 if context.Mac(): | 322 if context.Mac(): |
379 subprocess.call( | 323 subprocess.call( |
380 "find /var/folders -name '.org.chromium.*' -exec rm -rfv '{}' ';'", | 324 "find /var/folders -name '.org.chromium.*' -exec rm -rfv '{}' ';'", |
381 shell=True) | 325 shell=True) |
382 subprocess.call( | 326 subprocess.call( |
383 "find /var/folders -name '.com.google.Chrome*' -exec rm -rfv '{}' ';'"
, | 327 "find /var/folders -name '.com.google.Chrome*' -exec rm -rfv '{}' ';'"
, |
384 shell=True) | 328 shell=True) |
385 | 329 |
386 # Skip over hooks when run inside the toolchain build because | 330 # Skip over hooks when run inside the toolchain build because |
387 # package_version would overwrite the toolchain build. | 331 # package_version would overwrite the toolchain build. |
388 if inside_toolchain: | 332 if not inside_toolchain: |
389 with Step('gyp_generate_only', status): | |
390 CommandGypGenerate(context) | |
391 else: | |
392 with Step('gclient_runhooks', status): | 333 with Step('gclient_runhooks', status): |
393 CommandGclientRunhooks(context) | 334 CommandGclientRunhooks(context) |
394 | 335 |
395 # Always update Clang. On Linux and Mac, it's the default for the GN build. | 336 # Always update Clang. On Linux and Mac, it's the default for the GN build. |
396 # On Windows, we do a second Clang GN build. | 337 # On Windows, we do a second Clang GN build. |
397 with Step('update_clang', status): | 338 with Step('update_clang', status): |
398 Command(context, cmd=[sys.executable, '../tools/clang/scripts/update.py']) | 339 Command(context, cmd=[sys.executable, '../tools/clang/scripts/update.py']) |
399 | 340 |
400 # Make sure our GN build is working. | 341 # Make sure our GN build is working. |
401 using_gn = DoGNBuild(status, context) | 342 using_gn = DoGNBuild(status, context) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 ValidatorTest( | 383 ValidatorTest( |
443 context, 'x86-64', | 384 context, 'x86-64', |
444 'scons-out/opt-linux-x86-64/staging/ncval_new') | 385 'scons-out/opt-linux-x86-64/staging/ncval_new') |
445 | 386 |
446 return | 387 return |
447 | 388 |
448 # Run checkdeps script to vet #includes. | 389 # Run checkdeps script to vet #includes. |
449 with Step('checkdeps', status): | 390 with Step('checkdeps', status): |
450 Command(context, cmd=[sys.executable, 'tools/checkdeps/checkdeps.py']) | 391 Command(context, cmd=[sys.executable, 'tools/checkdeps/checkdeps.py']) |
451 | 392 |
452 # Make sure our Gyp build is working. | |
453 if not context['no_gyp']: | |
454 with Step('gyp_compile', status): | |
455 CommandGypBuild(context) | |
456 | |
457 # On a subset of Linux builds, build Breakpad tools for testing. | 393 # On a subset of Linux builds, build Breakpad tools for testing. |
458 if context['use_breakpad_tools']: | 394 if context['use_breakpad_tools']: |
459 with Step('breakpad configure', status): | 395 with Step('breakpad configure', status): |
460 Command(context, cmd=['mkdir', '-p', 'breakpad-out']) | 396 Command(context, cmd=['mkdir', '-p', 'breakpad-out']) |
461 Command(context, cwd='breakpad-out', | 397 Command(context, cwd='breakpad-out', |
462 cmd=['bash', '../../breakpad/configure', | 398 cmd=['bash', '../../breakpad/configure', |
463 'CXXFLAGS=-I../..']) # For third_party/lss | 399 'CXXFLAGS=-I../..']) # For third_party/lss |
464 with Step('breakpad make', status): | 400 with Step('breakpad make', status): |
465 Command(context, cmd=['make', '-j%d' % context['max_jobs'], | 401 Command(context, cmd=['make', '-j%d' % context['max_jobs'], |
466 # This avoids a broken dependency on | 402 # This avoids a broken dependency on |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 | 460 |
525 def Main(): | 461 def Main(): |
526 # TODO(ncbray) make buildbot scripts composable to support toolchain use case. | 462 # TODO(ncbray) make buildbot scripts composable to support toolchain use case. |
527 context = BuildContext() | 463 context = BuildContext() |
528 status = BuildStatus(context) | 464 status = BuildStatus(context) |
529 ParseStandardCommandLine(context) | 465 ParseStandardCommandLine(context) |
530 SetupContextVars(context) | 466 SetupContextVars(context) |
531 if context.Windows(): | 467 if context.Windows(): |
532 SetupWindowsEnvironment(context) | 468 SetupWindowsEnvironment(context) |
533 elif context.Linux(): | 469 elif context.Linux(): |
534 if context['android']: | 470 if not context['android']: |
535 SetupAndroidEnvironment(context) | |
536 else: | |
537 SetupLinuxEnvironment(context) | 471 SetupLinuxEnvironment(context) |
538 elif context.Mac(): | 472 elif context.Mac(): |
539 SetupMacEnvironment(context) | 473 # No setup to do for Mac. |
| 474 pass |
540 else: | 475 else: |
541 raise Exception("Unsupported platform.") | 476 raise Exception("Unsupported platform.") |
542 RunBuild(BuildScript, status) | 477 RunBuild(BuildScript, status) |
543 | 478 |
544 | 479 |
545 def TimedMain(): | 480 def TimedMain(): |
546 start_time = time.time() | 481 start_time = time.time() |
547 try: | 482 try: |
548 Main() | 483 Main() |
549 finally: | 484 finally: |
550 time_taken = time.time() - start_time | 485 time_taken = time.time() - start_time |
551 print 'RESULT BuildbotTime: total= %.3f minutes' % (time_taken / 60) | 486 print 'RESULT BuildbotTime: total= %.3f minutes' % (time_taken / 60) |
552 | 487 |
553 | 488 |
554 if __name__ == '__main__': | 489 if __name__ == '__main__': |
555 TimedMain() | 490 TimedMain() |
OLD | NEW |