Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: tools/clang/scripts/update.py

Issue 1180693002: Update from https://crrev.com/333737 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/clang/scripts/run_tool.py ('k') | tools/clang/scripts/update.sh » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium 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 """Windows can't run .sh files, so this is a Python implementation of 6 """Windows can't run .sh files, so this is a Python implementation of
7 update.sh. This script should replace update.sh on all platforms eventually.""" 7 update.sh. This script should replace update.sh on all platforms eventually."""
8 8
9 import argparse 9 import argparse
10 import contextlib
11 import cStringIO
10 import os 12 import os
11 import re 13 import re
12 import shutil 14 import shutil
13 import subprocess 15 import subprocess
14 import stat 16 import stat
15 import sys 17 import sys
18 import tarfile
16 import time 19 import time
20 import urllib2
21 import zipfile
17 22
18 # Do NOT CHANGE this if you don't know what you're doing -- see 23 # Do NOT CHANGE this if you don't know what you're doing -- see
19 # https://code.google.com/p/chromium/wiki/UpdatingClang 24 # https://code.google.com/p/chromium/wiki/UpdatingClang
20 # Reverting problematic clang rolls is safe, though. 25 # Reverting problematic clang rolls is safe, though.
21 # Note: this revision is only used for Windows. Other platforms use update.sh. 26 # Note: this revision is only used for Windows. Other platforms use update.sh.
22 LLVM_WIN_REVISION = 'HEAD' 27 # TODO(thakis): Use the same revision on Windows and non-Windows.
28 # TODO(thakis): Remove update.sh, use update.py everywhere.
29 LLVM_WIN_REVISION = '238562'
23 30
24 # ASan on Windows is useful enough to use it even while the clang/win is still 31 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
25 # in bringup. Use a pinned revision to make it slightly more stable. 32 if use_head_revision:
26 use_head_revision = ('LLVM_FORCE_HEAD_REVISION' in os.environ or 33 LLVM_WIN_REVISION = 'HEAD'
27 not re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')))
28 34
29 if not use_head_revision: 35 # This is incremented when pushing a new build of Clang at the same revision.
30 LLVM_WIN_REVISION = '235968' 36 CLANG_SUB_REVISION=1
37
38 PACKAGE_VERSION = "%s-%s" % (LLVM_WIN_REVISION, CLANG_SUB_REVISION)
31 39
32 # Path constants. (All of these should be absolute paths.) 40 # Path constants. (All of these should be absolute paths.)
33 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) 41 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
34 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) 42 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
35 LLVM_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm') 43 THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
44 LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm')
45 LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
46 LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
47 'llvm-bootstrap-install')
36 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools') 48 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
37 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build', 49 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
38 'Release+Asserts') 50 'Release+Asserts')
39 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') 51 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt')
40 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang') 52 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
41 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld') 53 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
42 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt') 54 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
43 STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision') 55 LLVM_BUILD_TOOLS_DIR = os.path.abspath(
56 os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
57 STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')
58 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
44 VERSION = '3.7.0' 59 VERSION = '3.7.0'
45 60
61 # URL for pre-built binaries.
62 CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang'
63
46 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' 64 LLVM_REPO_URL='https://llvm.org/svn/llvm-project'
47 if 'LLVM_REPO_URL' in os.environ: 65 if 'LLVM_REPO_URL' in os.environ:
48 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] 66 LLVM_REPO_URL = os.environ['LLVM_REPO_URL']
49 67
50 68
69 def DownloadUrl(url, output_file):
70 """Download url into output_file."""
71 CHUNK_SIZE = 4096
72 TOTAL_DOTS = 10
73 sys.stdout.write('Downloading %s ' % url)
74 sys.stdout.flush()
75 response = urllib2.urlopen(url)
76 total_size = int(response.info().getheader('Content-Length').strip())
77 bytes_done = 0
78 dots_printed = 0
79 while True:
80 chunk = response.read(CHUNK_SIZE)
81 if not chunk:
82 break
83 output_file.write(chunk)
84 bytes_done += len(chunk)
85 num_dots = TOTAL_DOTS * bytes_done / total_size
86 sys.stdout.write('.' * (num_dots - dots_printed))
87 sys.stdout.flush()
88 dots_printed = num_dots
89 print ' Done.'
90
91
51 def ReadStampFile(): 92 def ReadStampFile():
52 """Return the contents of the stamp file, or '' if it doesn't exist.""" 93 """Return the contents of the stamp file, or '' if it doesn't exist."""
53 try: 94 try:
54 with open(STAMP_FILE, 'r') as f: 95 with open(STAMP_FILE, 'r') as f:
55 return f.read(); 96 return f.read();
56 except IOError: 97 except IOError:
57 return '' 98 return ''
58 99
59 100
60 def WriteStampFile(s): 101 def WriteStampFile(s):
61 """Write s to the stamp file.""" 102 """Write s to the stamp file."""
62 if not os.path.exists(LLVM_BUILD_DIR): 103 if not os.path.exists(LLVM_BUILD_DIR):
63 os.makedirs(LLVM_BUILD_DIR) 104 os.makedirs(LLVM_BUILD_DIR)
64 with open(STAMP_FILE, 'w') as f: 105 with open(STAMP_FILE, 'w') as f:
65 f.write(s) 106 f.write(s)
66 107
67 108
68 def PrintRevision(): 109 def GetSvnRevision(svn_repo):
69 """Print the current Clang revision.""" 110 """Returns current revision of the svn repo at svn_repo."""
70 # gyp runs update.py --print-revision even when clang isn't used. 111 svn_info = subprocess.check_output(['svn', 'info', svn_repo], shell=True)
71 # It won't use the value, but we must not error.
72 if not os.path.exists(LLVM_DIR):
73 print "0"
74 return
75
76 # TODO(hans): This needs an update when we move to prebuilt Clang binaries.
77 svn_info = subprocess.check_output(['svn', 'info', LLVM_DIR], shell=True)
78 m = re.search(r'Revision: (\d+)', svn_info) 112 m = re.search(r'Revision: (\d+)', svn_info)
79 assert m 113 return m.group(1)
80 print m.group(1)
81 114
82 115
83 def RmTree(dir): 116 def RmTree(dir):
84 """Delete dir.""" 117 """Delete dir."""
85 def ChmodAndRetry(func, path, _): 118 def ChmodAndRetry(func, path, _):
86 # Subversion can leave read-only files around. 119 # Subversion can leave read-only files around.
87 if not os.access(path, os.W_OK): 120 if not os.access(path, os.W_OK):
88 os.chmod(path, stat.S_IWUSR) 121 os.chmod(path, stat.S_IWUSR)
89 return func(path) 122 return func(path)
90 raise 123 raise
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 tool detection logic munges them in a weird way.""" 187 tool detection logic munges them in a weird way."""
155 assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_') 188 assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
156 os.mkdir(CHROME_TOOLS_SHIM_DIR) 189 os.mkdir(CHROME_TOOLS_SHIM_DIR)
157 with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f: 190 with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f:
158 f.write('# Automatically generated by tools/clang/scripts/update.py. ' + 191 f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
159 'Do not edit.\n') 192 'Do not edit.\n')
160 f.write('# Since tools/clang is located in another directory, use the \n') 193 f.write('# Since tools/clang is located in another directory, use the \n')
161 f.write('# two arg version to specify where build artifacts go. CMake\n') 194 f.write('# two arg version to specify where build artifacts go. CMake\n')
162 f.write('# disallows reuse of the same binary dir for multiple source\n') 195 f.write('# disallows reuse of the same binary dir for multiple source\n')
163 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n') 196 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
164 f.write('add_subdirectory(${CHROMIUM_TOOLS_SRC} ' + 197 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
165 '${CMAKE_CURRENT_BINARY_DIR}/a)\n') 198 f.write('if (CHROMIUM_TOOLS_SRC)\n')
199 f.write(' add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
200 '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
201 f.write('endif (CHROMIUM_TOOLS_SRC)\n')
166 202
167 203
168 def AddCMakeToPath(): 204 def AddCMakeToPath():
169 """Look for CMake and add it to PATH if it's not there already.""" 205 """Download CMake and add it to PATH."""
170 try: 206 if sys.platform == 'win32':
171 # First check if cmake is already on PATH. 207 zip_name = 'cmake-3.2.2-win32-x86.zip'
172 subprocess.call(['cmake', '--version']) 208 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR,
173 return 209 'cmake-3.2.2-win32-x86', 'bin')
174 except OSError as e: 210 else:
175 if e.errno != os.errno.ENOENT: 211 suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux'
176 raise 212 zip_name = 'cmake310_%s.tgz' % suffix
177 213 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake310', 'bin')
178 cmake_dir = 'C:\\Program Files (x86)\\CMake\\bin' 214 if not os.path.exists(cmake_dir):
179 if os.path.isdir(cmake_dir): 215 if not os.path.exists(LLVM_BUILD_TOOLS_DIR):
180 os.environ['PATH'] = os.environ.get('PATH', '') + os.pathsep + cmake_dir 216 os.makedirs(LLVM_BUILD_TOOLS_DIR)
181 return 217 # The cmake archive is smaller than 20 MB, small enough to keep in memory:
182 print 'Failed to find CMake!' 218 with contextlib.closing(cStringIO.StringIO()) as f:
183 sys.exit(1) 219 DownloadUrl(CDS_URL + '/tools/' + zip_name, f)
184 220 f.seek(0)
221 if zip_name.endswith('.zip'):
222 zipfile.ZipFile(f).extractall(path=LLVM_BUILD_TOOLS_DIR)
223 else:
224 tarfile.open(mode='r:gz', fileobj=f).extractall(path=LLVM_BUILD_DIR)
225 os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
185 226
186 vs_version = None 227 vs_version = None
187 def GetVSVersion(): 228 def GetVSVersion():
188 global vs_version 229 global vs_version
189 if vs_version: 230 if vs_version:
190 return vs_version 231 return vs_version
191 232
192 # Try using the toolchain in depot_tools. 233 # Try using the toolchain in depot_tools.
193 # This sets environment variables used by SelectVisualStudioVersion below. 234 # This sets environment variables used by SelectVisualStudioVersion below.
194 sys.path.append(os.path.join(CHROMIUM_DIR, 'build')) 235 sys.path.append(os.path.join(CHROMIUM_DIR, 'build'))
195 import vs_toolchain 236 import vs_toolchain
196 vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs() 237 vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
197 238
198 # Use gyp to find the MSVS installation, either in depot_tools as per above, 239 # Use gyp to find the MSVS installation, either in depot_tools as per above,
199 # or a system-wide installation otherwise. 240 # or a system-wide installation otherwise.
200 sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib')) 241 sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib'))
201 import gyp.MSVSVersion 242 import gyp.MSVSVersion
202 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion('2013') 243 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion('2013')
203 return vs_version 244 return vs_version
204 245
205 246
206 def SubversionCmakeArg():
207 # Since cmake's find_program can only find .exe and .com,
208 # svn.bat in depot_tools will be ignored.
209 default_pathext = ('.com', '.exe', '.bat', '.cmd')
210 for path in os.environ.get('PATH', '').split(os.pathsep):
211 for ext in default_pathext:
212 candidate = os.path.join(path, 'svn' + ext)
213 if os.path.isfile(candidate):
214 return '-DSubversion_SVN_EXECUTABLE=%s' % candidate
215 return ''
216
217
218 def UpdateClang(args): 247 def UpdateClang(args):
219 print 'Updating Clang to %s...' % (LLVM_WIN_REVISION) 248 print 'Updating Clang to %s...' % PACKAGE_VERSION
220 if LLVM_WIN_REVISION != 'HEAD' and ReadStampFile() == LLVM_WIN_REVISION: 249 if ReadStampFile() == PACKAGE_VERSION:
221 print 'Already up to date.' 250 print 'Already up to date.'
222 return 0 251 return 0
223 252
224 AddCMakeToPath()
225 # Reset the stamp file in case the build is unsuccessful. 253 # Reset the stamp file in case the build is unsuccessful.
226 WriteStampFile('') 254 WriteStampFile('')
227 255
256 if not args.force_local_build:
257 cds_file = "clang-%s.tgz" % PACKAGE_VERSION
258 cds_full_url = CDS_URL + '/Win/' + cds_file
259
260 # Check if there's a prebuilt binary and if so just fetch that. That's
261 # faster, and goma relies on having matching binary hashes on client and
262 # server too.
263 print 'Trying to download prebuilt clang'
264
265 # clang packages are smaller than 50 MB, small enough to keep in memory.
266 with contextlib.closing(cStringIO.StringIO()) as f:
267 try:
268 DownloadUrl(cds_full_url, f)
269 f.seek(0)
270 tarfile.open(mode='r:gz', fileobj=f).extractall(path=LLVM_BUILD_DIR)
271 print 'clang %s unpacked' % PACKAGE_VERSION
272 WriteStampFile(PACKAGE_VERSION)
273 return 0
274 except urllib2.HTTPError:
275 print 'Did not find prebuilt clang %s, building locally' % cds_file
276
277 AddCMakeToPath()
278
228 DeleteChromeToolsShim(); 279 DeleteChromeToolsShim();
229 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) 280 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
230 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) 281 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
231 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) 282 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
232 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) 283 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
233 CreateChromeToolsShim(); 284 CreateChromeToolsShim();
234 285
235 if not os.path.exists(LLVM_BUILD_DIR):
236 os.makedirs(LLVM_BUILD_DIR)
237 os.chdir(LLVM_BUILD_DIR)
238
239 # If building at head, define a macro that plugins can use for #ifdefing 286 # If building at head, define a macro that plugins can use for #ifdefing
240 # out code that builds at head, but not at CLANG_REVISION or vice versa. 287 # out code that builds at head, but not at CLANG_REVISION or vice versa.
241 cflags = cxxflags = '' 288 cflags = cxxflags = ''
242 289
243 # TODO(thakis): Set this only conditionally if use_head_revision once posix 290 # If building at head, define a macro that plugins can use for #ifdefing
244 # and win clang are in sync. At the moment, the plugins only build at clang 291 # out code that builds at head, but not at LLVM_WIN_REVISION or vice versa.
245 # head on posix, but they build at both head and the pinned win version :-/ 292 if use_head_revision:
246 cflags += ' -DLLVM_FORCE_HEAD_REVISION' 293 cflags += ' -DLLVM_FORCE_HEAD_REVISION'
247 cxxflags += ' -DLLVM_FORCE_HEAD_REVISION' 294 cxxflags += ' -DLLVM_FORCE_HEAD_REVISION'
248 295
249 cmake_args = ['-GNinja', '-DCMAKE_BUILD_TYPE=Release', 296 base_cmake_args = ['-GNinja',
250 '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(), 297 '-DCMAKE_BUILD_TYPE=Release',
251 '-DCMAKE_C_FLAGS=' + cflags, 298 '-DLLVM_ENABLE_ASSERTIONS=ON',
252 '-DCMAKE_CXX_FLAGS=' + cxxflags, 299 '-DLLVM_ENABLE_THREADS=OFF',
253 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join( 300 ]
254 CHROMIUM_DIR, 'tools', 'clang'),
255 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
256 301
302 cc, cxx = None, None
303 if args.bootstrap:
304 print 'Building bootstrap compiler'
305 if not os.path.exists(LLVM_BOOTSTRAP_DIR):
306 os.makedirs(LLVM_BOOTSTRAP_DIR)
307 os.chdir(LLVM_BOOTSTRAP_DIR)
308 bootstrap_args = base_cmake_args + [
309 '-DLLVM_TARGETS_TO_BUILD=host',
310 '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
311 '-DCMAKE_C_FLAGS=' + cflags,
312 '-DCMAKE_CXX_FLAGS=' + cxxflags,
313 ]
314 if cc is not None: bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
315 if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
316 RunCommand(GetVSVersion().SetupScript('x64') +
317 ['&&', 'cmake'] + bootstrap_args + [LLVM_DIR])
318 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja'])
319 if args.run_tests:
320 RunCommand(GetVSVersion().SetupScript('x64') +
321 ['&&', 'ninja', 'check-all'])
322 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'install'])
323 # TODO(thakis): Set these to clang / clang++ on posix once this script
324 # is used on posix.
325 cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
326 cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
327 # CMake has a hard time with backslashes in compiler paths:
328 # https://stackoverflow.com/questions/13050827
329 cc = cc.replace('\\', '/')
330 cxx = cxx.replace('\\', '/')
331 print 'Building final compiler'
332
333 # Build clang.
334 binutils_incdir = ''
335 if sys.platform.startswith('linux'):
336 binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include')
337
338 cmake_args = base_cmake_args + [
339 '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
340 '-DCMAKE_C_FLAGS=' + cflags,
341 '-DCMAKE_CXX_FLAGS=' + cxxflags,
342 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
343 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
344 # TODO(thakis): Append this to base_cmake_args instead once compiler-rt
345 # can build with clang-cl (http://llvm.org/PR23698)
346 if cc is not None: cmake_args.append('-DCMAKE_C_COMPILER=' + cc)
347 if cxx is not None: cmake_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
348
349 if not os.path.exists(LLVM_BUILD_DIR):
350 os.makedirs(LLVM_BUILD_DIR)
351 os.chdir(LLVM_BUILD_DIR)
257 RunCommand(GetVSVersion().SetupScript('x64') + 352 RunCommand(GetVSVersion().SetupScript('x64') +
258 ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) 353 ['&&', 'cmake'] + cmake_args + [LLVM_DIR])
259 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all']) 354 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all'])
260 355
261 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time. 356 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time.
262 # TODO(hans): Remove once the regular build above produces this. 357 # TODO(hans): Remove once the regular build above produces this.
263 if not os.path.exists(COMPILER_RT_BUILD_DIR): 358 if not os.path.exists(COMPILER_RT_BUILD_DIR):
264 os.makedirs(COMPILER_RT_BUILD_DIR) 359 os.makedirs(COMPILER_RT_BUILD_DIR)
265 os.chdir(COMPILER_RT_BUILD_DIR) 360 os.chdir(COMPILER_RT_BUILD_DIR)
361 # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
362 # above).
363 #if args.bootstrap:
364 # The bootstrap compiler produces 64-bit binaries by default.
365 #cflags += ' -m32'
366 #cxxflags += ' -m32'
367 compiler_rt_args = base_cmake_args + [
368 '-DCMAKE_C_FLAGS=' + cflags,
369 '-DCMAKE_CXX_FLAGS=' + cxxflags]
266 RunCommand(GetVSVersion().SetupScript('x86') + 370 RunCommand(GetVSVersion().SetupScript('x86') +
267 ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) 371 ['&&', 'cmake'] + compiler_rt_args + [LLVM_DIR])
268 RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt']) 372 RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt'])
269 373
270 # TODO(hans): Make this (and the .gypi and .isolate files) version number 374 # TODO(hans): Make this (and the .gypi and .isolate files) version number
271 # independent. 375 # independent.
272 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang', 376 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
273 VERSION, 'lib', 'windows') 377 VERSION, 'lib', 'windows')
274 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 378 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
275 VERSION, 'lib', 'windows') 379 VERSION, 'lib', 'windows')
276 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir, 380 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir,
277 r'^.*-i386\.lib$') 381 r'^.*-i386\.lib$')
(...skipping 10 matching lines...) Expand all
288 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 392 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
289 VERSION, 'include_sanitizer', 393 VERSION, 'include_sanitizer',
290 'sanitizer') 394 'sanitizer')
291 if not os.path.exists(aux_sanitizer_include_dir): 395 if not os.path.exists(aux_sanitizer_include_dir):
292 os.makedirs(aux_sanitizer_include_dir) 396 os.makedirs(aux_sanitizer_include_dir)
293 for _, _, files in os.walk(sanitizer_include_dir): 397 for _, _, files in os.walk(sanitizer_include_dir):
294 for f in files: 398 for f in files:
295 CopyFile(os.path.join(sanitizer_include_dir, f), 399 CopyFile(os.path.join(sanitizer_include_dir, f),
296 aux_sanitizer_include_dir) 400 aux_sanitizer_include_dir)
297 401
402 # Run tests.
403 if args.run_tests or use_head_revision:
404 os.chdir(LLVM_BUILD_DIR)
405 RunCommand(GetVSVersion().SetupScript('x64') +
406 ['&&', 'ninja', 'cr-check-all'])
298 if args.run_tests: 407 if args.run_tests:
299 os.chdir(LLVM_BUILD_DIR) 408 os.chdir(LLVM_BUILD_DIR)
300 RunCommand(GetVSVersion().SetupScript('x64') + 409 RunCommand(GetVSVersion().SetupScript('x64') +
301 ['&&', 'ninja', 'cr-check-all']) 410 ['&&', 'ninja', 'check-all'])
302 411
303 WriteStampFile(LLVM_WIN_REVISION) 412 WriteStampFile(PACKAGE_VERSION)
304 print 'Clang update was successful.' 413 print 'Clang update was successful.'
305 return 0 414 return 0
306 415
307 416
308 def main(): 417 def main():
309 if not sys.platform in ['win32', 'cygwin']: 418 if not sys.platform in ['win32', 'cygwin']:
310 # For non-Windows, fall back to update.sh. 419 # For non-Windows, fall back to update.sh.
311 # TODO(hans): Make update.py replace update.sh completely. 420 # TODO(hans): Make update.py replace update.sh completely.
312 421
313 # This script is called by gclient. gclient opens its hooks subprocesses 422 # This script is called by gclient. gclient opens its hooks subprocesses
314 # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does 423 # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does
315 # custom output processing that breaks printing '\r' characters for 424 # custom output processing that breaks printing '\r' characters for
316 # single-line updating status messages as printed by curl and wget. 425 # single-line updating status messages as printed by curl and wget.
317 # Work around this by setting stderr of the update.sh process to stdin (!): 426 # Work around this by setting stderr of the update.sh process to stdin (!):
318 # gclient doesn't redirect stdin, and while stdin itself is read-only, a 427 # gclient doesn't redirect stdin, and while stdin itself is read-only, a
319 # dup()ed sys.stdin is writable, try 428 # dup()ed sys.stdin is writable, try
320 # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi') 429 # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi')
321 # TODO: Fix gclient instead, http://crbug.com/95350 430 # TODO: Fix gclient instead, http://crbug.com/95350
322 try: 431 if '--no-stdin-hack' in sys.argv:
323 stderr = os.fdopen(os.dup(sys.stdin.fileno())) 432 sys.argv.remove('--no-stdin-hack')
324 except: 433 stderr = None
325 stderr = sys.stderr 434 else:
435 try:
436 stderr = os.fdopen(os.dup(sys.stdin.fileno()))
437 except:
438 stderr = sys.stderr
326 return subprocess.call( 439 return subprocess.call(
327 [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:], 440 [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:],
328 stderr=stderr) 441 stderr=stderr)
329 442
330 parser = argparse.ArgumentParser(description='Build Clang.') 443 parser = argparse.ArgumentParser(description='Build Clang.')
444 parser.add_argument('--bootstrap', action='store_true',
445 help='first build clang with CC, then with itself.')
446 parser.add_argument('--if-needed', action='store_true',
447 help="run only if the script thinks clang is needed")
448 parser.add_argument('--force-local-build', action='store_true',
449 help="don't try to download prebuild binaries")
450 parser.add_argument('--print-revision', action='store_true',
451 help='print current clang revision and exit.')
452 parser.add_argument('--run-tests', action='store_true',
453 help='run tests after building; only for local builds')
331 parser.add_argument('--tools', nargs='*', 454 parser.add_argument('--tools', nargs='*',
455 help='select which chrome tools to build',
332 default=['plugins', 'blink_gc_plugin']) 456 default=['plugins', 'blink_gc_plugin'])
333 # For now, this flag is only used for the non-Windows flow, but argparser gets 457 # For now, these flags are only used for the non-Windows flow, but argparser
334 # mad if it sees a flag it doesn't recognize. 458 # gets mad if it sees a flag it doesn't recognize.
335 parser.add_argument('--if-needed', action='store_true') 459 parser.add_argument('--no-stdin-hack', action='store_true')
336 parser.add_argument('--print-revision', action='store_true')
337 parser.add_argument('--run-tests', action='store_true')
338 460
339 args = parser.parse_args() 461 args = parser.parse_args()
340 462
341 if args.print_revision:
342 PrintRevision()
343 return 0
344
345 if not re.search(r'\b(clang|asan)=1', os.environ.get('GYP_DEFINES', '')):
346 print 'Skipping Clang update (clang=1 was not set in GYP_DEFINES).'
347 return 0
348
349 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): 463 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')):
350 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' 464 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
351 return 0 465 return 0
466 if args.if_needed:
467 is_clang_required = False
468 # clang is always used on Mac and Linux.
469 if sys.platform == 'darwin' or sys.platform.startswith('linux'):
470 is_clang_required = True
471 # clang requested via $GYP_DEFINES.
472 if re.search(r'\b(clang|asan|lsan|msan|tsan)=1',
473 os.environ.get('GYP_DEFINES', '')):
474 is_clang_required = True
475 # clang previously downloaded, keep it up-to-date.
476 # If you don't want this, delete third_party/llvm-build on your machine.
477 if os.path.isdir(LLVM_BUILD_DIR):
478 is_clang_required = True
479 if not is_clang_required:
480 return 0
481
482 global LLVM_WIN_REVISION, PACKAGE_VERSION
483 if args.print_revision:
484 if use_head_revision:
485 print GetSvnRevision(LLVM_DIR)
486 else:
487 print PACKAGE_VERSION
488 return 0
489
490 if LLVM_WIN_REVISION == 'HEAD':
491 # Use a real revision number rather than HEAD to make sure that the stamp
492 # file logic works.
493 LLVM_WIN_REVISION = GetSvnRevision(LLVM_REPO_URL)
494 PACKAGE_VERSION = LLVM_WIN_REVISION + '-0'
352 495
353 return UpdateClang(args) 496 return UpdateClang(args)
354 497
355 498
356 if __name__ == '__main__': 499 if __name__ == '__main__':
357 sys.exit(main()) 500 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/clang/scripts/run_tool.py ('k') | tools/clang/scripts/update.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698