| 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 |