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

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

Issue 2399893002: Roll buildtools and clang for GN build. (Closed)
Patch Set: Created 4 years, 2 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 | « DEPS ('k') | 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 """Windows can't run .sh files, so this is a Python implementation of 6 """This script is used to download prebuilt clang binaries.
7 update.sh. This script should replace update.sh on all platforms eventually.""" 7
8 It is also used by package.py to build the prebuilt clang binaries."""
8 9
9 import argparse 10 import argparse
10 import contextlib 11 import distutils.spawn
11 import cStringIO
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 time 22 import time
22 import urllib2 23 import urllib2
23 import zipfile 24 import zipfile
24 25
26
25 # Do NOT CHANGE this if you don't know what you're doing -- see 27 # Do NOT CHANGE this if you don't know what you're doing -- see
26 # https://code.google.com/p/chromium/wiki/UpdatingClang 28 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
27 # Reverting problematic clang rolls is safe, though. 29 # Reverting problematic clang rolls is safe, though.
28 # Note: this revision is only used for Windows. Other platforms use update.sh. 30 CLANG_REVISION = '282487'
29 # TODO(thakis): Use the same revision on Windows and non-Windows.
30 # TODO(thakis): Remove update.sh, use update.py everywhere.
31 LLVM_WIN_REVISION = '242415'
32 31
33 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ 32 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
34 if use_head_revision: 33 if use_head_revision:
35 LLVM_WIN_REVISION = 'HEAD' 34 CLANG_REVISION = 'HEAD'
36 35
37 # This is incremented when pushing a new build of Clang at the same revision. 36 # This is incremented when pushing a new build of Clang at the same revision.
38 CLANG_SUB_REVISION=1 37 CLANG_SUB_REVISION=1
39 38
40 PACKAGE_VERSION = "%s-%s" % (LLVM_WIN_REVISION, CLANG_SUB_REVISION) 39 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
41 40
42 # Path constants. (All of these should be absolute paths.) 41 # Path constants. (All of these should be absolute paths.)
43 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) 42 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
44 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) 43 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
45 THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party') 44 THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
46 LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm') 45 LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm')
47 LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap') 46 LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
48 LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR, 47 LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
49 'llvm-bootstrap-install') 48 'llvm-bootstrap-install')
49 LLVM_LTO_GOLD_PLUGIN_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-lto-gold-plugin')
50 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools') 50 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
51 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build', 51 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
52 'Release+Asserts') 52 'Release+Asserts')
53 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') 53 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'compiler-rt')
54 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang') 54 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
55 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld') 55 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
56 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt') 56 # compiler-rt is built as part of the regular LLVM build on Windows to get
57 # the 64-bit runtime, and out-of-tree elsewhere.
58 # TODO(thakis): Try to unify this.
59 if sys.platform == 'win32':
60 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
61 else:
62 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'compiler-rt')
57 LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx') 63 LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx')
58 LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi') 64 LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
59 LLVM_BUILD_TOOLS_DIR = os.path.abspath( 65 LLVM_BUILD_TOOLS_DIR = os.path.abspath(
60 os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) 66 os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
61 STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision') 67 STAMP_FILE = os.path.normpath(
68 os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision'))
62 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils') 69 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
63 VERSION = '3.8.0' 70 BINUTILS_BIN_DIR = os.path.join(BINUTILS_DIR, BINUTILS_DIR,
71 'Linux_x64', 'Release', 'bin')
72 BFD_PLUGINS_DIR = os.path.join(BINUTILS_DIR, 'Linux_x64', 'Release',
73 'lib', 'bfd-plugins')
74 VERSION = '4.0.0'
75 ANDROID_NDK_DIR = os.path.join(
76 CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk')
64 77
65 # URL for pre-built binaries. 78 # URL for pre-built binaries.
66 CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang' 79 CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE',
80 'https://commondatastorage.googleapis.com/chromium-browser-clang')
67 81
68 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' 82 LLVM_REPO_URL='https://llvm.org/svn/llvm-project'
69 if 'LLVM_REPO_URL' in os.environ: 83 if 'LLVM_REPO_URL' in os.environ:
70 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] 84 LLVM_REPO_URL = os.environ['LLVM_REPO_URL']
71 85
86 # Bump after VC updates.
87 DIA_DLL = {
88 '2013': 'msdia120.dll',
89 '2015': 'msdia140.dll',
90 }
91
72 92
73 def DownloadUrl(url, output_file): 93 def DownloadUrl(url, output_file):
74 """Download url into output_file.""" 94 """Download url into output_file."""
75 CHUNK_SIZE = 4096 95 CHUNK_SIZE = 4096
76 TOTAL_DOTS = 10 96 TOTAL_DOTS = 10
77 sys.stdout.write('Downloading %s ' % url) 97 num_retries = 3
78 sys.stdout.flush() 98 retry_wait_s = 5 # Doubled at each retry.
79 response = urllib2.urlopen(url) 99
80 total_size = int(response.info().getheader('Content-Length').strip())
81 bytes_done = 0
82 dots_printed = 0
83 while True: 100 while True:
84 chunk = response.read(CHUNK_SIZE) 101 try:
85 if not chunk: 102 sys.stdout.write('Downloading %s ' % url)
86 break 103 sys.stdout.flush()
87 output_file.write(chunk) 104 response = urllib2.urlopen(url)
88 bytes_done += len(chunk) 105 total_size = int(response.info().getheader('Content-Length').strip())
89 num_dots = TOTAL_DOTS * bytes_done / total_size 106 bytes_done = 0
90 sys.stdout.write('.' * (num_dots - dots_printed)) 107 dots_printed = 0
91 sys.stdout.flush() 108 while True:
92 dots_printed = num_dots 109 chunk = response.read(CHUNK_SIZE)
93 print ' Done.' 110 if not chunk:
111 break
112 output_file.write(chunk)
113 bytes_done += len(chunk)
114 num_dots = TOTAL_DOTS * bytes_done / total_size
115 sys.stdout.write('.' * (num_dots - dots_printed))
116 sys.stdout.flush()
117 dots_printed = num_dots
118 if bytes_done != total_size:
119 raise urllib2.URLError("only got %d of %d bytes" %
120 (bytes_done, total_size))
121 print ' Done.'
122 return
123 except urllib2.URLError as e:
124 sys.stdout.write('\n')
125 print e
126 if num_retries == 0 or isinstance(e, urllib2.HTTPError) and e.code == 404:
127 raise e
128 num_retries -= 1
129 print 'Retrying in %d s ...' % retry_wait_s
130 time.sleep(retry_wait_s)
131 retry_wait_s *= 2
94 132
95 133
96 def ReadStampFile(): 134 def EnsureDirExists(path):
135 if not os.path.exists(path):
136 print "Creating directory %s" % path
137 os.makedirs(path)
138
139
140 def DownloadAndUnpack(url, output_dir):
141 with tempfile.TemporaryFile() as f:
142 DownloadUrl(url, f)
143 f.seek(0)
144 EnsureDirExists(output_dir)
145 if url.endswith('.zip'):
146 zipfile.ZipFile(f).extractall(path=output_dir)
147 else:
148 tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir)
149
150
151 def ReadStampFile(path=STAMP_FILE):
97 """Return the contents of the stamp file, or '' if it doesn't exist.""" 152 """Return the contents of the stamp file, or '' if it doesn't exist."""
98 try: 153 try:
99 with open(STAMP_FILE, 'r') as f: 154 with open(path, 'r') as f:
100 return f.read() 155 return f.read().rstrip()
101 except IOError: 156 except IOError:
102 return '' 157 return ''
103 158
104 159
105 def WriteStampFile(s): 160 def WriteStampFile(s, path=STAMP_FILE):
106 """Write s to the stamp file.""" 161 """Write s to the stamp file."""
107 if not os.path.exists(os.path.dirname(STAMP_FILE)): 162 EnsureDirExists(os.path.dirname(path))
108 os.makedirs(os.path.dirname(STAMP_FILE)) 163 with open(path, 'w') as f:
109 with open(STAMP_FILE, 'w') as f:
110 f.write(s) 164 f.write(s)
165 f.write('\n')
111 166
112 167
113 def GetSvnRevision(svn_repo): 168 def GetSvnRevision(svn_repo):
114 """Returns current revision of the svn repo at svn_repo.""" 169 """Returns current revision of the svn repo at svn_repo."""
170 if sys.platform == 'darwin':
171 # mac_files toolchain must be set for hermetic builds.
172 root = os.path.dirname(os.path.dirname(os.path.dirname(
173 os.path.dirname(__file__))))
174 sys.path.append(os.path.join(root, 'build'))
175 import mac_toolchain
176
177 mac_toolchain.SetToolchainEnvironment()
115 svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True) 178 svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True)
116 m = re.search(r'Revision: (\d+)', svn_info) 179 m = re.search(r'Revision: (\d+)', svn_info)
117 return m.group(1) 180 return m.group(1)
118 181
119 182
120 def RmTree(dir): 183 def RmTree(dir):
121 """Delete dir.""" 184 """Delete dir."""
122 def ChmodAndRetry(func, path, _): 185 def ChmodAndRetry(func, path, _):
123 # Subversion can leave read-only files around. 186 # Subversion can leave read-only files around.
124 if not os.access(path, os.W_OK): 187 if not os.access(path, os.W_OK):
125 os.chmod(path, stat.S_IWUSR) 188 os.chmod(path, stat.S_IWUSR)
126 return func(path) 189 return func(path)
127 raise 190 raise
128 191
129 shutil.rmtree(dir, onerror=ChmodAndRetry) 192 shutil.rmtree(dir, onerror=ChmodAndRetry)
130 193
131 194
195 def RmCmakeCache(dir):
196 """Delete CMake cache related files from dir."""
197 for dirpath, dirs, files in os.walk(dir):
198 if 'CMakeCache.txt' in files:
199 os.remove(os.path.join(dirpath, 'CMakeCache.txt'))
200 if 'CMakeFiles' in dirs:
201 RmTree(os.path.join(dirpath, 'CMakeFiles'))
202
203
132 def RunCommand(command, msvc_arch=None, env=None, fail_hard=True): 204 def RunCommand(command, msvc_arch=None, env=None, fail_hard=True):
133 """Run command and return success (True) or failure; or if fail_hard is 205 """Run command and return success (True) or failure; or if fail_hard is
134 True, exit on failure. If msvc_arch is set, runs the command in a 206 True, exit on failure. If msvc_arch is set, runs the command in a
135 shell with the msvc tools for that architecture.""" 207 shell with the msvc tools for that architecture."""
136 208
137 if msvc_arch and sys.platform == 'win32': 209 if msvc_arch and sys.platform == 'win32':
138 command = GetVSVersion().SetupScript(msvc_arch) + ['&&'] + command 210 command = GetVSVersion().SetupScript(msvc_arch) + ['&&'] + command
139 211
140 # https://docs.python.org/2/library/subprocess.html: 212 # https://docs.python.org/2/library/subprocess.html:
141 # "On Unix with shell=True [...] if args is a sequence, the first item 213 # "On Unix with shell=True [...] if args is a sequence, the first item
(...skipping 14 matching lines...) Expand all
156 if subprocess.call(command, env=env, shell=True) == 0: 228 if subprocess.call(command, env=env, shell=True) == 0:
157 return True 229 return True
158 print 'Failed.' 230 print 'Failed.'
159 if fail_hard: 231 if fail_hard:
160 sys.exit(1) 232 sys.exit(1)
161 return False 233 return False
162 234
163 235
164 def CopyFile(src, dst): 236 def CopyFile(src, dst):
165 """Copy a file from src to dst.""" 237 """Copy a file from src to dst."""
238 print "Copying %s to %s" % (src, dst)
166 shutil.copy(src, dst) 239 shutil.copy(src, dst)
167 print "Copying %s to %s" % (src, dst)
168 240
169 241
170 def CopyDirectoryContents(src, dst, filename_filter=None): 242 def CopyDirectoryContents(src, dst, filename_filter=None):
171 """Copy the files from directory src to dst 243 """Copy the files from directory src to dst
172 with an optional filename filter.""" 244 with an optional filename filter."""
173 if not os.path.exists(dst): 245 dst = os.path.realpath(dst) # realpath() in case dst ends in /..
174 os.makedirs(dst) 246 EnsureDirExists(dst)
175 for root, _, files in os.walk(src): 247 for root, _, files in os.walk(src):
176 for f in files: 248 for f in files:
177 if filename_filter and not re.match(filename_filter, f): 249 if filename_filter and not re.match(filename_filter, f):
178 continue 250 continue
179 CopyFile(os.path.join(root, f), dst) 251 CopyFile(os.path.join(root, f), dst)
180 252
181 253
182 def Checkout(name, url, dir): 254 def Checkout(name, url, dir):
183 """Checkout the SVN module at url into dir. Use name for the log message.""" 255 """Checkout the SVN module at url into dir. Use name for the log message."""
184 print "Checking out %s r%s into '%s'" % (name, LLVM_WIN_REVISION, dir) 256 print "Checking out %s r%s into '%s'" % (name, CLANG_REVISION, dir)
185 257
186 command = ['svn', 'checkout', '--force', url + '@' + LLVM_WIN_REVISION, dir] 258 command = ['svn', 'checkout', '--force', url + '@' + CLANG_REVISION, dir]
187 if RunCommand(command, fail_hard=False): 259 if RunCommand(command, fail_hard=False):
188 return 260 return
189 261
190 if os.path.isdir(dir): 262 if os.path.isdir(dir):
191 print "Removing %s." % (dir) 263 print "Removing %s." % (dir)
192 RmTree(dir) 264 RmTree(dir)
193 265
194 print "Retrying." 266 print "Retrying."
195 RunCommand(command) 267 RunCommand(command)
196 268
197 269
198 def RevertPreviouslyPatchedFiles():
199 print 'Reverting previously patched files'
200 files = [
201 '%(clang)s/test/Index/crash-recovery-modules.m',
202 '%(clang)s/unittests/libclang/LibclangTest.cpp',
203 '%(compiler_rt)s/lib/asan/asan_rtl.cc',
204 '%(compiler_rt)s/test/asan/TestCases/Linux/new_array_cookie_test.cc',
205 '%(llvm)s/test/DebugInfo/gmlt.ll',
206 '%(llvm)s/lib/CodeGen/SpillPlacement.cpp',
207 '%(llvm)s/lib/CodeGen/SpillPlacement.h',
208 '%(llvm)s/lib/Transforms/Instrumentation/MemorySanitizer.cpp',
209 '%(clang)s/test/Driver/env.c',
210 '%(clang)s/lib/Frontend/InitPreprocessor.cpp',
211 '%(clang)s/test/Frontend/exceptions.c',
212 '%(clang)s/test/Preprocessor/predefined-exceptions.m',
213 '%(llvm)s/test/Bindings/Go/go.test',
214 '%(clang)s/lib/Parse/ParseExpr.cpp',
215 '%(clang)s/lib/Parse/ParseTemplate.cpp',
216 '%(clang)s/lib/Sema/SemaDeclCXX.cpp',
217 '%(clang)s/lib/Sema/SemaExprCXX.cpp',
218 '%(clang)s/test/SemaCXX/default2.cpp',
219 '%(clang)s/test/SemaCXX/typo-correction-delayed.cpp',
220 '%(compiler_rt)s/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.c c',
221 '%(compiler_rt)s/test/tsan/signal_segv_handler.cc',
222 '%(compiler_rt)s/lib/sanitizer_common/sanitizer_coverage_libcdep.cc',
223 '%(compiler_rt)s/cmake/config-ix.cmake',
224 '%(compiler_rt)s/CMakeLists.txt',
225 '%(compiler_rt)s/lib/ubsan/ubsan_platform.h',
226 ]
227 for f in files:
228 f = f % {
229 'clang': CLANG_DIR,
230 'compiler_rt': COMPILER_RT_DIR,
231 'llvm': LLVM_DIR,
232 }
233 if os.path.exists(f):
234 os.remove(f) # For unversioned files.
235 RunCommand(['svn', 'revert', f])
236
237
238 def ApplyLocalPatches():
239 # There's no patch program on Windows by default. We don't need patches on
240 # Windows yet, and maybe this not working on Windows will motivate us to
241 # remove patches over time.
242 assert sys.platform != 'win32'
243
244 # Apply patch for tests failing with --disable-pthreads (llvm.org/PR11974)
245 clang_patches = [ r"""\
246 --- test/Index/crash-recovery-modules.m (revision 202554)
247 +++ test/Index/crash-recovery-modules.m (working copy)
248 @@ -12,6 +12,8 @@
249
250 // REQUIRES: crash-recovery
251 // REQUIRES: shell
252 +// XFAIL: *
253 +// (PR11974)
254
255 @import Crash;
256 """, r"""\
257 --- unittests/libclang/LibclangTest.cpp (revision 215949)
258 +++ unittests/libclang/LibclangTest.cpp (working copy)
259 @@ -431,7 +431,7 @@
260 EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
261 }
262
263 -TEST_F(LibclangReparseTest, ReparseWithModule) {
264 +TEST_F(LibclangReparseTest, DISABLED_ReparseWithModule) {
265 const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
266 const char *HeaderBottom = "\n};\n#endif\n";
267 const char *MFile = "#include \"HeaderFile.h\"\nint main() {"
268 """
269 ]
270
271 # This Go bindings test doesn't work after bootstrap on Linux, PR21552.
272 llvm_patches = [ r"""\
273 --- test/Bindings/Go/go.test (revision 223109)
274 +++ test/Bindings/Go/go.test (working copy)
275 @@ -1,3 +1,3 @@
276 -; RUN: llvm-go test llvm.org/llvm/bindings/go/llvm
277 +; RUN: true
278
279 ; REQUIRES: shell
280 """
281 ]
282
283 # The UBSan run-time, which is now bundled with the ASan run-time, doesn't
284 # work on Mac OS X 10.8 (PR23539).
285 compiler_rt_patches = [ r"""\
286 --- CMakeLists.txt (revision 241602)
287 +++ CMakeLists.txt (working copy)
288 @@ -305,6 +305,7 @@
289 list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim)
290 endif()
291 endif()
292 + set(SANITIZER_MIN_OSX_VERSION "10.7")
293 if(SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.7")
294 message(FATAL_ERROR "Too old OS X version: ${SANITIZER_MIN_OSX_VERSION}")
295 endif()
296 """
297 ]
298
299 for path, patches in [(LLVM_DIR, llvm_patches),
300 (CLANG_DIR, clang_patches),
301 (COMPILER_RT_DIR, compiler_rt_patches)]:
302 print 'Applying patches in', path
303 for patch in patches:
304 print patch
305 p = subprocess.Popen( ['patch', '-p0', '-d', path], stdin=subprocess.PIPE)
306 (stdout, stderr) = p.communicate(input=patch)
307 if p.returncode != 0:
308 raise RuntimeError('stdout %s, stderr %s' % (stdout, stderr))
309
310
311 def DeleteChromeToolsShim(): 270 def DeleteChromeToolsShim():
271 OLD_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'zzz-chrometools')
272 shutil.rmtree(OLD_SHIM_DIR, ignore_errors=True)
312 shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True) 273 shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)
313 274
314 275
315 def CreateChromeToolsShim(): 276 def CreateChromeToolsShim():
316 """Hooks the Chrome tools into the LLVM build. 277 """Hooks the Chrome tools into the LLVM build.
317 278
318 Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build 279 Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build
319 detects implicit tools in the tools subdirectory, so this helper install a 280 detects implicit tools in the tools subdirectory, so this helper install a
320 shim CMakeLists.txt that forwards to the real directory for the Chrome tools. 281 shim CMakeLists.txt that forwards to the real directory for the Chrome tools.
321 282
322 Note that the shim directory name intentionally has no - or _. The implicit 283 Note that the shim directory name intentionally has no - or _. The implicit
323 tool detection logic munges them in a weird way.""" 284 tool detection logic munges them in a weird way."""
324 assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_') 285 assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
325 os.mkdir(CHROME_TOOLS_SHIM_DIR) 286 os.mkdir(CHROME_TOOLS_SHIM_DIR)
326 with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f: 287 with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f:
327 f.write('# Automatically generated by tools/clang/scripts/update.py. ' + 288 f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
328 'Do not edit.\n') 289 'Do not edit.\n')
329 f.write('# Since tools/clang is located in another directory, use the \n') 290 f.write('# Since tools/clang is located in another directory, use the \n')
330 f.write('# two arg version to specify where build artifacts go. CMake\n') 291 f.write('# two arg version to specify where build artifacts go. CMake\n')
331 f.write('# disallows reuse of the same binary dir for multiple source\n') 292 f.write('# disallows reuse of the same binary dir for multiple source\n')
332 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n') 293 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
333 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n') 294 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
334 f.write('if (CHROMIUM_TOOLS_SRC)\n') 295 f.write('if (CHROMIUM_TOOLS_SRC)\n')
335 f.write(' add_subdirectory(${CHROMIUM_TOOLS_SRC} ' + 296 f.write(' add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
336 '${CMAKE_CURRENT_BINARY_DIR}/a)\n') 297 '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
337 f.write('endif (CHROMIUM_TOOLS_SRC)\n') 298 f.write('endif (CHROMIUM_TOOLS_SRC)\n')
338 299
339 300
301 def DownloadHostGcc(args):
302 """Downloads gcc 4.8.5 and makes sure args.gcc_toolchain is set."""
303 if not sys.platform.startswith('linux') or args.gcc_toolchain:
304 return
305 # Unconditionally download a prebuilt gcc to guarantee the included libstdc++
306 # works on Ubuntu Precise.
307 gcc_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gcc485precise')
308 if not os.path.exists(gcc_dir):
309 print 'Downloading pre-built GCC 4.8.5...'
310 DownloadAndUnpack(
311 CDS_URL + '/tools/gcc485precise.tgz', LLVM_BUILD_TOOLS_DIR)
312 args.gcc_toolchain = gcc_dir
313
314
340 def AddCMakeToPath(): 315 def AddCMakeToPath():
341 """Download CMake and add it to PATH.""" 316 """Download CMake and add it to PATH."""
342 if sys.platform == 'win32': 317 if sys.platform == 'win32':
343 zip_name = 'cmake-3.2.2-win32-x86.zip' 318 zip_name = 'cmake-3.4.3-win32-x86.zip'
344 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 319 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR,
345 'cmake-3.2.2-win32-x86', 'bin') 320 'cmake-3.4.3-win32-x86', 'bin')
346 else: 321 else:
347 suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux' 322 suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux'
348 zip_name = 'cmake310_%s.tgz' % suffix 323 zip_name = 'cmake343_%s.tgz' % suffix
349 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake310', 'bin') 324 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake343', 'bin')
350 if not os.path.exists(cmake_dir): 325 if not os.path.exists(cmake_dir):
351 if not os.path.exists(LLVM_BUILD_TOOLS_DIR): 326 DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
352 os.makedirs(LLVM_BUILD_TOOLS_DIR)
353 # The cmake archive is smaller than 20 MB, small enough to keep in memory:
354 with contextlib.closing(cStringIO.StringIO()) as f:
355 DownloadUrl(CDS_URL + '/tools/' + zip_name, f)
356 f.seek(0)
357 if zip_name.endswith('.zip'):
358 zipfile.ZipFile(f).extractall(path=LLVM_BUILD_TOOLS_DIR)
359 else:
360 tarfile.open(mode='r:gz', fileobj=f).extractall(path=
361 LLVM_BUILD_TOOLS_DIR)
362 os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '') 327 os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
363 328
329
330 def AddGnuWinToPath():
331 """Download some GNU win tools and add them to PATH."""
332 if sys.platform != 'win32':
333 return
334
335 gnuwin_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gnuwin')
336 GNUWIN_VERSION = '5'
337 GNUWIN_STAMP = os.path.join(gnuwin_dir, 'stamp')
338 if ReadStampFile(GNUWIN_STAMP) == GNUWIN_VERSION:
339 print 'GNU Win tools already up to date.'
340 else:
341 zip_name = 'gnuwin-%s.zip' % GNUWIN_VERSION
342 DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
343 WriteStampFile(GNUWIN_VERSION, GNUWIN_STAMP)
344
345 os.environ['PATH'] = gnuwin_dir + os.pathsep + os.environ.get('PATH', '')
346
347
364 vs_version = None 348 vs_version = None
365 def GetVSVersion(): 349 def GetVSVersion():
366 global vs_version 350 global vs_version
367 if vs_version: 351 if vs_version:
368 return vs_version 352 return vs_version
369 353
370 # Try using the toolchain in depot_tools. 354 # Try using the toolchain in depot_tools.
371 # This sets environment variables used by SelectVisualStudioVersion below. 355 # This sets environment variables used by SelectVisualStudioVersion below.
372 sys.path.append(os.path.join(CHROMIUM_DIR, 'build')) 356 sys.path.append(os.path.join(CHROMIUM_DIR, 'build'))
373 import vs_toolchain 357 import vs_toolchain
374 vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs() 358 vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
375 359
376 # Use gyp to find the MSVS installation, either in depot_tools as per above, 360 # Use gyp to find the MSVS installation, either in depot_tools as per above,
377 # or a system-wide installation otherwise. 361 # or a system-wide installation otherwise.
378 sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib')) 362 sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib'))
379 import gyp.MSVSVersion 363 import gyp.MSVSVersion
380 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion('2013') 364 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion(
365 vs_toolchain.GetVisualStudioVersion())
381 return vs_version 366 return vs_version
382 367
383 368
369 def CopyDiaDllTo(target_dir):
370 # This script always wants to use the 64-bit msdia*.dll.
371 dia_path = os.path.join(GetVSVersion().Path(), 'DIA SDK', 'bin', 'amd64')
372 dia_dll = os.path.join(dia_path, DIA_DLL[GetVSVersion().ShortName()])
373 CopyFile(dia_dll, target_dir)
374
375
376 def VeryifyVersionOfBuiltClangMatchesVERSION():
377 """Checks that `clang --version` outputs VERSION. If this fails, VERSION
378 in this file is out-of-date and needs to be updated (possibly in an
379 `if use_head_revision:` block in main() first)."""
380 clang = os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')
381 if sys.platform == 'win32':
382 # TODO: Parse `clang-cl /?` output for built clang's version and check that
383 # to check the binary we're actually shipping? But clang-cl.exe is just
384 # a copy of clang.exe, so this does check the same thing.
385 clang += '.exe'
386 version_out = subprocess.check_output([clang, '--version'])
387 version_out = re.match(r'clang version ([0-9.]+)', version_out).group(1)
388 if version_out != VERSION:
389 print ('unexpected clang version %s (not %s), update VERSION in update.py'
390 % (version_out, VERSION))
391 sys.exit(1)
392
393
384 def UpdateClang(args): 394 def UpdateClang(args):
385 print 'Updating Clang to %s...' % PACKAGE_VERSION 395 print 'Updating Clang to %s...' % PACKAGE_VERSION
386 if ReadStampFile() == PACKAGE_VERSION: 396
387 print 'Already up to date.' 397 need_gold_plugin = 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ or (
388 return 0 398 sys.platform.startswith('linux') and
399 'buildtype=Official' in os.environ.get('GYP_DEFINES', '') and
400 'branding=Chrome' in os.environ.get('GYP_DEFINES', ''))
401
402 if ReadStampFile() == PACKAGE_VERSION and not args.force_local_build:
403 print 'Clang is already up to date.'
404 if not need_gold_plugin or os.path.exists(
405 os.path.join(LLVM_BUILD_DIR, "lib/LLVMgold.so")):
406 return 0
389 407
390 # Reset the stamp file in case the build is unsuccessful. 408 # Reset the stamp file in case the build is unsuccessful.
391 WriteStampFile('') 409 WriteStampFile('')
392 410
393 if not args.force_local_build: 411 if not args.force_local_build:
394 cds_file = "clang-%s.tgz" % PACKAGE_VERSION 412 cds_file = "clang-%s.tgz" % PACKAGE_VERSION
395 cds_full_url = CDS_URL + '/Win/' + cds_file 413 if sys.platform == 'win32' or sys.platform == 'cygwin':
414 cds_full_url = CDS_URL + '/Win/' + cds_file
415 elif sys.platform == 'darwin':
416 cds_full_url = CDS_URL + '/Mac/' + cds_file
417 else:
418 assert sys.platform.startswith('linux')
419 cds_full_url = CDS_URL + '/Linux_x64/' + cds_file
396 420
397 # Check if there's a prebuilt binary and if so just fetch that. That's 421 print 'Downloading prebuilt clang'
398 # faster, and goma relies on having matching binary hashes on client and 422 if os.path.exists(LLVM_BUILD_DIR):
399 # server too. 423 RmTree(LLVM_BUILD_DIR)
400 print 'Trying to download prebuilt clang' 424 try:
425 DownloadAndUnpack(cds_full_url, LLVM_BUILD_DIR)
426 print 'clang %s unpacked' % PACKAGE_VERSION
427 if sys.platform == 'win32':
428 CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
429 # Download the gold plugin if requested to by an environment variable.
430 # This is used by the CFI ClusterFuzz bot, and it's required for official
431 # builds on linux.
432 if need_gold_plugin:
433 RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
434 WriteStampFile(PACKAGE_VERSION)
435 return 0
436 except urllib2.URLError:
437 print 'Failed to download prebuilt clang %s' % cds_file
438 print 'Use --force-local-build if you want to build locally.'
439 print 'Exiting.'
440 return 1
401 441
402 # clang packages are smaller than 50 MB, small enough to keep in memory. 442 if args.with_android and not os.path.exists(ANDROID_NDK_DIR):
403 with contextlib.closing(cStringIO.StringIO()) as f: 443 print 'Android NDK not found at ' + ANDROID_NDK_DIR
404 try: 444 print 'The Android NDK is needed to build a Clang whose -fsanitize=address'
405 DownloadUrl(cds_full_url, f) 445 print 'works on Android. See '
406 f.seek(0) 446 print 'https://www.chromium.org/developers/how-tos/android-build-instruction s'
407 tarfile.open(mode='r:gz', fileobj=f).extractall(path=LLVM_BUILD_DIR) 447 print 'for how to install the NDK, or pass --without-android.'
408 print 'clang %s unpacked' % PACKAGE_VERSION 448 return 1
409 # Download the gold plugin if requested to by an environment variable.
410 # This is used by the CFI ClusterFuzz bot.
411 if 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ:
412 RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
413 WriteStampFile(PACKAGE_VERSION)
414 return 0
415 except urllib2.HTTPError:
416 print 'Did not find prebuilt clang %s, building locally' % cds_file
417 449
450 DownloadHostGcc(args)
418 AddCMakeToPath() 451 AddCMakeToPath()
452 AddGnuWinToPath()
419 453
420 RevertPreviouslyPatchedFiles()
421 DeleteChromeToolsShim() 454 DeleteChromeToolsShim()
422 455
423 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) 456 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
424 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) 457 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
425 if sys.platform == 'win32': 458 if sys.platform == 'win32' or use_head_revision:
426 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) 459 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
427 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) 460 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
428 if sys.platform == 'darwin': 461 if sys.platform == 'darwin':
429 # clang needs a libc++ checkout, else -stdlib=libc++ won't find includes 462 # clang needs a libc++ checkout, else -stdlib=libc++ won't find includes
430 # (i.e. this is needed for bootstrap builds). 463 # (i.e. this is needed for bootstrap builds).
431 Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR) 464 Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR)
432 # While we're bundling our own libc++ on OS X, we need to compile libc++abi 465 # We used to check out libcxxabi on OS X; we no longer need that.
433 # into it too (since OS X 10.6 doesn't have libc++abi.dylib either). 466 if os.path.exists(LIBCXXABI_DIR):
434 Checkout('libcxxabi', LLVM_REPO_URL + '/libcxxabi/trunk', LIBCXXABI_DIR) 467 RmTree(LIBCXXABI_DIR)
435
436 if args.with_patches and sys.platform != 'win32':
437 ApplyLocalPatches()
438 468
439 cc, cxx = None, None 469 cc, cxx = None, None
440 cflags = cxxflags = ldflags = [] 470 libstdcpp = None
471 if args.gcc_toolchain: # This option is only used on Linux.
472 # Use the specified gcc installation for building.
473 cc = os.path.join(args.gcc_toolchain, 'bin', 'gcc')
474 cxx = os.path.join(args.gcc_toolchain, 'bin', 'g++')
441 475
442 # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is 476 if not os.access(cc, os.X_OK):
443 # needed, on OS X it requires libc++. clang only automatically links to libc++ 477 print 'Invalid --gcc-toolchain: "%s"' % args.gcc_toolchain
444 # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run 478 print '"%s" does not appear to be valid.' % cc
445 # on OS X versions as old as 10.7. 479 return 1
446 # TODO(thakis): Some bots are still on 10.6 (nacl...), so for now bundle
447 # libc++.dylib. Remove this once all bots are on 10.7+, then use
448 # -DLLVM_ENABLE_LIBCXX=ON and change deployment_target to 10.7.
449 deployment_target = ''
450 480
451 if sys.platform == 'darwin': 481 # Set LD_LIBRARY_PATH to make auxiliary targets (tablegen, bootstrap
452 # When building on 10.9, /usr/include usually doesn't exist, and while 482 # compiler, etc.) find the .so.
453 # Xcode's clang automatically sets a sysroot, self-built clangs don't. 483 libstdcpp = subprocess.check_output(
454 cflags = ['-isysroot', subprocess.check_output( 484 [cxx, '-print-file-name=libstdc++.so.6']).rstrip()
455 ['xcrun', '--show-sdk-path']).rstrip()] 485 os.environ['LD_LIBRARY_PATH'] = os.path.dirname(libstdcpp)
456 cxxflags = ['-stdlib=libc++', '-nostdinc++', 486
457 '-I' + os.path.join(LIBCXX_DIR, 'include')] + cflags 487 cflags = []
458 if args.bootstrap: 488 cxxflags = []
459 deployment_target = '10.6' 489 ldflags = []
460 490
461 base_cmake_args = ['-GNinja', 491 base_cmake_args = ['-GNinja',
462 '-DCMAKE_BUILD_TYPE=Release', 492 '-DCMAKE_BUILD_TYPE=Release',
463 '-DLLVM_ENABLE_ASSERTIONS=ON', 493 '-DLLVM_ENABLE_ASSERTIONS=ON',
464 '-DLLVM_ENABLE_THREADS=OFF', 494 '-DLLVM_ENABLE_THREADS=OFF',
495 '-DLLVM_ENABLE_TIMESTAMPS=OFF',
496 # Statically link MSVCRT to avoid DLL dependencies.
497 '-DLLVM_USE_CRT_RELEASE=MT',
465 ] 498 ]
466 499
500 binutils_incdir = ''
501 if sys.platform.startswith('linux'):
502 binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include')
503
467 if args.bootstrap: 504 if args.bootstrap:
468 print 'Building bootstrap compiler' 505 print 'Building bootstrap compiler'
469 if not os.path.exists(LLVM_BOOTSTRAP_DIR): 506 EnsureDirExists(LLVM_BOOTSTRAP_DIR)
470 os.makedirs(LLVM_BOOTSTRAP_DIR)
471 os.chdir(LLVM_BOOTSTRAP_DIR) 507 os.chdir(LLVM_BOOTSTRAP_DIR)
472 bootstrap_args = base_cmake_args + [ 508 bootstrap_args = base_cmake_args + [
509 '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
473 '-DLLVM_TARGETS_TO_BUILD=host', 510 '-DLLVM_TARGETS_TO_BUILD=host',
474 '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR, 511 '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
475 '-DCMAKE_C_FLAGS=' + ' '.join(cflags), 512 '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
476 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags), 513 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
477 ] 514 ]
478 if cc is not None: bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc) 515 if cc is not None: bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
479 if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx) 516 if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
517 RmCmakeCache('.')
480 RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64') 518 RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64')
481 RunCommand(['ninja'], msvc_arch='x64') 519 RunCommand(['ninja'], msvc_arch='x64')
482 if args.run_tests: 520 if args.run_tests:
521 if sys.platform == 'win32':
522 CopyDiaDllTo(os.path.join(LLVM_BOOTSTRAP_DIR, 'bin'))
483 RunCommand(['ninja', 'check-all'], msvc_arch='x64') 523 RunCommand(['ninja', 'check-all'], msvc_arch='x64')
484 RunCommand(['ninja', 'install'], msvc_arch='x64') 524 RunCommand(['ninja', 'install'], msvc_arch='x64')
525 if args.gcc_toolchain:
526 # Copy that gcc's stdlibc++.so.6 to the build dir, so the bootstrap
527 # compiler can start.
528 CopyFile(libstdcpp, os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'lib'))
485 529
486 if sys.platform == 'win32': 530 if sys.platform == 'win32':
487 cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe') 531 cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
488 cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe') 532 cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
489 # CMake has a hard time with backslashes in compiler paths: 533 # CMake has a hard time with backslashes in compiler paths:
490 # https://stackoverflow.com/questions/13050827 534 # https://stackoverflow.com/questions/13050827
491 cc = cc.replace('\\', '/') 535 cc = cc.replace('\\', '/')
492 cxx = cxx.replace('\\', '/') 536 cxx = cxx.replace('\\', '/')
493 else: 537 else:
494 cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang') 538 cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang')
495 cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++') 539 cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++')
540
541 if args.gcc_toolchain:
542 # Tell the bootstrap compiler to use a specific gcc prefix to search
543 # for standard library headers and shared object files.
544 cflags = ['--gcc-toolchain=' + args.gcc_toolchain]
545 cxxflags = ['--gcc-toolchain=' + args.gcc_toolchain]
496 print 'Building final compiler' 546 print 'Building final compiler'
497 547
498 if sys.platform == 'darwin': 548 # Build LLVM gold plugin with LTO. That speeds up the linker by ~10%.
499 # Build libc++.dylib while some bots are still on OS X 10.6. 549 # We only use LTO for Linux now.
500 libcxxbuild = os.path.join(LLVM_BUILD_DIR, 'libcxxbuild') 550 if args.bootstrap and args.lto_gold_plugin:
501 if os.path.isdir(libcxxbuild): 551 print 'Building LTO LLVM Gold plugin'
502 RmTree(libcxxbuild) 552 if os.path.exists(LLVM_LTO_GOLD_PLUGIN_DIR):
503 libcxxflags = ['-O3', '-std=c++11', '-fstrict-aliasing'] 553 RmTree(LLVM_LTO_GOLD_PLUGIN_DIR)
554 EnsureDirExists(LLVM_LTO_GOLD_PLUGIN_DIR)
555 os.chdir(LLVM_LTO_GOLD_PLUGIN_DIR)
504 556
505 # libcxx and libcxxabi both have a file stdexcept.cpp, so put their .o files 557 # Create a symlink to LLVMgold.so build in the previous step so that ar
506 # into different subdirectories. 558 # and ranlib could find it while linking LLVMgold.so with LTO.
507 os.makedirs(os.path.join(libcxxbuild, 'libcxx')) 559 EnsureDirExists(BFD_PLUGINS_DIR)
508 os.chdir(os.path.join(libcxxbuild, 'libcxx')) 560 RunCommand(['ln', '-sf',
509 RunCommand(['c++', '-c'] + cxxflags + libcxxflags + 561 os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'lib', 'LLVMgold.so'),
510 glob.glob(os.path.join(LIBCXX_DIR, 'src', '*.cpp'))) 562 os.path.join(BFD_PLUGINS_DIR, 'LLVMgold.so')])
511 563
512 os.makedirs(os.path.join(libcxxbuild, 'libcxxabi')) 564 lto_cflags = ['-flto']
513 os.chdir(os.path.join(libcxxbuild, 'libcxxabi')) 565 lto_ldflags = ['-fuse-ld=gold']
514 RunCommand(['c++', '-c'] + cxxflags + libcxxflags + 566 if args.gcc_toolchain:
515 glob.glob(os.path.join(LIBCXXABI_DIR, 'src', '*.cpp')) + 567 # Tell the bootstrap compiler to use a specific gcc prefix to search
516 ['-I' + os.path.join(LIBCXXABI_DIR, 'include')]) 568 # for standard library headers and shared object files.
569 lto_cflags += ['--gcc-toolchain=' + args.gcc_toolchain]
570 lto_cmake_args = base_cmake_args + [
571 '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
572 '-DCMAKE_C_COMPILER=' + cc,
573 '-DCMAKE_CXX_COMPILER=' + cxx,
574 '-DCMAKE_C_FLAGS=' + ' '.join(lto_cflags),
575 '-DCMAKE_CXX_FLAGS=' + ' '.join(lto_cflags),
576 '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(lto_ldflags),
577 '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(lto_ldflags),
578 '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(lto_ldflags)]
517 579
518 os.chdir(libcxxbuild) 580 # We need to use the proper binutils which support LLVM Gold plugin.
519 libdir = os.path.join(LIBCXX_DIR, 'lib') 581 lto_env = os.environ.copy()
520 RunCommand(['cc'] + glob.glob('libcxx/*.o') + glob.glob('libcxxabi/*.o') + 582 lto_env['PATH'] = BINUTILS_BIN_DIR + os.pathsep + lto_env.get('PATH', '')
521 ['-o', 'libc++.1.dylib', '-dynamiclib', '-nodefaultlibs',
522 '-current_version', '1', '-compatibility_version', '1', '-lSystem',
523 '-install_name', '@executable_path/libc++.dylib',
524 '-Wl,-unexported_symbols_list,' + libdir + '/libc++unexp.exp',
525 '-Wl,-force_symbols_not_weak_list,' + libdir + '/notweak.exp',
526 '-Wl,-force_symbols_weak_list,' + libdir + '/weak.exp'])
527 if os.path.exists('libc++.dylib'):
528 os.remove('libc++.dylib')
529 os.symlink('libc++.1.dylib', 'libc++.dylib')
530 ldflags += ['-stdlib=libc++', '-L' + libcxxbuild]
531 583
532 if args.bootstrap: 584 RmCmakeCache('.')
533 # Now that the libc++ headers have been installed and libc++.dylib is 585 RunCommand(['cmake'] + lto_cmake_args + [LLVM_DIR], env=lto_env)
534 # built, delete the libc++ checkout again so that it's not part of the 586 RunCommand(['ninja', 'LLVMgold'], env=lto_env)
535 # main build below -- the libc++(abi) tests don't pass on OS X in 587
536 # bootstrap builds (http://llvm.org/PR24068) 588
537 RmTree(LIBCXX_DIR) 589 # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
538 RmTree(LIBCXXABI_DIR) 590 # needed, on OS X it requires libc++. clang only automatically links to libc++
539 cxxflags = ['-stdlib=libc++', '-nostdinc++', 591 # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run
540 '-I' + os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 592 # on OS X versions as old as 10.7.
541 'include/c++/v1') 593 deployment_target = ''
542 ] + cflags 594
595 if sys.platform == 'darwin' and args.bootstrap:
596 # When building on 10.9, /usr/include usually doesn't exist, and while
597 # Xcode's clang automatically sets a sysroot, self-built clangs don't.
598 cflags = ['-isysroot', subprocess.check_output(
599 ['xcrun', '--show-sdk-path']).rstrip()]
600 cxxflags = ['-stdlib=libc++'] + cflags
601 ldflags += ['-stdlib=libc++']
602 deployment_target = '10.7'
603 # Running libc++ tests takes a long time. Since it was only needed for
604 # the install step above, don't build it as part of the main build.
605 # This makes running package.py over 10% faster (30 min instead of 34 min)
606 RmTree(LIBCXX_DIR)
543 607
544 # Build clang. 608 # Build clang.
545 binutils_incdir = ''
546 if sys.platform.startswith('linux'):
547 binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include')
548 609
549 # If building at head, define a macro that plugins can use for #ifdefing 610 # If building at head, define a macro that plugins can use for #ifdefing
550 # out code that builds at head, but not at LLVM_WIN_REVISION or vice versa. 611 # out code that builds at head, but not at CLANG_REVISION or vice versa.
551 if use_head_revision: 612 if use_head_revision:
552 cflags += ['-DLLVM_FORCE_HEAD_REVISION'] 613 cflags += ['-DLLVM_FORCE_HEAD_REVISION']
553 cxxflags += ['-DLLVM_FORCE_HEAD_REVISION'] 614 cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']
554 615
555 CreateChromeToolsShim() 616 CreateChromeToolsShim()
556 617
557 deployment_env = None 618 deployment_env = None
558 if deployment_target: 619 if deployment_target:
559 deployment_env = os.environ.copy() 620 deployment_env = os.environ.copy()
560 deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target 621 deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
561 622
562 cmake_args = base_cmake_args + [ 623 cmake_args = []
624 # TODO(thakis): Unconditionally append this to base_cmake_args instead once
625 # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
626 cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
627 if cc is not None: cc_args.append('-DCMAKE_C_COMPILER=' + cc)
628 if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
629 cmake_args += base_cmake_args + [
563 '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir, 630 '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
564 '-DCMAKE_C_FLAGS=' + ' '.join(cflags), 631 '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
565 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags), 632 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
566 '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags), 633 '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
567 '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags), 634 '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
568 '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags), 635 '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags),
569 '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR, 636 '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
637 # TODO(thakis): Remove this once official builds pass -Wl,--build-id
638 # explicitly, https://crbug.com/622775
639 '-DENABLE_LINKER_BUILD_ID=ON',
570 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'), 640 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
571 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)] 641 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
572 # TODO(thakis): Unconditionally append this to base_cmake_args instead once
573 # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
574 cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
575 if cc is not None: cc_args.append('-DCMAKE_C_COMPILER=' + cc)
576 if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
577 642
578 if not os.path.exists(LLVM_BUILD_DIR): 643 EnsureDirExists(LLVM_BUILD_DIR)
579 os.makedirs(LLVM_BUILD_DIR)
580 os.chdir(LLVM_BUILD_DIR) 644 os.chdir(LLVM_BUILD_DIR)
645 RmCmakeCache('.')
581 RunCommand(['cmake'] + cmake_args + [LLVM_DIR], 646 RunCommand(['cmake'] + cmake_args + [LLVM_DIR],
582 msvc_arch='x64', env=deployment_env) 647 msvc_arch='x64', env=deployment_env)
648
649 if args.gcc_toolchain:
650 # Copy in the right stdlibc++.so.6 so clang can start.
651 if not os.path.exists(os.path.join(LLVM_BUILD_DIR, 'lib')):
652 os.mkdir(os.path.join(LLVM_BUILD_DIR, 'lib'))
653 libstdcpp = subprocess.check_output(
654 [cxx] + cxxflags + ['-print-file-name=libstdc++.so.6']).rstrip()
655 CopyFile(libstdcpp, os.path.join(LLVM_BUILD_DIR, 'lib'))
656
583 RunCommand(['ninja'], msvc_arch='x64') 657 RunCommand(['ninja'], msvc_arch='x64')
584 658
585 if args.tools: 659 if args.tools:
586 # If any Chromium tools were built, install those now. 660 # If any Chromium tools were built, install those now.
587 RunCommand(['ninja', 'cr-install'], msvc_arch='x64') 661 RunCommand(['ninja', 'cr-install'], msvc_arch='x64')
588 662
589 if sys.platform == 'darwin': 663 if sys.platform == 'darwin':
590 CopyFile(os.path.join(LLVM_BUILD_DIR, 'libc++.1.dylib'),
591 os.path.join(LLVM_BUILD_DIR, 'bin'))
592 # See http://crbug.com/256342 664 # See http://crbug.com/256342
593 RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) 665 RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
594 elif sys.platform.startswith('linux'): 666 elif sys.platform.startswith('linux'):
595 RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) 667 RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
596 668
597 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time. 669 VeryifyVersionOfBuiltClangMatchesVERSION()
670
671 # Do an out-of-tree build of compiler-rt.
672 # On Windows, this is used to get the 32-bit ASan run-time.
598 # TODO(hans): Remove once the regular build above produces this. 673 # TODO(hans): Remove once the regular build above produces this.
599 if not os.path.exists(COMPILER_RT_BUILD_DIR): 674 # On Mac and Linux, this is used to get the regular 64-bit run-time.
600 os.makedirs(COMPILER_RT_BUILD_DIR) 675 # Do a clobbered build due to cmake changes.
676 if os.path.isdir(COMPILER_RT_BUILD_DIR):
677 RmTree(COMPILER_RT_BUILD_DIR)
678 os.makedirs(COMPILER_RT_BUILD_DIR)
601 os.chdir(COMPILER_RT_BUILD_DIR) 679 os.chdir(COMPILER_RT_BUILD_DIR)
602 # TODO(thakis): Add this once compiler-rt can build with clang-cl (see 680 # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
603 # above). 681 # above).
604 #if args.bootstrap and sys.platform == 'win32': 682 #if args.bootstrap and sys.platform == 'win32':
605 # The bootstrap compiler produces 64-bit binaries by default. 683 # The bootstrap compiler produces 64-bit binaries by default.
606 #cflags += ['-m32'] 684 #cflags += ['-m32']
607 #cxxflags += ['-m32'] 685 #cxxflags += ['-m32']
608 compiler_rt_args = base_cmake_args + [ 686 compiler_rt_args = base_cmake_args + [
609 '-DCMAKE_C_FLAGS=' + ' '.join(cflags), 687 '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
610 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)] 688 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)]
689 if sys.platform == 'darwin':
690 compiler_rt_args += ['-DCOMPILER_RT_ENABLE_IOS=ON']
611 if sys.platform != 'win32': 691 if sys.platform != 'win32':
612 compiler_rt_args += ['-DLLVM_CONFIG_PATH=' + 692 compiler_rt_args += ['-DLLVM_CONFIG_PATH=' +
613 os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config')] 693 os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config'),
614 RunCommand(['cmake'] + compiler_rt_args + [LLVM_DIR], 694 '-DSANITIZER_MIN_OSX_VERSION="10.7"']
615 msvc_arch='x86', env=deployment_env) 695 # compiler-rt is part of the llvm checkout on Windows but a stand-alone
696 # directory elsewhere, see the TODO above COMPILER_RT_DIR.
697 RmCmakeCache('.')
698 RunCommand(['cmake'] + compiler_rt_args +
699 [LLVM_DIR if sys.platform == 'win32' else COMPILER_RT_DIR],
700 msvc_arch='x86', env=deployment_env)
616 RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86') 701 RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')
617 702
703 # Copy select output to the main tree.
618 # TODO(hans): Make this (and the .gypi and .isolate files) version number 704 # TODO(hans): Make this (and the .gypi and .isolate files) version number
619 # independent. 705 # independent.
620 if sys.platform == 'win32': 706 if sys.platform == 'win32':
621 platform = 'windows' 707 platform = 'windows'
622 elif sys.platform == 'darwin': 708 elif sys.platform == 'darwin':
623 platform = 'darwin' 709 platform = 'darwin'
624 else: 710 else:
625 assert sys.platform.startswith('linux') 711 assert sys.platform.startswith('linux')
626 platform = 'linux' 712 platform = 'linux'
627 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang', 713 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', platform)
628 VERSION, 'lib', platform) 714 if sys.platform == 'win32':
715 # TODO(thakis): This too is due to compiler-rt being part of the checkout
716 # on Windows, see TODO above COMPILER_RT_DIR.
717 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
718 VERSION, 'lib', platform)
629 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 719 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
630 VERSION, 'lib', platform) 720 VERSION, 'lib', platform)
631 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir, 721 # Blacklists:
632 r'^.*-i386\.lib$') 722 CopyDirectoryContents(os.path.join(asan_rt_lib_src_dir, '..', '..'),
633 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir, 723 os.path.join(asan_rt_lib_dst_dir, '..', '..'),
634 r'^.*-i386\.dll$') 724 r'^.*blacklist\.txt$')
725 # Headers:
726 if sys.platform != 'win32':
727 CopyDirectoryContents(
728 os.path.join(COMPILER_RT_BUILD_DIR, 'include/sanitizer'),
729 os.path.join(LLVM_BUILD_DIR, 'lib/clang', VERSION, 'include/sanitizer'))
730 # Static and dynamic libraries:
731 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir)
732 if sys.platform == 'darwin':
733 for dylib in glob.glob(os.path.join(asan_rt_lib_dst_dir, '*.dylib')):
734 # Fix LC_ID_DYLIB for the ASan dynamic libraries to be relative to
735 # @executable_path.
736 # TODO(glider): this is transitional. We'll need to fix the dylib
737 # name either in our build system, or in Clang. See also
738 # http://crbug.com/344836.
739 subprocess.call(['install_name_tool', '-id',
740 '@executable_path/' + os.path.basename(dylib), dylib])
635 741
636 CopyFile(os.path.join(asan_rt_lib_src_dir, '..', '..', 'asan_blacklist.txt'),
637 os.path.join(asan_rt_lib_dst_dir, '..', '..'))
638 742
639 if sys.platform == 'win32': 743 if sys.platform == 'win32':
640 # Make an extra copy of the sanitizer headers, to be put on the include path 744 # Make an extra copy of the sanitizer headers, to be put on the include path
641 # of the fallback compiler. 745 # of the fallback compiler.
642 sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 746 sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
643 VERSION, 'include', 'sanitizer') 747 VERSION, 'include', 'sanitizer')
644 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 748 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
645 VERSION, 'include_sanitizer', 749 VERSION, 'include_sanitizer',
646 'sanitizer') 750 'sanitizer')
647 if not os.path.exists(aux_sanitizer_include_dir): 751 EnsureDirExists(aux_sanitizer_include_dir)
648 os.makedirs(aux_sanitizer_include_dir)
649 for _, _, files in os.walk(sanitizer_include_dir): 752 for _, _, files in os.walk(sanitizer_include_dir):
650 for f in files: 753 for f in files:
651 CopyFile(os.path.join(sanitizer_include_dir, f), 754 CopyFile(os.path.join(sanitizer_include_dir, f),
652 aux_sanitizer_include_dir) 755 aux_sanitizer_include_dir)
653 756
757 if args.with_android:
758 make_toolchain = os.path.join(
759 ANDROID_NDK_DIR, 'build', 'tools', 'make_standalone_toolchain.py')
760 for target_arch in ['aarch64', 'arm', 'i686']:
761 # Make standalone Android toolchain for target_arch.
762 toolchain_dir = os.path.join(
763 LLVM_BUILD_DIR, 'android-toolchain-' + target_arch)
764 RunCommand([
765 make_toolchain,
766 '--api=' + ('21' if target_arch == 'aarch64' else '19'),
767 '--force',
768 '--install-dir=%s' % toolchain_dir,
769 '--stl=stlport',
770 '--arch=' + {
771 'aarch64': 'arm64',
772 'arm': 'arm',
773 'i686': 'x86',
774 }[target_arch]])
775 # Android NDK r9d copies a broken unwind.h into the toolchain, see
776 # http://crbug.com/357890
777 for f in glob.glob(os.path.join(toolchain_dir, 'include/c++/*/unwind.h')):
778 os.remove(f)
779
780 # Build ASan runtime for Android in a separate build tree.
781 build_dir = os.path.join(LLVM_BUILD_DIR, 'android-' + target_arch)
782 if not os.path.exists(build_dir):
783 os.mkdir(os.path.join(build_dir))
784 os.chdir(build_dir)
785 cflags = ['--target=%s-linux-androideabi' % target_arch,
786 '--sysroot=%s/sysroot' % toolchain_dir,
787 '-B%s' % toolchain_dir]
788 android_args = base_cmake_args + [
789 '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
790 '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
791 '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
792 '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
793 '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
794 '-DANDROID=1']
795 RmCmakeCache('.')
796 RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR])
797 RunCommand(['ninja', 'libclang_rt.asan-%s-android.so' % target_arch])
798
799 # And copy it into the main build tree.
800 runtime = 'libclang_rt.asan-%s-android.so' % target_arch
801 for root, _, files in os.walk(build_dir):
802 if runtime in files:
803 shutil.copy(os.path.join(root, runtime), asan_rt_lib_dst_dir)
804
654 # Run tests. 805 # Run tests.
655 if args.run_tests or use_head_revision: 806 if args.run_tests or use_head_revision:
656 os.chdir(LLVM_BUILD_DIR) 807 os.chdir(LLVM_BUILD_DIR)
657 RunCommand(GetVSVersion().SetupScript('x64') + 808 RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64')
658 ['&&', 'ninja', 'cr-check-all'])
659 if args.run_tests: 809 if args.run_tests:
810 if sys.platform == 'win32':
811 CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
660 os.chdir(LLVM_BUILD_DIR) 812 os.chdir(LLVM_BUILD_DIR)
661 RunCommand(GetVSVersion().SetupScript('x64') + 813 RunCommand(['ninja', 'check-all'], msvc_arch='x64')
662 ['&&', 'ninja', 'check-all'])
663 814
664 WriteStampFile(PACKAGE_VERSION) 815 WriteStampFile(PACKAGE_VERSION)
665 print 'Clang update was successful.' 816 print 'Clang update was successful.'
666 return 0 817 return 0
667 818
668 819
669 def main(): 820 def main():
670 if not sys.platform in ['win32', 'cygwin']:
671 # For non-Windows, fall back to update.sh.
672 # TODO(hans): Make update.py replace update.sh completely.
673
674 # This script is called by gclient. gclient opens its hooks subprocesses
675 # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does
676 # custom output processing that breaks printing '\r' characters for
677 # single-line updating status messages as printed by curl and wget.
678 # Work around this by setting stderr of the update.sh process to stdin (!):
679 # gclient doesn't redirect stdin, and while stdin itself is read-only, a
680 # dup()ed sys.stdin is writable, try
681 # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi')
682 # TODO: Fix gclient instead, http://crbug.com/95350
683 if '--no-stdin-hack' in sys.argv:
684 sys.argv.remove('--no-stdin-hack')
685 stderr = None
686 else:
687 try:
688 stderr = os.fdopen(os.dup(sys.stdin.fileno()))
689 except:
690 stderr = sys.stderr
691 return subprocess.call(
692 [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:],
693 stderr=stderr)
694
695 parser = argparse.ArgumentParser(description='Build Clang.') 821 parser = argparse.ArgumentParser(description='Build Clang.')
696 parser.add_argument('--bootstrap', action='store_true', 822 parser.add_argument('--bootstrap', action='store_true',
697 help='first build clang with CC, then with itself.') 823 help='first build clang with CC, then with itself.')
698 parser.add_argument('--if-needed', action='store_true', 824 parser.add_argument('--if-needed', action='store_true',
699 help="run only if the script thinks clang is needed") 825 help="run only if the script thinks clang is needed")
700 parser.add_argument('--force-local-build', action='store_true', 826 parser.add_argument('--force-local-build', action='store_true',
701 help="don't try to download prebuild binaries") 827 help="don't try to download prebuild binaries")
828 parser.add_argument('--gcc-toolchain', help='set the version for which gcc '
829 'version be used for building; --gcc-toolchain=/opt/foo '
830 'picks /opt/foo/bin/gcc')
831 parser.add_argument('--lto-gold-plugin', action='store_true',
832 help='build LLVM Gold plugin with LTO')
833 parser.add_argument('--llvm-force-head-revision', action='store_true',
834 help=('use the revision in the repo when printing '
835 'the revision'))
702 parser.add_argument('--print-revision', action='store_true', 836 parser.add_argument('--print-revision', action='store_true',
703 help='print current clang revision and exit.') 837 help='print current clang revision and exit.')
704 parser.add_argument('--print-clang-version', action='store_true', 838 parser.add_argument('--print-clang-version', action='store_true',
705 help='print current clang version (e.g. x.y.z) and exit.') 839 help='print current clang version (e.g. x.y.z) and exit.')
706 parser.add_argument('--run-tests', action='store_true', 840 parser.add_argument('--run-tests', action='store_true',
707 help='run tests after building; only for local builds') 841 help='run tests after building; only for local builds')
708 parser.add_argument('--tools', nargs='*', 842 parser.add_argument('--tools', nargs='*',
709 help='select which chrome tools to build', 843 help='select which chrome tools to build',
710 default=['plugins', 'blink_gc_plugin']) 844 default=['plugins', 'blink_gc_plugin'])
711 parser.add_argument('--without-patches', action='store_false', 845 parser.add_argument('--without-android', action='store_false',
712 help="don't apply patches (default)", dest='with_patches', 846 help='don\'t build Android ASan runtime (linux only)',
713 default=True) 847 dest='with_android',
848 default=sys.platform.startswith('linux'))
849 args = parser.parse_args()
714 850
715 # For now, these flags are only used for the non-Windows flow, but argparser 851 if args.lto_gold_plugin and not args.bootstrap:
716 # gets mad if it sees a flag it doesn't recognize. 852 print '--lto-gold-plugin requires --bootstrap'
717 parser.add_argument('--no-stdin-hack', action='store_true') 853 return 1
718 854 if args.lto_gold_plugin and not sys.platform.startswith('linux'):
719 args = parser.parse_args() 855 print '--lto-gold-plugin is only effective on Linux. Ignoring the option.'
856 args.lto_gold_plugin = False
720 857
721 if args.if_needed: 858 if args.if_needed:
722 is_clang_required = False 859 is_clang_required = False
723 # clang is always used on Mac and Linux. 860 # clang is always used on Mac and Linux.
724 if sys.platform == 'darwin' or sys.platform.startswith('linux'): 861 if sys.platform == 'darwin' or sys.platform.startswith('linux'):
725 is_clang_required = True 862 is_clang_required = True
726 # clang requested via $GYP_DEFINES. 863 # clang requested via $GYP_DEFINES.
727 if re.search(r'\b(clang|asan|lsan|msan|tsan)=1', 864 if re.search(r'\b(clang|asan|lsan|msan|tsan)=1',
728 os.environ.get('GYP_DEFINES', '')): 865 os.environ.get('GYP_DEFINES', '')):
729 is_clang_required = True 866 is_clang_required = True
730 # clang previously downloaded, keep it up-to-date. 867 # clang previously downloaded, keep it up to date.
731 # If you don't want this, delete third_party/llvm-build on your machine. 868 # If you don't want this, delete third_party/llvm-build on your machine.
732 if os.path.isdir(LLVM_BUILD_DIR): 869 if os.path.isdir(LLVM_BUILD_DIR):
733 is_clang_required = True 870 is_clang_required = True
734 if not is_clang_required: 871 if not is_clang_required:
735 return 0 872 return 0
736 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): 873 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')):
737 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' 874 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
738 return 0 875 return 0
739 876
740 global LLVM_WIN_REVISION, PACKAGE_VERSION 877 global CLANG_REVISION, PACKAGE_VERSION
741 if args.print_revision: 878 if args.print_revision:
742 if use_head_revision: 879 if use_head_revision or args.llvm_force_head_revision:
743 print GetSvnRevision(LLVM_DIR) 880 print GetSvnRevision(LLVM_DIR)
744 else: 881 else:
745 print PACKAGE_VERSION 882 print PACKAGE_VERSION
746 return 0 883 return 0
747 884
748 if args.print_clang_version: 885 if args.print_clang_version:
749 sys.stdout.write(VERSION) 886 sys.stdout.write(VERSION)
750 return 0 887 return 0
751 888
752 # Don't buffer stdout, so that print statements are immediately flushed. 889 # Don't buffer stdout, so that print statements are immediately flushed.
753 # Do this only after --print-revision has been handled, else we'll get 890 # Do this only after --print-revision has been handled, else we'll get
754 # an error message when this script is run from gn for some reason. 891 # an error message when this script is run from gn for some reason.
755 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) 892 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
756 893
757 if use_head_revision: 894 if use_head_revision:
758 # Use a real revision number rather than HEAD to make sure that the stamp 895 # Use a real revision number rather than HEAD to make sure that the stamp
759 # file logic works. 896 # file logic works.
760 LLVM_WIN_REVISION = GetSvnRevision(LLVM_REPO_URL) 897 CLANG_REVISION = GetSvnRevision(LLVM_REPO_URL)
761 PACKAGE_VERSION = LLVM_WIN_REVISION + '-0' 898 PACKAGE_VERSION = CLANG_REVISION + '-0'
762 899
763 args.force_local_build = True 900 args.force_local_build = True
764 # Skip local patches when using HEAD: they probably don't apply anymore. 901 if 'OS=android' not in os.environ.get('GYP_DEFINES', ''):
765 args.with_patches = False 902 # Only build the Android ASan rt on ToT bots when targetting Android.
903 args.with_android = False
766 904
767 return UpdateClang(args) 905 return UpdateClang(args)
768 906
769 907
770 if __name__ == '__main__': 908 if __name__ == '__main__':
771 sys.exit(main()) 909 sys.exit(main())
OLDNEW
« no previous file with comments | « DEPS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698