Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / buildbot / buildbot_pnacl_toolchain.py
1 #!/usr/bin/python
2 # Copyright (c) 2013 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import argparse
7 import logging
8 import os
9 import platform
10 import subprocess
11 import sys
12
13 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
14 import pynacl.platform
15 import pynacl.file_tools
16
17 import buildbot_lib
18 import packages
19
20 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
21 NACL_DIR = os.path.dirname(SCRIPT_DIR)
22 TOOLCHAIN_BUILD_DIR = os.path.join(NACL_DIR, 'toolchain_build')
23 TOOLCHAIN_BUILD_OUT_DIR = os.path.join(TOOLCHAIN_BUILD_DIR, 'out')
24
25 TEMP_PACKAGES_FILE = os.path.join(TOOLCHAIN_BUILD_OUT_DIR, 'packages.txt')
26
27 BUILD_DIR = os.path.join(NACL_DIR, 'build')
28 PACKAGE_VERSION_DIR = os.path.join(BUILD_DIR, 'package_version')
29 PACKAGE_VERSION_SCRIPT = os.path.join(PACKAGE_VERSION_DIR, 'package_version.py')
30
31 # As this is a buildbot script, we want verbose logging. Note however, that
32 # toolchain_build has its own log settings, controlled by its CLI flags.
33 logging.getLogger().setLevel(logging.DEBUG)
34
35 parser = argparse.ArgumentParser(description='PNaCl toolchain buildbot script')
36 group = parser.add_mutually_exclusive_group()
37 group.add_argument('--buildbot', action='store_true',
38                  help='Buildbot mode (build and archive the toolchain)')
39 group.add_argument('--trybot', action='store_true',
40                  help='Trybot mode (build but do not archove the toolchain)')
41 args = parser.parse_args()
42
43 host_os = buildbot_lib.GetHostPlatform()
44
45 # This is a minimal context, not useful for running tests yet, but enough for
46 # basic Step handling.
47 context = buildbot_lib.BuildContext()
48 buildbot_lib.SetDefaultContextAttributes(context)
49 context['pnacl'] = True
50 status = buildbot_lib.BuildStatus(context)
51
52 toolchain_install_dir = os.path.join(
53     NACL_DIR,
54     'toolchain',
55     '%s_%s' % (host_os, pynacl.platform.GetArch()),
56     'pnacl_newlib')
57
58 toolchain_build_cmd = [
59     sys.executable,
60     os.path.join(
61         NACL_DIR, 'toolchain_build', 'toolchain_build_pnacl.py'),
62     '--verbose', '--sync', '--clobber', '--build-64bit-host',
63     '--install', toolchain_install_dir,
64 ]
65
66
67 # Sync the git repos used by build.sh
68 with buildbot_lib.Step('Sync build.sh repos', status, halt_on_fail=True):
69   buildbot_lib.Command(context, toolchain_build_cmd + ['--legacy-repo-sync'])
70
71 # Clean out any installed toolchain parts that were built by previous bot runs.
72 with buildbot_lib.Step('Sync TC install dir', status):
73   pynacl.file_tools.RemoveDirectoryIfPresent(toolchain_install_dir)
74   buildbot_lib.Command(
75       context,
76       [sys.executable, PACKAGE_VERSION_SCRIPT,
77        '--packages', 'pnacl_newlib', 'sync', '--extract'])
78
79 # Run checkdeps so that the PNaCl toolchain trybots catch mistakes that would
80 # cause the normal NaCl bots to fail.
81 with buildbot_lib.Step('checkdeps', status):
82   buildbot_lib.Command(
83       context,
84       [sys.executable,
85        os.path.join(NACL_DIR, 'tools', 'checkdeps', 'checkdeps.py')])
86
87 # Test the pinned toolchain. Since we don't yet have main waterfall
88 # Windows or mac bots, we need to test the full assembled toolchain here.
89 if host_os == 'win' or host_os == 'mac' or not pynacl.platform.IsArch64Bit():
90   with buildbot_lib.Step('Test NaCl-pinned toolchain', status,
91                          halt_on_fail=False):
92     buildbot_lib.SCons(context, args=['smoke_tests'], parallel=True)
93     buildbot_lib.SCons(context, args=['large_tests'], parallel=False)
94     buildbot_lib.SCons(context, args=['pnacl_generate_pexe=0',
95                                       'nonpexe_tests'], parallel=True)
96
97
98 # toolchain_build outputs its own buildbot annotations, so don't use
99 # buildbot_lib.Step to run it here.
100 try:
101   gsd_arg = []
102   if args.buildbot:
103     gsd_arg = ['--buildbot']
104   elif args.trybot:
105     gsd_arg = ['--trybot']
106
107   cmd = toolchain_build_cmd + gsd_arg + ['--packages-file', TEMP_PACKAGES_FILE]
108   logging.info('Running: ' + ' '.join(cmd))
109   subprocess.check_call(cmd)
110
111   if args.buildbot or args.trybot:
112     # Don't upload packages from the 32-bit linux bot to avoid racing on
113     # uploading the same packages as the 64-bit linux bot
114     if host_os != 'linux' or pynacl.platform.IsArch64Bit():
115       packages.UploadPackages(TEMP_PACKAGES_FILE, args.trybot)
116
117 except subprocess.CalledProcessError:
118   # Ignore any failures and keep going (but make the bot stage red).
119   print '@@@STEP_FAILURE@@@'
120 sys.stdout.flush()
121
122 # Since mac and windows bots don't build target libraries or run tests yet,
123 # Run a basic sanity check that tests the host components (LLVM, binutils,
124 # gold plugin)
125 if host_os == 'win' or host_os == 'mac':
126   with buildbot_lib.Step('Test host binaries and gold plugin', status,
127                          halt_on_fail=False):
128     buildbot_lib.Command(
129         context,
130         [sys.executable,
131         os.path.join('tests', 'gold_plugin', 'gold_plugin_test.py'),
132         '--toolchaindir', toolchain_install_dir])
133
134 if host_os != 'win':
135   # TODO(dschuff): Fix windows regression test runner (upstream in the LLVM
136   # codebase or locally in the way we build LLVM) ASAP
137   with buildbot_lib.Step('LLVM Regression (toolchain_build)', status):
138     llvm_test = [sys.executable,
139                  os.path.join(NACL_DIR, 'pnacl', 'scripts', 'llvm-test.py'),
140                  '--llvm-regression',
141                  '--verbose']
142     buildbot_lib.Command(context, llvm_test)
143
144 with buildbot_lib.Step('Update cygwin/check bash', status, halt_on_fail=True):
145   # Update cygwin if necessary.
146   if host_os == 'win':
147     if sys.platform == 'cygwin':
148       print 'This script does not support running from inside cygwin!'
149       sys.exit(1)
150     subprocess.check_call(os.path.join(SCRIPT_DIR, 'cygwin_env.bat'))
151     print os.environ['PATH']
152     paths = os.environ['PATH'].split(os.pathsep)
153     # Put path to cygwin tools at the beginning, so cygwin tools like python
154     # and cmake will supercede others (which do not understand cygwin paths)
155     paths = [os.path.join(NACL_DIR, 'cygwin', 'bin')] + paths
156     print paths
157     os.environ['PATH'] = os.pathsep.join(paths)
158     print os.environ['PATH']
159     bash = os.path.join(NACL_DIR, 'cygwin', 'bin', 'bash')
160   else:
161     # Assume bash is in the path
162     bash = 'bash'
163
164   try:
165     print 'Bash version:'
166     sys.stdout.flush()
167     subprocess.check_call([bash , '--version'])
168   except subprocess.CalledProcessError:
169     print 'Bash not found in path!'
170     raise buildbot_lib.StepFailed()
171
172 # Now we run the PNaCl buildbot script. It in turn runs the PNaCl build.sh
173 # script and runs scons tests.
174 # TODO(dschuff): re-implement the test-running portion of buildbot_pnacl.sh
175 # using buildbot_lib, and use them here and in the non-toolchain builder.
176 buildbot_shell = os.path.join(NACL_DIR, 'buildbot', 'buildbot_pnacl.sh')
177
178 # Because patching mangles the shell script on the trybots, fix it up here
179 # so we can have working windows trybots.
180 def FixCRLF(f):
181   with open(f, 'rb') as script:
182     data = script.read().replace('\r\n', '\n')
183   with open(f, 'wb') as script:
184     script.write(data)
185
186 if host_os == 'win':
187   FixCRLF(buildbot_shell)
188   FixCRLF(os.path.join(NACL_DIR, 'pnacl', 'build.sh'))
189   FixCRLF(os.path.join(NACL_DIR, 'pnacl', 'scripts', 'common-tools.sh'))
190
191 # Generate flags for buildbot_pnacl.sh
192 if host_os == 'linux':
193   arg_os = 'linux'
194   # TODO(dschuff): Figure out if it makes sense to import the utilities from
195   # build/ into scripts from buildbot/ or only use things from buildbot_lib,
196   # or unify them in some way.
197   arch = 'x8664' if platform.machine() == 'x86_64' else 'x8632'
198 elif host_os == 'mac':
199   arg_os = 'mac'
200   arch = 'x8632'
201 elif host_os == 'win':
202   arg_os = 'win'
203   arch = 'x8664'
204 else:
205   print 'Unrecognized platform: ', host_os
206   sys.exit(1)
207
208 if args.buildbot:
209   trybot_mode = 'false'
210 elif args.trybot:
211   trybot_mode = 'true'
212
213 platform_arg = 'mode-buildbot-tc-' + arch + '-' + arg_os
214
215 command = [bash,
216            buildbot_shell,
217            platform_arg,
218            trybot_mode]
219 logging.info('Running: ' + ' '.join(command))
220 subprocess.check_call(command)