OLD | NEW |
---|---|
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 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 LLVM_BUILD_TOOLS_DIR = os.path.abspath( | 63 LLVM_BUILD_TOOLS_DIR = os.path.abspath( |
64 os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) | 64 os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) |
65 STAMP_FILE = os.path.normpath( | 65 STAMP_FILE = os.path.normpath( |
66 os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')) | 66 os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')) |
67 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils') | 67 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils') |
68 VERSION = '3.9.0' | 68 VERSION = '3.9.0' |
69 ANDROID_NDK_DIR = os.path.join( | 69 ANDROID_NDK_DIR = os.path.join( |
70 CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk') | 70 CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk') |
71 | 71 |
72 # URL for pre-built binaries. | 72 # URL for pre-built binaries. |
73 CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang' | 73 CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang' |
Nico
2016/02/15 15:13:47
Do you really need all this code? Isn't
CDS_URL
Mostyn Bramley-Moore
2016/02/15 16:14:06
I implemented this using a local patch that was ha
| |
74 | 74 |
75 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' | 75 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' |
76 if 'LLVM_REPO_URL' in os.environ: | 76 if 'LLVM_REPO_URL' in os.environ: |
77 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] | 77 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] |
78 | 78 |
79 # MIRROR_MAP is an optional environment variable, which contains zero or more | |
80 # mappings from a URL prefix to one or more mirrors. A mapping from a URL | |
81 # prefix to its mirrors starts with the URL prefix and is followed by a pipe | |
82 # char and a mirror prefix, additional mirrors are separated by pipe | |
83 # characters. Multiple such mappings can be separated by whitespace. | |
84 # eg: MIRROR_MAP="http://orig1/foo|http://mirror1/foo/" | |
85 MIRROR_MAP = {} | |
86 if 'MIRROR_MAP' in os.environ: | |
87 for _mg in os.environ['MIRROR_MAP'].split(): | |
88 _items = _mg.split('|') | |
89 MIRROR_MAP[_items[0]] = _items[1:] | |
90 | |
91 def UrlMirrors(orig_url): | |
92 """Return a list of mirror URLS to try (if any), followed by the | |
93 original URL.""" | |
94 url_list = [] | |
95 for url_prefix in MIRROR_MAP: | |
96 if orig_url.startswith(url_prefix): | |
97 for mirror_prefix in MIRROR_MAP[url_prefix]: | |
98 url_list += [ orig_url.replace(url_prefix, mirror_prefix, 1) ] | |
99 return url_list + [ orig_url ] | |
100 | |
79 | 101 |
80 def DownloadUrl(url, output_file): | 102 def DownloadUrl(url, output_file): |
81 """Download url into output_file.""" | 103 """Download url into output_file, or throw an exception.""" |
82 CHUNK_SIZE = 4096 | 104 CHUNK_SIZE = 4096 |
83 TOTAL_DOTS = 10 | 105 TOTAL_DOTS = 10 |
84 num_retries = 3 | 106 |
107 sys.stdout.write('Downloading %s ' % url) | |
108 sys.stdout.flush() | |
109 response = urllib2.urlopen(url) | |
110 total_size = int(response.info().getheader('Content-Length').strip()) | |
111 bytes_done = 0 | |
112 dots_printed = 0 | |
113 while True: | |
114 chunk = response.read(CHUNK_SIZE) | |
115 if not chunk: | |
116 break | |
117 output_file.write(chunk) | |
118 bytes_done += len(chunk) | |
119 num_dots = TOTAL_DOTS * bytes_done / total_size | |
120 sys.stdout.write('.' * (num_dots - dots_printed)) | |
121 sys.stdout.flush() | |
122 dots_printed = num_dots | |
123 if bytes_done != total_size: | |
124 raise urllib2.URLError("only got %d of %d bytes" % | |
125 (bytes_done, total_size)) | |
126 print ' Done.' | |
127 | |
128 | |
129 def DownloadMirroredUrl(orig_url, output_file): | |
130 """Download orig_url (or a mirror of it) into output_file.""" | |
131 url_list = UrlMirrors(orig_url) | |
132 num_retries = 3 # Try each url in url_list this many times. | |
85 retry_wait_s = 5 # Doubled at each retry. | 133 retry_wait_s = 5 # Doubled at each retry. |
86 | 134 |
87 while True: | 135 for loop_num in range(num_retries): |
88 try: | 136 |
89 sys.stdout.write('Downloading %s ' % url) | 137 if loop_num > 0 and len(url_list) > 0: |
90 sys.stdout.flush() | |
91 response = urllib2.urlopen(url) | |
92 total_size = int(response.info().getheader('Content-Length').strip()) | |
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 | |
110 except urllib2.URLError as e: | |
111 sys.stdout.write('\n') | |
112 print e | |
113 if num_retries == 0 or isinstance(e, urllib2.HTTPError) and e.code == 404: | |
114 raise e | |
115 num_retries -= 1 | |
116 print 'Retrying in %d s ...' % retry_wait_s | 138 print 'Retrying in %d s ...' % retry_wait_s |
117 time.sleep(retry_wait_s) | 139 time.sleep(retry_wait_s) |
118 retry_wait_s *= 2 | 140 retry_wait_s *= 2 |
119 | 141 |
142 # Loop over a copy of url_list since it may be modified: | |
143 for url in list(url_list): | |
144 try: | |
145 DownloadUrl(url, output_file) | |
146 return | |
147 except urllib2.URLError as e: | |
148 sys.stdout.write('\n') | |
149 print e | |
150 | |
151 if isinstance(e, urllib2.HTTPError) and e.code == 404: | |
152 # Don't bother trying this URL again. | |
153 url_list.remove(url) | |
154 | |
155 raise urllib2.URLError("Failed to download %s" % orig_url) | |
156 | |
120 | 157 |
121 def EnsureDirExists(path): | 158 def EnsureDirExists(path): |
122 if not os.path.exists(path): | 159 if not os.path.exists(path): |
123 print "Creating directory %s" % path | 160 print "Creating directory %s" % path |
124 os.makedirs(path) | 161 os.makedirs(path) |
125 | 162 |
126 | 163 |
127 def DownloadAndUnpack(url, output_dir): | 164 def DownloadAndUnpack(url, output_dir): |
128 with tempfile.TemporaryFile() as f: | 165 with tempfile.TemporaryFile() as f: |
129 DownloadUrl(url, f) | 166 DownloadMirroredUrl(url, f) |
130 f.seek(0) | 167 f.seek(0) |
131 EnsureDirExists(output_dir) | 168 EnsureDirExists(output_dir) |
132 if url.endswith('.zip'): | 169 if url.endswith('.zip'): |
133 zipfile.ZipFile(f).extractall(path=output_dir) | 170 zipfile.ZipFile(f).extractall(path=output_dir) |
134 else: | 171 else: |
135 tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir) | 172 tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir) |
136 | 173 |
137 | 174 |
138 def ReadStampFile(): | 175 def ReadStampFile(): |
139 """Return the contents of the stamp file, or '' if it doesn't exist.""" | 176 """Return the contents of the stamp file, or '' if it doesn't exist.""" |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
763 args.force_local_build = True | 800 args.force_local_build = True |
764 if 'OS=android' not in os.environ.get('GYP_DEFINES', ''): | 801 if 'OS=android' not in os.environ.get('GYP_DEFINES', ''): |
765 # Only build the Android ASan rt on ToT bots when targetting Android. | 802 # Only build the Android ASan rt on ToT bots when targetting Android. |
766 args.with_android = False | 803 args.with_android = False |
767 | 804 |
768 return UpdateClang(args) | 805 return UpdateClang(args) |
769 | 806 |
770 | 807 |
771 if __name__ == '__main__': | 808 if __name__ == '__main__': |
772 sys.exit(main()) | 809 sys.exit(main()) |
OLD | NEW |