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

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

Issue 1688183004: use gsutil to download clang et al binaries (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | no next file » | 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 """This script is used to download prebuilt clang binaries. 6 """This script is used to download prebuilt clang binaries.
7 7
8 It is also used by package.py to build the prebuilt clang binaries.""" 8 It is also used by package.py to build the prebuilt clang binaries."""
9 9
10 import argparse 10 import argparse
11 import distutils.spawn 11 import distutils.spawn
12 import glob 12 import glob
13 import os 13 import os
14 import pipes 14 import pipes
15 import re 15 import re
16 import shutil 16 import shutil
17 import subprocess 17 import subprocess
18 import stat 18 import stat
19 import sys 19 import sys
20 import tarfile 20 import tarfile
21 import tempfile 21 import tempfile
22 import time 22 import time
23 import urllib2
24 import zipfile 23 import zipfile
25 24
26 # Do NOT CHANGE this if you don't know what you're doing -- see 25 # Do NOT CHANGE this if you don't know what you're doing -- see
27 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md 26 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
28 # Reverting problematic clang rolls is safe, though. 27 # Reverting problematic clang rolls is safe, though.
29 CLANG_REVISION = '259396' 28 CLANG_REVISION = '259396'
30 29
31 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ 30 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
32 if use_head_revision: 31 if use_head_revision:
33 CLANG_REVISION = 'HEAD' 32 CLANG_REVISION = 'HEAD'
(...skipping 28 matching lines...) Expand all
62 LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi') 61 LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
63 LLVM_BUILD_TOOLS_DIR = os.path.abspath( 62 LLVM_BUILD_TOOLS_DIR = os.path.abspath(
64 os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) 63 os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
65 STAMP_FILE = os.path.normpath( 64 STAMP_FILE = os.path.normpath(
66 os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')) 65 os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision'))
67 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils') 66 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
68 VERSION = '3.9.0' 67 VERSION = '3.9.0'
69 ANDROID_NDK_DIR = os.path.join( 68 ANDROID_NDK_DIR = os.path.join(
70 CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk') 69 CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk')
71 70
72 # URL for pre-built binaries. 71 sys.path.insert(0, os.path.join(CHROMIUM_DIR, 'build'))
73 CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang' 72 import find_depot_tools
73 DEPOT_PATH = find_depot_tools.add_depot_tools_to_path()
74 GSUTIL_PATH = os.path.join(DEPOT_PATH, 'gsutil.py')
75
76 # Google Storage bucket where the pre-built binaries are kept.
77 CDS_BUCKET = 'gs://chromium-browser-clang'
74 78
75 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' 79 LLVM_REPO_URL='https://llvm.org/svn/llvm-project'
76 if 'LLVM_REPO_URL' in os.environ: 80 if 'LLVM_REPO_URL' in os.environ:
77 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] 81 LLVM_REPO_URL = os.environ['LLVM_REPO_URL']
78 82
79 83
80 def DownloadUrl(url, output_file): 84 def DownloadFile(source, output_file):
81 """Download url into output_file.""" 85 """Download google storage source into output_file."""
82 CHUNK_SIZE = 4096
83 TOTAL_DOTS = 10
84 num_retries = 3 86 num_retries = 3
85 retry_wait_s = 5 # Doubled at each retry. 87 retry_wait_s = 5 # Doubled at each retry.
86 88
87 while True: 89 while True:
88 try: 90 try:
89 sys.stdout.write('Downloading %s ' % url) 91 sys.stdout.write('Downloading %s ' % source)
90 sys.stdout.flush() 92 sys.stdout.flush()
91 response = urllib2.urlopen(url) 93 cmd = ['python', GSUTIL_PATH, 'cp', source, output_file]
92 total_size = int(response.info().getheader('Content-Length').strip()) 94 subprocess.check_call(cmd, stderr=open('/dev/null', 'w'))
hans 2016/02/12 00:39:11 What does the error message look like for the user
Mostyn Bramley-Moore 2016/02/12 00:43:33 This is what I get on a throttled/blocked machine,
hans 2016/02/12 01:42:33 I assume opening /dev/null doesn't work on Windows
hans 2016/02/12 01:42:33 That's pretty opaque. The current code will tell t
Mostyn Bramley-Moore 2016/02/15 13:29:44 Ahh, right- I copied this pattern from build/downl
93 bytes_done = 0
94 dots_printed = 0
95 while True:
96 chunk = response.read(CHUNK_SIZE)
97 if not chunk:
98 break
99 output_file.write(chunk)
100 bytes_done += len(chunk)
101 num_dots = TOTAL_DOTS * bytes_done / total_size
102 sys.stdout.write('.' * (num_dots - dots_printed))
103 sys.stdout.flush()
104 dots_printed = num_dots
105 if bytes_done != total_size:
106 raise urllib2.URLError("only got %d of %d bytes" %
107 (bytes_done, total_size))
108 print ' Done.'
109 return 95 return
110 except urllib2.URLError as e: 96 except Exception as e:
111 sys.stdout.write('\n') 97 sys.stdout.write('\n')
112 print e 98 print e
113 if num_retries == 0 or isinstance(e, urllib2.HTTPError) and e.code == 404: 99 if num_retries == 0: # TODO(mostynb): exit early on 404?
114 raise e 100 raise e
115 num_retries -= 1 101 num_retries -= 1
116 print 'Retrying in %d s ...' % retry_wait_s 102 print 'Retrying in %d s ...' % retry_wait_s
117 time.sleep(retry_wait_s) 103 time.sleep(retry_wait_s)
118 retry_wait_s *= 2 104 retry_wait_s *= 2
119 105
120 106
121 def EnsureDirExists(path): 107 def EnsureDirExists(path):
122 if not os.path.exists(path): 108 if not os.path.exists(path):
123 print "Creating directory %s" % path 109 print "Creating directory %s" % path
124 os.makedirs(path) 110 os.makedirs(path)
125 111
126 112
127 def DownloadAndUnpack(url, output_dir): 113 def DownloadAndUnpack(source, output_dir):
128 with tempfile.TemporaryFile() as f: 114 with tempfile.NamedTemporaryFile() as f:
129 DownloadUrl(url, f) 115 DownloadFile(source, f.name)
130 f.seek(0) 116 f.seek(0)
131 EnsureDirExists(output_dir) 117 EnsureDirExists(output_dir)
132 if url.endswith('.zip'): 118 if source.endswith('.zip'):
133 zipfile.ZipFile(f).extractall(path=output_dir) 119 zipfile.ZipFile(f).extractall(path=output_dir)
134 else: 120 else:
135 tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir) 121 tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir)
136 122
137 123
138 def ReadStampFile(): 124 def ReadStampFile():
139 """Return the contents of the stamp file, or '' if it doesn't exist.""" 125 """Return the contents of the stamp file, or '' if it doesn't exist."""
140 try: 126 try:
141 with open(STAMP_FILE, 'r') as f: 127 with open(STAMP_FILE, 'r') as f:
142 return f.read().rstrip() 128 return f.read().rstrip()
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 def DownloadHostGcc(args): 264 def DownloadHostGcc(args):
279 """Downloads gcc 4.8.2 and makes sure args.gcc_toolchain is set.""" 265 """Downloads gcc 4.8.2 and makes sure args.gcc_toolchain is set."""
280 if not sys.platform.startswith('linux') or args.gcc_toolchain: 266 if not sys.platform.startswith('linux') or args.gcc_toolchain:
281 return 267 return
282 # Unconditionally download a prebuilt gcc to guarantee the included libstdc++ 268 # Unconditionally download a prebuilt gcc to guarantee the included libstdc++
283 # works on Ubuntu Precise. 269 # works on Ubuntu Precise.
284 gcc_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gcc482precise') 270 gcc_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gcc482precise')
285 if not os.path.exists(gcc_dir): 271 if not os.path.exists(gcc_dir):
286 print 'Downloading pre-built GCC 4.8.2...' 272 print 'Downloading pre-built GCC 4.8.2...'
287 DownloadAndUnpack( 273 DownloadAndUnpack(
288 CDS_URL + '/tools/gcc482precise.tgz', LLVM_BUILD_TOOLS_DIR) 274 CDS_BUCKET + '/tools/gcc482precise.tgz', LLVM_BUILD_TOOLS_DIR)
289 args.gcc_toolchain = gcc_dir 275 args.gcc_toolchain = gcc_dir
290 276
291 277
292 def AddCMakeToPath(): 278 def AddCMakeToPath():
293 """Download CMake and add it to PATH.""" 279 """Download CMake and add it to PATH."""
294 if sys.platform == 'win32': 280 if sys.platform == 'win32':
295 zip_name = 'cmake-3.2.2-win32-x86.zip' 281 zip_name = 'cmake-3.2.2-win32-x86.zip'
296 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 282 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR,
297 'cmake-3.2.2-win32-x86', 'bin') 283 'cmake-3.2.2-win32-x86', 'bin')
298 else: 284 else:
299 suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux' 285 suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux'
300 zip_name = 'cmake322_%s.tgz' % suffix 286 zip_name = 'cmake322_%s.tgz' % suffix
301 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake322', 'bin') 287 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake322', 'bin')
302 if not os.path.exists(cmake_dir): 288 if not os.path.exists(cmake_dir):
303 DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR) 289 DownloadAndUnpack(CDS_BUCKET + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
304 os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '') 290 os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
305 291
306 292
307 vs_version = None 293 vs_version = None
308 def GetVSVersion(): 294 def GetVSVersion():
309 global vs_version 295 global vs_version
310 if vs_version: 296 if vs_version:
311 return vs_version 297 return vs_version
312 298
313 # Try using the toolchain in depot_tools. 299 # Try using the toolchain in depot_tools.
(...skipping 23 matching lines...) Expand all
337 if not need_gold_plugin or os.path.exists( 323 if not need_gold_plugin or os.path.exists(
338 os.path.join(LLVM_BUILD_DIR, "lib/LLVMgold.so")): 324 os.path.join(LLVM_BUILD_DIR, "lib/LLVMgold.so")):
339 return 0 325 return 0
340 326
341 # Reset the stamp file in case the build is unsuccessful. 327 # Reset the stamp file in case the build is unsuccessful.
342 WriteStampFile('') 328 WriteStampFile('')
343 329
344 if not args.force_local_build: 330 if not args.force_local_build:
345 cds_file = "clang-%s.tgz" % PACKAGE_VERSION 331 cds_file = "clang-%s.tgz" % PACKAGE_VERSION
346 if sys.platform == 'win32' or sys.platform == 'cygwin': 332 if sys.platform == 'win32' or sys.platform == 'cygwin':
347 cds_full_url = CDS_URL + '/Win/' + cds_file 333 cds_source = CDS_BUCKET + '/Win/' + cds_file
348 elif sys.platform == 'darwin': 334 elif sys.platform == 'darwin':
349 cds_full_url = CDS_URL + '/Mac/' + cds_file 335 cds_source = CDS_BUCKET + '/Mac/' + cds_file
350 else: 336 else:
351 assert sys.platform.startswith('linux') 337 assert sys.platform.startswith('linux')
352 cds_full_url = CDS_URL + '/Linux_x64/' + cds_file 338 cds_source = CDS_BUCKET + '/Linux_x64/' + cds_file
353 339
354 print 'Downloading prebuilt clang' 340 print 'Downloading prebuilt clang'
355 if os.path.exists(LLVM_BUILD_DIR): 341 if os.path.exists(LLVM_BUILD_DIR):
356 RmTree(LLVM_BUILD_DIR) 342 RmTree(LLVM_BUILD_DIR)
357 try: 343 try:
358 DownloadAndUnpack(cds_full_url, LLVM_BUILD_DIR) 344 DownloadAndUnpack(cds_source, LLVM_BUILD_DIR)
359 print 'clang %s unpacked' % PACKAGE_VERSION 345 print 'clang %s unpacked' % PACKAGE_VERSION
360 # Download the gold plugin if requested to by an environment variable. 346 # Download the gold plugin if requested to by an environment variable.
361 # This is used by the CFI ClusterFuzz bot, and it's required for official 347 # This is used by the CFI ClusterFuzz bot, and it's required for official
362 # builds on linux. 348 # builds on linux.
363 if need_gold_plugin: 349 if need_gold_plugin:
364 RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py']) 350 RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
365 WriteStampFile(PACKAGE_VERSION) 351 WriteStampFile(PACKAGE_VERSION)
366 return 0 352 return 0
367 except urllib2.URLError: 353 except Exception:
hans 2016/02/12 01:42:33 This exception handler is much broader than the pr
368 print 'Failed to download prebuilt clang %s' % cds_file 354 print 'Failed to download prebuilt clang %s' % cds_file
369 print 'Use --force-local-build if you want to build locally.' 355 print 'Use --force-local-build if you want to build locally.'
370 print 'Exiting.' 356 print 'Exiting.'
371 return 1 357 return 1
372 358
373 if args.with_android and not os.path.exists(ANDROID_NDK_DIR): 359 if args.with_android and not os.path.exists(ANDROID_NDK_DIR):
374 print 'Android NDK not found at ' + ANDROID_NDK_DIR 360 print 'Android NDK not found at ' + ANDROID_NDK_DIR
375 print 'The Android NDK is needed to build a Clang whose -fsanitize=address' 361 print 'The Android NDK is needed to build a Clang whose -fsanitize=address'
376 print 'works on Android. See ' 362 print 'works on Android. See '
377 print 'https://www.chromium.org/developers/how-tos/android-build-instruction s' 363 print 'https://www.chromium.org/developers/how-tos/android-build-instruction s'
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 args.force_local_build = True 749 args.force_local_build = True
764 if 'OS=android' not in os.environ.get('GYP_DEFINES', ''): 750 if 'OS=android' not in os.environ.get('GYP_DEFINES', ''):
765 # Only build the Android ASan rt on ToT bots when targetting Android. 751 # Only build the Android ASan rt on ToT bots when targetting Android.
766 args.with_android = False 752 args.with_android = False
767 753
768 return UpdateClang(args) 754 return UpdateClang(args)
769 755
770 756
771 if __name__ == '__main__': 757 if __name__ == '__main__':
772 sys.exit(main()) 758 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698