Update To 11.40.268.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 parser.add_argument('--tests-arch', choices=['x86-32', 'x86-64'],
42                     default='x86-64',
43                     help='Host architecture for tests in buildbot_pnacl.sh')
44 args = parser.parse_args()
45
46 host_os = buildbot_lib.GetHostPlatform()
47
48 # This is a minimal context, not useful for running tests yet, but enough for
49 # basic Step handling.
50 context = buildbot_lib.BuildContext()
51 buildbot_lib.SetDefaultContextAttributes(context)
52 context['pnacl'] = True
53 status = buildbot_lib.BuildStatus(context)
54
55 toolchain_install_dir = os.path.join(
56     NACL_DIR,
57     'toolchain',
58     '%s_%s' % (host_os, pynacl.platform.GetArch()),
59     'pnacl_newlib')
60
61 def ToolchainBuildCmd(python_executable=None, sync=False, extra_flags=[]):
62   executable = [python_executable] if python_executable else [sys.executable]
63   sync_flag = ['--sync'] if sync else []
64
65   # The path to the script is a relative path with forward slashes so it is
66   # interpreted properly when it uses __file__ inside cygwin
67   executable_args = ['toolchain_build/toolchain_build_pnacl.py',
68                      '--verbose', '--clobber',
69                      '--install', toolchain_install_dir]
70
71   if args.buildbot:
72     executable_args.append('--buildbot')
73   elif args.trybot:
74     executable_args.append('--trybot')
75
76   # Enabling LLVM assertions have a higher cost on Windows, particularly in the
77   # presence of threads. So disable them on windows but leave them on elsewhere
78   # to get the extra error checking.
79   # See https://code.google.com/p/nativeclient/issues/detail?id=3830
80   if host_os == 'win':
81     executable_args.append('--disable-llvm-assertions')
82
83   return executable + executable_args + sync_flag + extra_flags
84
85
86 # Clean out any installed toolchain parts that were built by previous bot runs.
87 with buildbot_lib.Step('Clobber TC install dir', status):
88   print 'Removing', toolchain_install_dir
89   pynacl.file_tools.RemoveDirectoryIfPresent(toolchain_install_dir)
90
91
92 # Run checkdeps so that the PNaCl toolchain trybots catch mistakes that would
93 # cause the normal NaCl bots to fail.
94 with buildbot_lib.Step('checkdeps', status):
95   buildbot_lib.Command(
96       context,
97       [sys.executable,
98        os.path.join(NACL_DIR, 'tools', 'checkdeps', 'checkdeps.py')])
99
100
101 if host_os != 'win':
102   with buildbot_lib.Step('update clang', status):
103     buildbot_lib.Command(
104         context,
105         [sys.executable,
106          os.path.join(
107              NACL_DIR, '..', 'tools', 'clang', 'scripts', 'update.py')])
108
109 if host_os == 'win':
110   # On windows, sync with Windows git/svn rather than cygwin git/svn
111   with buildbot_lib.Step('Sync toolchain_build sources', status):
112     buildbot_lib.Command(
113       context, ToolchainBuildCmd(sync=True, extra_flags=['--sync-only']))
114
115 with buildbot_lib.Step('Update cygwin/check bash', status, halt_on_fail=True):
116   # Update cygwin if necessary.
117   if host_os == 'win':
118     if sys.platform == 'cygwin':
119       print 'This script does not support running from inside cygwin!'
120       sys.exit(1)
121     subprocess.check_call(os.path.join(SCRIPT_DIR, 'cygwin_env.bat'))
122     saved_path = os.environ['PATH']
123     print saved_path
124     paths = saved_path.split(os.pathsep)
125     # Put path to cygwin tools at the beginning, so cygwin tools like python
126     # and cmake will supercede others (which do not understand cygwin paths)
127     paths = [os.path.join(NACL_DIR, 'cygwin', 'bin')] + paths
128     print paths
129     os.environ['PATH'] = os.pathsep.join(paths)
130     print os.environ['PATH']
131     bash = os.path.join(NACL_DIR, 'cygwin', 'bin', 'bash')
132     cygwin_python = os.path.join(NACL_DIR, 'cygwin', 'bin', 'python')
133   else:
134     # Assume bash is in the path
135     bash = 'bash'
136
137   try:
138     print 'Bash version:'
139     sys.stdout.flush()
140     subprocess.check_call([bash , '--version'])
141   except subprocess.CalledProcessError:
142     print 'Bash not found in path!'
143     raise buildbot_lib.StepFailed()
144
145 # toolchain_build outputs its own buildbot annotations, so don't use
146 # buildbot_lib.Step to run it here.
147 # Always run with the system python.
148 # TODO(dschuff): remove support for cygwin python once the mingw build is rolled
149 cmd = ToolchainBuildCmd(None,
150                         host_os != 'win', # On Windows, we synced already
151                         ['--packages-file', TEMP_PACKAGES_FILE])
152 logging.info('Running: ' + ' '.join(cmd))
153 subprocess.check_call(cmd)
154
155 if args.buildbot or args.trybot:
156   # Don't upload packages from the 32-bit linux bot to avoid racing on
157   # uploading the same packages as the 64-bit linux bot
158   if host_os != 'linux' or pynacl.platform.IsArch64Bit():
159     if host_os == 'win':
160       # Since we are currently running the build in cygwin, the filenames in
161       # TEMP_PACKAGES_FILE will have cygwin paths. Convert them to system
162       # paths so we dont' have to worry about running package_version tools
163       # in cygwin.
164       converted = []
165       with open(TEMP_PACKAGES_FILE) as f:
166         for line in f:
167           converted.append(
168             subprocess.check_output(['cygpath', '-w', line]).strip())
169       with open(TEMP_PACKAGES_FILE, 'w') as f:
170         f.write('\n'.join(converted))
171     packages.UploadPackages(TEMP_PACKAGES_FILE, args.trybot)
172
173 sys.stdout.flush()
174
175 # Since mac and windows bots don't build target libraries or run tests yet,
176 # Run a basic sanity check that tests the host components (LLVM, binutils,
177 # gold plugin)
178 if host_os == 'win' or host_os == 'mac':
179   with buildbot_lib.Step('Test host binaries and gold plugin', status,
180                          halt_on_fail=False):
181     buildbot_lib.Command(
182         context,
183         [sys.executable,
184         os.path.join('tests', 'gold_plugin', 'gold_plugin_test.py'),
185         '--toolchaindir', toolchain_install_dir])
186
187 if host_os != 'win':
188   # TODO(dschuff): Fix windows regression test runner (upstream in the LLVM
189   # codebase or locally in the way we build LLVM) ASAP
190   with buildbot_lib.Step('LLVM Regression', status,
191                          halt_on_fail=False):
192     llvm_test = [sys.executable,
193                  os.path.join(NACL_DIR, 'pnacl', 'scripts', 'llvm-test.py'),
194                  '--llvm-regression',
195                  '--verbose']
196     buildbot_lib.Command(context, llvm_test)
197
198 sys.stdout.flush()
199 # On Linux we build all toolchain components (driven from this script), and then
200 # call buildbot_pnacl.sh which builds the sandboxed translator and runs tests
201 # for all the components.
202 # On Mac we build the toolchain but not the sandboxed translator, and run the
203 # same tests as the main waterfall bot (which also does not run the sandboxed
204 # translator: see https://code.google.com/p/nativeclient/issues/detail?id=3856 )
205 # On Windows we don't build the target libraries, so we can't run the SCons
206 # tests (other than the gold_plugin_test) on those platforms yet.
207 # For now full test coverage is only achieved on the main waterfall bots.
208 if host_os == 'win':
209   sys.exit(0)
210 elif host_os == 'mac':
211   subprocess.check_call([sys.executable,
212                          os.path.join(NACL_DIR, 'buildbot','buildbot_pnacl.py'),
213                          'opt', '64', 'pnacl'])
214 else:
215   # Now we run the PNaCl buildbot script. It in turn runs the PNaCl build.sh
216   # script (currently only for the sandboxed translator) and runs scons tests.
217   # TODO(dschuff): re-implement the test-running portion of buildbot_pnacl.sh
218   # using buildbot_lib, and use them here and in the non-toolchain builder.
219   buildbot_shell = os.path.join(NACL_DIR, 'buildbot', 'buildbot_pnacl.sh')
220
221   # Generate flags for buildbot_pnacl.sh
222
223   arch = 'x8664' if args.tests_arch == 'x86-64' else 'x8632'
224
225   if args.buildbot:
226     trybot_mode = 'false'
227   else:
228     trybot_mode = 'true'
229
230   platform_arg = 'mode-buildbot-tc-' + arch + '-linux'
231
232   command = [bash, buildbot_shell, platform_arg,  trybot_mode]
233   logging.info('Running: ' + ' '.join(command))
234   subprocess.check_call(command)