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

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

Issue 1841863002: Update monet. (Closed) Base URL: https://github.com/domokit/monet.git@master
Patch Set: Created 4 years, 8 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
12 import glob
10 import os 13 import os
14 import pipes
11 import re 15 import re
12 import shutil 16 import shutil
13 import subprocess 17 import subprocess
14 import stat 18 import stat
15 import sys 19 import sys
20 import tarfile
16 import time 21 import time
22 import urllib2
23 import zipfile
17 24
18 # 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
19 # https://code.google.com/p/chromium/wiki/UpdatingClang 26 # https://code.google.com/p/chromium/wiki/UpdatingClang
20 # Reverting problematic clang rolls is safe, though. 27 # Reverting problematic clang rolls is safe, though.
21 # Note: this revision is only used for Windows. Other platforms use update.sh. 28 # Note: this revision is only used for Windows. Other platforms use update.sh.
22 LLVM_WIN_REVISION = 'HEAD' 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 = '247874'
23 32
24 # ASan on Windows is useful enough to use it even while the clang/win is still 33 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
25 # in bringup. Use a pinned revision to make it slightly more stable. 34 if use_head_revision:
26 use_head_revision = ('LLVM_FORCE_HEAD_REVISION' in os.environ or 35 LLVM_WIN_REVISION = 'HEAD'
27 not re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')))
28 36
29 if not use_head_revision: 37 # This is incremented when pushing a new build of Clang at the same revision.
30 LLVM_WIN_REVISION = '235968' 38 CLANG_SUB_REVISION=1
39
40 PACKAGE_VERSION = "%s-%s" % (LLVM_WIN_REVISION, CLANG_SUB_REVISION)
31 41
32 # Path constants. (All of these should be absolute paths.) 42 # Path constants. (All of these should be absolute paths.)
33 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) 43 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
34 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) 44 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
35 LLVM_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm') 45 THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
46 LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm')
47 LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
48 LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
49 'llvm-bootstrap-install')
36 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools') 50 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
37 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',
38 'Release+Asserts') 52 'Release+Asserts')
39 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') 53 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt')
40 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang') 54 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
41 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld') 55 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
42 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt') 56 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
43 STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision') 57 LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx')
44 VERSION = '3.7.0' 58 LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
59 LLVM_BUILD_TOOLS_DIR = os.path.abspath(
60 os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
61 STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')
62 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
63 VERSION = '3.8.0'
64
65 # URL for pre-built binaries.
66 CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang'
45 67
46 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' 68 LLVM_REPO_URL='https://llvm.org/svn/llvm-project'
47 if 'LLVM_REPO_URL' in os.environ: 69 if 'LLVM_REPO_URL' in os.environ:
48 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] 70 LLVM_REPO_URL = os.environ['LLVM_REPO_URL']
49 71
50 72
73 def DownloadUrl(url, output_file):
74 """Download url into output_file."""
75 CHUNK_SIZE = 4096
76 TOTAL_DOTS = 10
77 sys.stdout.write('Downloading %s ' % url)
78 sys.stdout.flush()
79 response = urllib2.urlopen(url)
80 total_size = int(response.info().getheader('Content-Length').strip())
81 bytes_done = 0
82 dots_printed = 0
83 while True:
84 chunk = response.read(CHUNK_SIZE)
85 if not chunk:
86 break
87 output_file.write(chunk)
88 bytes_done += len(chunk)
89 num_dots = TOTAL_DOTS * bytes_done / total_size
90 sys.stdout.write('.' * (num_dots - dots_printed))
91 sys.stdout.flush()
92 dots_printed = num_dots
93 print ' Done.'
94
95
51 def ReadStampFile(): 96 def ReadStampFile():
52 """Return the contents of the stamp file, or '' if it doesn't exist.""" 97 """Return the contents of the stamp file, or '' if it doesn't exist."""
53 try: 98 try:
54 with open(STAMP_FILE, 'r') as f: 99 with open(STAMP_FILE, 'r') as f:
55 return f.read(); 100 return f.read()
56 except IOError: 101 except IOError:
57 return '' 102 return ''
58 103
59 104
60 def WriteStampFile(s): 105 def WriteStampFile(s):
61 """Write s to the stamp file.""" 106 """Write s to the stamp file."""
62 if not os.path.exists(LLVM_BUILD_DIR): 107 if not os.path.exists(os.path.dirname(STAMP_FILE)):
63 os.makedirs(LLVM_BUILD_DIR) 108 os.makedirs(os.path.dirname(STAMP_FILE))
64 with open(STAMP_FILE, 'w') as f: 109 with open(STAMP_FILE, 'w') as f:
65 f.write(s) 110 f.write(s)
66 111
67 112
68 def PrintRevision(): 113 def GetSvnRevision(svn_repo):
69 """Print the current Clang revision.""" 114 """Returns current revision of the svn repo at svn_repo."""
70 # gyp runs update.py --print-revision even when clang isn't used. 115 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) 116 m = re.search(r'Revision: (\d+)', svn_info)
79 assert m 117 return m.group(1)
80 print m.group(1)
81 118
82 119
83 def RmTree(dir): 120 def RmTree(dir):
84 """Delete dir.""" 121 """Delete dir."""
85 def ChmodAndRetry(func, path, _): 122 def ChmodAndRetry(func, path, _):
86 # Subversion can leave read-only files around. 123 # Subversion can leave read-only files around.
87 if not os.access(path, os.W_OK): 124 if not os.access(path, os.W_OK):
88 os.chmod(path, stat.S_IWUSR) 125 os.chmod(path, stat.S_IWUSR)
89 return func(path) 126 return func(path)
90 raise 127 raise
91 128
92 shutil.rmtree(dir, onerror=ChmodAndRetry) 129 shutil.rmtree(dir, onerror=ChmodAndRetry)
93 130
94 131
95 def RunCommand(command, fail_hard=True): 132 def RunCommand(command, msvc_arch=None, env=None, fail_hard=True):
96 """Run command and return success (True) or failure; or if fail_hard is 133 """Run command and return success (True) or failure; or if fail_hard is
97 True, exit on failure.""" 134 True, exit on failure. If msvc_arch is set, runs the command in a
135 shell with the msvc tools for that architecture."""
98 136
99 print 'Running %s' % (str(command)) 137 if msvc_arch and sys.platform == 'win32':
100 if subprocess.call(command, shell=True) == 0: 138 command = GetVSVersion().SetupScript(msvc_arch) + ['&&'] + command
139
140 # https://docs.python.org/2/library/subprocess.html:
141 # "On Unix with shell=True [...] if args is a sequence, the first item
142 # specifies the command string, and any additional items will be treated as
143 # additional arguments to the shell itself. That is to say, Popen does the
144 # equivalent of:
145 # Popen(['/bin/sh', '-c', args[0], args[1], ...])"
146 #
147 # We want to pass additional arguments to command[0], not to the shell,
148 # so manually join everything into a single string.
149 # Annoyingly, for "svn co url c:\path", pipes.quote() thinks that it should
150 # quote c:\path but svn can't handle quoted paths on Windows. Since on
151 # Windows follow-on args are passed to args[0] instead of the shell, don't
152 # do the single-string transformation there.
153 if sys.platform != 'win32':
154 command = ' '.join([pipes.quote(c) for c in command])
155 print 'Running', command
156 if subprocess.call(command, env=env, shell=True) == 0:
101 return True 157 return True
102 print 'Failed.' 158 print 'Failed.'
103 if fail_hard: 159 if fail_hard:
104 sys.exit(1) 160 sys.exit(1)
105 return False 161 return False
106 162
107 163
108 def CopyFile(src, dst): 164 def CopyFile(src, dst):
109 """Copy a file from src to dst.""" 165 """Copy a file from src to dst."""
110 shutil.copy(src, dst) 166 shutil.copy(src, dst)
(...skipping 21 matching lines...) Expand all
132 return 188 return
133 189
134 if os.path.isdir(dir): 190 if os.path.isdir(dir):
135 print "Removing %s." % (dir) 191 print "Removing %s." % (dir)
136 RmTree(dir) 192 RmTree(dir)
137 193
138 print "Retrying." 194 print "Retrying."
139 RunCommand(command) 195 RunCommand(command)
140 196
141 197
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 # No patches.
245
246
142 def DeleteChromeToolsShim(): 247 def DeleteChromeToolsShim():
248 OLD_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'zzz-chrometools')
249 shutil.rmtree(OLD_SHIM_DIR, ignore_errors=True)
143 shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True) 250 shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)
144 251
145 252
146 def CreateChromeToolsShim(): 253 def CreateChromeToolsShim():
147 """Hooks the Chrome tools into the LLVM build. 254 """Hooks the Chrome tools into the LLVM build.
148 255
149 Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build 256 Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build
150 detects implicit tools in the tools subdirectory, so this helper install a 257 detects implicit tools in the tools subdirectory, so this helper install a
151 shim CMakeLists.txt that forwards to the real directory for the Chrome tools. 258 shim CMakeLists.txt that forwards to the real directory for the Chrome tools.
152 259
153 Note that the shim directory name intentionally has no - or _. The implicit 260 Note that the shim directory name intentionally has no - or _. The implicit
154 tool detection logic munges them in a weird way.""" 261 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 '-_') 262 assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
156 os.mkdir(CHROME_TOOLS_SHIM_DIR) 263 os.mkdir(CHROME_TOOLS_SHIM_DIR)
157 with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f: 264 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. ' + 265 f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
159 'Do not edit.\n') 266 'Do not edit.\n')
160 f.write('# Since tools/clang is located in another directory, use the \n') 267 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') 268 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') 269 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') 270 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
164 f.write('add_subdirectory(${CHROMIUM_TOOLS_SRC} ' + 271 f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
165 '${CMAKE_CURRENT_BINARY_DIR}/a)\n') 272 f.write('if (CHROMIUM_TOOLS_SRC)\n')
273 f.write(' add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
274 '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
275 f.write('endif (CHROMIUM_TOOLS_SRC)\n')
166 276
167 277
168 def AddCMakeToPath(): 278 def AddCMakeToPath():
169 """Look for CMake and add it to PATH if it's not there already.""" 279 """Download CMake and add it to PATH."""
170 try: 280 if sys.platform == 'win32':
171 # First check if cmake is already on PATH. 281 zip_name = 'cmake-3.2.2-win32-x86.zip'
172 subprocess.call(['cmake', '--version']) 282 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR,
173 return 283 'cmake-3.2.2-win32-x86', 'bin')
174 except OSError as e: 284 else:
175 if e.errno != os.errno.ENOENT: 285 suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux'
176 raise 286 zip_name = 'cmake310_%s.tgz' % suffix
177 287 cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake310', 'bin')
178 cmake_dir = 'C:\\Program Files (x86)\\CMake\\bin' 288 if not os.path.exists(cmake_dir):
179 if os.path.isdir(cmake_dir): 289 if not os.path.exists(LLVM_BUILD_TOOLS_DIR):
180 os.environ['PATH'] = os.environ.get('PATH', '') + os.pathsep + cmake_dir 290 os.makedirs(LLVM_BUILD_TOOLS_DIR)
181 return 291 # The cmake archive is smaller than 20 MB, small enough to keep in memory:
182 print 'Failed to find CMake!' 292 with contextlib.closing(cStringIO.StringIO()) as f:
183 sys.exit(1) 293 DownloadUrl(CDS_URL + '/tools/' + zip_name, f)
184 294 f.seek(0)
295 if zip_name.endswith('.zip'):
296 zipfile.ZipFile(f).extractall(path=LLVM_BUILD_TOOLS_DIR)
297 else:
298 tarfile.open(mode='r:gz', fileobj=f).extractall(path=
299 LLVM_BUILD_TOOLS_DIR)
300 os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
185 301
186 vs_version = None 302 vs_version = None
187 def GetVSVersion(): 303 def GetVSVersion():
188 global vs_version 304 global vs_version
189 if vs_version: 305 if vs_version:
190 return vs_version 306 return vs_version
191 307
192 # Try using the toolchain in depot_tools. 308 # Try using the toolchain in depot_tools.
193 # This sets environment variables used by SelectVisualStudioVersion below. 309 # This sets environment variables used by SelectVisualStudioVersion below.
194 sys.path.append(os.path.join(CHROMIUM_DIR, 'build')) 310 sys.path.append(os.path.join(CHROMIUM_DIR, 'build'))
195 import vs_toolchain 311 import vs_toolchain
196 vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs() 312 vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
197 313
198 # Use gyp to find the MSVS installation, either in depot_tools as per above, 314 # Use gyp to find the MSVS installation, either in depot_tools as per above,
199 # or a system-wide installation otherwise. 315 # or a system-wide installation otherwise.
200 sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib')) 316 sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib'))
201 import gyp.MSVSVersion 317 import gyp.MSVSVersion
202 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion('2013') 318 vs_version = gyp.MSVSVersion.SelectVisualStudioVersion('2013')
203 return vs_version 319 return vs_version
204 320
205 321
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): 322 def UpdateClang(args):
219 print 'Updating Clang to %s...' % (LLVM_WIN_REVISION) 323 print 'Updating Clang to %s...' % PACKAGE_VERSION
220 if LLVM_WIN_REVISION != 'HEAD' and ReadStampFile() == LLVM_WIN_REVISION: 324 if ReadStampFile() == PACKAGE_VERSION:
221 print 'Already up to date.' 325 print 'Already up to date.'
222 return 0 326 return 0
223 327
224 AddCMakeToPath()
225 # Reset the stamp file in case the build is unsuccessful. 328 # Reset the stamp file in case the build is unsuccessful.
226 WriteStampFile('') 329 WriteStampFile('')
227 330
228 DeleteChromeToolsShim(); 331 if not args.force_local_build:
332 cds_file = "clang-%s.tgz" % PACKAGE_VERSION
333 cds_full_url = CDS_URL + '/Win/' + cds_file
334
335 # Check if there's a prebuilt binary and if so just fetch that. That's
336 # faster, and goma relies on having matching binary hashes on client and
337 # server too.
338 print 'Trying to download prebuilt clang'
339
340 # clang packages are smaller than 50 MB, small enough to keep in memory.
341 with contextlib.closing(cStringIO.StringIO()) as f:
342 try:
343 DownloadUrl(cds_full_url, f)
344 f.seek(0)
345 # TODO(thakis): Delete LLVM_BUILD_DIR before extracting.
346 tarfile.open(mode='r:gz', fileobj=f).extractall(path=LLVM_BUILD_DIR)
347 print 'clang %s unpacked' % PACKAGE_VERSION
348 # Download the gold plugin if requested to by an environment variable.
349 # This is used by the CFI ClusterFuzz bot.
350 if 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ:
351 RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
352 WriteStampFile(PACKAGE_VERSION)
353 return 0
354 except urllib2.HTTPError:
355 print 'Did not find prebuilt clang %s, building locally' % cds_file
356
357 AddCMakeToPath()
358
359 RevertPreviouslyPatchedFiles()
360 DeleteChromeToolsShim()
361
229 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) 362 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
230 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) 363 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
231 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) 364 if sys.platform == 'win32':
365 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
232 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) 366 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
233 CreateChromeToolsShim(); 367 if sys.platform == 'darwin':
368 # clang needs a libc++ checkout, else -stdlib=libc++ won't find includes
369 # (i.e. this is needed for bootstrap builds).
370 Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR)
371 # While we're bundling our own libc++ on OS X, we need to compile libc++abi
372 # into it too (since OS X 10.6 doesn't have libc++abi.dylib either).
373 Checkout('libcxxabi', LLVM_REPO_URL + '/libcxxabi/trunk', LIBCXXABI_DIR)
374
375 if args.with_patches and sys.platform != 'win32':
376 ApplyLocalPatches()
377
378 cc, cxx = None, None
379 libstdcpp = None
380 if args.gcc_toolchain: # This option is only used on Linux.
381 # Use the specified gcc installation for building.
382 cc = os.path.join(args.gcc_toolchain, 'bin', 'gcc')
383 cxx = os.path.join(args.gcc_toolchain, 'bin', 'g++')
384
385 if not os.access(cc, os.X_OK):
386 print 'Invalid --gcc-toolchain: "%s"' % args.gcc_toolchain
387 print '"%s" does not appear to be valid.' % cc
388 return 1
389
390 # Set LD_LIBRARY_PATH to make auxiliary targets (tablegen, bootstrap
391 # compiler, etc.) find the .so.
392 libstdcpp = subprocess.check_output(
393 [cxx, '-print-file-name=libstdc++.so.6']).rstrip()
394 os.environ['LD_LIBRARY_PATH'] = os.path.dirname(libstdcpp)
395
396 cflags = cxxflags = ldflags = []
397
398 # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
399 # needed, on OS X it requires libc++. clang only automatically links to libc++
400 # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run
401 # on OS X versions as old as 10.7.
402 # TODO(thakis): Some bots are still on 10.6 (nacl...), so for now bundle
403 # libc++.dylib. Remove this once all bots are on 10.7+, then use
404 # -DLLVM_ENABLE_LIBCXX=ON and change deployment_target to 10.7.
405 deployment_target = ''
406
407 if sys.platform == 'darwin':
408 # When building on 10.9, /usr/include usually doesn't exist, and while
409 # Xcode's clang automatically sets a sysroot, self-built clangs don't.
410 cflags = ['-isysroot', subprocess.check_output(
411 ['xcrun', '--show-sdk-path']).rstrip()]
412 cxxflags = ['-stdlib=libc++', '-nostdinc++',
413 '-I' + os.path.join(LIBCXX_DIR, 'include')] + cflags
414 if args.bootstrap:
415 deployment_target = '10.6'
416
417 base_cmake_args = ['-GNinja',
418 '-DCMAKE_BUILD_TYPE=Release',
419 '-DLLVM_ENABLE_ASSERTIONS=ON',
420 '-DLLVM_ENABLE_THREADS=OFF',
421 ]
422
423 if args.bootstrap:
424 print 'Building bootstrap compiler'
425 if not os.path.exists(LLVM_BOOTSTRAP_DIR):
426 os.makedirs(LLVM_BOOTSTRAP_DIR)
427 os.chdir(LLVM_BOOTSTRAP_DIR)
428 bootstrap_args = base_cmake_args + [
429 '-DLLVM_TARGETS_TO_BUILD=host',
430 '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
431 '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
432 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
433 ]
434 if cc is not None: bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
435 if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
436 RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64')
437 RunCommand(['ninja'], msvc_arch='x64')
438 if args.run_tests:
439 RunCommand(['ninja', 'check-all'], msvc_arch='x64')
440 RunCommand(['ninja', 'install'], msvc_arch='x64')
441 if args.gcc_toolchain:
442 # Copy that gcc's stdlibc++.so.6 to the build dir, so the bootstrap
443 # compiler can start.
444 CopyFile(libstdcpp, os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'lib'))
445
446 if sys.platform == 'win32':
447 cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
448 cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
449 # CMake has a hard time with backslashes in compiler paths:
450 # https://stackoverflow.com/questions/13050827
451 cc = cc.replace('\\', '/')
452 cxx = cxx.replace('\\', '/')
453 else:
454 cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang')
455 cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++')
456
457 if args.gcc_toolchain:
458 # Tell the bootstrap compiler to use a specific gcc prefix to search
459 # for standard library headers and shared object files.
460 cflags = ['--gcc-toolchain=' + args.gcc_toolchain]
461 cxxflags = ['--gcc-toolchain=' + args.gcc_toolchain]
462 print 'Building final compiler'
463
464 if sys.platform == 'darwin':
465 # Build libc++.dylib while some bots are still on OS X 10.6.
466 libcxxbuild = os.path.join(LLVM_BUILD_DIR, 'libcxxbuild')
467 if os.path.isdir(libcxxbuild):
468 RmTree(libcxxbuild)
469 libcxxflags = ['-O3', '-std=c++11', '-fstrict-aliasing']
470
471 # libcxx and libcxxabi both have a file stdexcept.cpp, so put their .o files
472 # into different subdirectories.
473 os.makedirs(os.path.join(libcxxbuild, 'libcxx'))
474 os.chdir(os.path.join(libcxxbuild, 'libcxx'))
475 RunCommand(['c++', '-c'] + cxxflags + libcxxflags +
476 glob.glob(os.path.join(LIBCXX_DIR, 'src', '*.cpp')))
477
478 os.makedirs(os.path.join(libcxxbuild, 'libcxxabi'))
479 os.chdir(os.path.join(libcxxbuild, 'libcxxabi'))
480 RunCommand(['c++', '-c'] + cxxflags + libcxxflags +
481 glob.glob(os.path.join(LIBCXXABI_DIR, 'src', '*.cpp')) +
482 ['-I' + os.path.join(LIBCXXABI_DIR, 'include')])
483
484 os.chdir(libcxxbuild)
485 libdir = os.path.join(LIBCXX_DIR, 'lib')
486 RunCommand(['cc'] + glob.glob('libcxx/*.o') + glob.glob('libcxxabi/*.o') +
487 ['-o', 'libc++.1.dylib', '-dynamiclib', '-nodefaultlibs',
488 '-current_version', '1', '-compatibility_version', '1', '-lSystem',
489 '-install_name', '@executable_path/libc++.dylib',
490 '-Wl,-unexported_symbols_list,' + libdir + '/libc++unexp.exp',
491 '-Wl,-force_symbols_not_weak_list,' + libdir + '/notweak.exp',
492 '-Wl,-force_symbols_weak_list,' + libdir + '/weak.exp'])
493 if os.path.exists('libc++.dylib'):
494 os.remove('libc++.dylib')
495 os.symlink('libc++.1.dylib', 'libc++.dylib')
496 ldflags += ['-stdlib=libc++', '-L' + libcxxbuild]
497
498 if args.bootstrap:
499 # Now that the libc++ headers have been installed and libc++.dylib is
500 # built, delete the libc++ checkout again so that it's not part of the
501 # main build below -- the libc++(abi) tests don't pass on OS X in
502 # bootstrap builds (http://llvm.org/PR24068)
503 RmTree(LIBCXX_DIR)
504 RmTree(LIBCXXABI_DIR)
505 cxxflags = ['-stdlib=libc++', '-nostdinc++',
506 '-I' + os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR,
507 'include/c++/v1')
508 ] + cflags
509
510 # Build clang.
511 binutils_incdir = ''
512 if sys.platform.startswith('linux'):
513 binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include')
514
515 # If building at head, define a macro that plugins can use for #ifdefing
516 # out code that builds at head, but not at LLVM_WIN_REVISION or vice versa.
517 if use_head_revision:
518 cflags += ['-DLLVM_FORCE_HEAD_REVISION']
519 cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']
520
521 CreateChromeToolsShim()
522
523 deployment_env = None
524 if deployment_target:
525 deployment_env = os.environ.copy()
526 deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
527
528 cmake_args = base_cmake_args + [
529 '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
530 '-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly',
531 '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
532 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
533 '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
534 '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
535 '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags),
536 '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
537 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
538 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
539 # TODO(thakis): Unconditionally append this to base_cmake_args instead once
540 # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
541 cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
542 if cc is not None: cc_args.append('-DCMAKE_C_COMPILER=' + cc)
543 if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
234 544
235 if not os.path.exists(LLVM_BUILD_DIR): 545 if not os.path.exists(LLVM_BUILD_DIR):
236 os.makedirs(LLVM_BUILD_DIR) 546 os.makedirs(LLVM_BUILD_DIR)
237 os.chdir(LLVM_BUILD_DIR) 547 os.chdir(LLVM_BUILD_DIR)
238 548 RunCommand(['cmake'] + cmake_args + [LLVM_DIR],
239 # If building at head, define a macro that plugins can use for #ifdefing 549 msvc_arch='x64', env=deployment_env)
240 # out code that builds at head, but not at CLANG_REVISION or vice versa. 550
241 cflags = cxxflags = '' 551 if args.gcc_toolchain:
242 552 # Copy in the right stdlibc++.so.6 so clang can start.
243 # TODO(thakis): Set this only conditionally if use_head_revision once posix 553 if not os.path.exists(os.path.join(LLVM_BUILD_DIR, 'lib')):
244 # and win clang are in sync. At the moment, the plugins only build at clang 554 os.mkdir(os.path.join(LLVM_BUILD_DIR, 'lib'))
245 # head on posix, but they build at both head and the pinned win version :-/ 555 libstdcpp = subprocess.check_output(
246 cflags += ' -DLLVM_FORCE_HEAD_REVISION' 556 [cxx] + cxxflags + ['-print-file-name=libstdc++.so.6']).rstrip()
247 cxxflags += ' -DLLVM_FORCE_HEAD_REVISION' 557 CopyFile(libstdcpp, os.path.join(LLVM_BUILD_DIR, 'lib'))
248 558
249 cmake_args = ['-GNinja', '-DCMAKE_BUILD_TYPE=Release', 559 RunCommand(['ninja'], msvc_arch='x64')
250 '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(), 560
251 '-DCMAKE_C_FLAGS=' + cflags, 561 if args.tools:
252 '-DCMAKE_CXX_FLAGS=' + cxxflags, 562 # If any Chromium tools were built, install those now.
253 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join( 563 RunCommand(['ninja', 'cr-install'], msvc_arch='x64')
254 CHROMIUM_DIR, 'tools', 'clang'), 564
255 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)] 565 if sys.platform == 'darwin':
256 566 CopyFile(os.path.join(LLVM_BUILD_DIR, 'libc++.1.dylib'),
257 RunCommand(GetVSVersion().SetupScript('x64') + 567 os.path.join(LLVM_BUILD_DIR, 'bin'))
258 ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) 568 # See http://crbug.com/256342
259 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all']) 569 RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
570 elif sys.platform.startswith('linux'):
571 RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
260 572
261 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time. 573 # 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. 574 # TODO(hans): Remove once the regular build above produces this.
263 if not os.path.exists(COMPILER_RT_BUILD_DIR): 575 if not os.path.exists(COMPILER_RT_BUILD_DIR):
264 os.makedirs(COMPILER_RT_BUILD_DIR) 576 os.makedirs(COMPILER_RT_BUILD_DIR)
265 os.chdir(COMPILER_RT_BUILD_DIR) 577 os.chdir(COMPILER_RT_BUILD_DIR)
266 RunCommand(GetVSVersion().SetupScript('x86') + 578 # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
267 ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) 579 # above).
268 RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt']) 580 #if args.bootstrap and sys.platform == 'win32':
581 # The bootstrap compiler produces 64-bit binaries by default.
582 #cflags += ['-m32']
583 #cxxflags += ['-m32']
584 compiler_rt_args = base_cmake_args + [
585 '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
586 '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)]
587 if sys.platform != 'win32':
588 compiler_rt_args += ['-DLLVM_CONFIG_PATH=' +
589 os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config'),
590 '-DSANITIZER_MIN_OSX_VERSION="10.7"']
591 RunCommand(['cmake'] + compiler_rt_args + [LLVM_DIR],
592 msvc_arch='x86', env=deployment_env)
593 RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')
269 594
270 # TODO(hans): Make this (and the .gypi and .isolate files) version number 595 # TODO(hans): Make this (and the .gypi and .isolate files) version number
271 # independent. 596 # independent.
597 if sys.platform == 'win32':
598 platform = 'windows'
599 elif sys.platform == 'darwin':
600 platform = 'darwin'
601 else:
602 assert sys.platform.startswith('linux')
603 platform = 'linux'
272 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang', 604 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
273 VERSION, 'lib', 'windows') 605 VERSION, 'lib', platform)
274 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 606 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
275 VERSION, 'lib', 'windows') 607 VERSION, 'lib', platform)
276 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir, 608 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir,
277 r'^.*-i386\.lib$') 609 r'^.*-i386\.lib$')
278 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir, 610 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir,
279 r'^.*-i386\.dll$') 611 r'^.*-i386\.dll$')
280 612
281 CopyFile(os.path.join(asan_rt_lib_src_dir, '..', '..', 'asan_blacklist.txt'), 613 CopyFile(os.path.join(asan_rt_lib_src_dir, '..', '..', 'asan_blacklist.txt'),
282 os.path.join(asan_rt_lib_dst_dir, '..', '..')) 614 os.path.join(asan_rt_lib_dst_dir, '..', '..'))
283 615
284 # Make an extra copy of the sanitizer headers, to be put on the include path 616 if sys.platform == 'win32':
285 # of the fallback compiler. 617 # Make an extra copy of the sanitizer headers, to be put on the include path
286 sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', VERSION, 618 # of the fallback compiler.
287 'include', 'sanitizer') 619 sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
288 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 620 VERSION, 'include', 'sanitizer')
289 VERSION, 'include_sanitizer', 621 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
290 'sanitizer') 622 VERSION, 'include_sanitizer',
291 if not os.path.exists(aux_sanitizer_include_dir): 623 'sanitizer')
292 os.makedirs(aux_sanitizer_include_dir) 624 if not os.path.exists(aux_sanitizer_include_dir):
293 for _, _, files in os.walk(sanitizer_include_dir): 625 os.makedirs(aux_sanitizer_include_dir)
294 for f in files: 626 for _, _, files in os.walk(sanitizer_include_dir):
295 CopyFile(os.path.join(sanitizer_include_dir, f), 627 for f in files:
296 aux_sanitizer_include_dir) 628 CopyFile(os.path.join(sanitizer_include_dir, f),
629 aux_sanitizer_include_dir)
297 630
631 # Run tests.
632 if args.run_tests or use_head_revision:
633 os.chdir(LLVM_BUILD_DIR)
634 RunCommand(GetVSVersion().SetupScript('x64') +
635 ['&&', 'ninja', 'cr-check-all'])
298 if args.run_tests: 636 if args.run_tests:
299 os.chdir(LLVM_BUILD_DIR) 637 os.chdir(LLVM_BUILD_DIR)
300 RunCommand(GetVSVersion().SetupScript('x64') + 638 RunCommand(GetVSVersion().SetupScript('x64') +
301 ['&&', 'ninja', 'cr-check-all']) 639 ['&&', 'ninja', 'check-all'])
302 640
303 WriteStampFile(LLVM_WIN_REVISION) 641 WriteStampFile(PACKAGE_VERSION)
304 print 'Clang update was successful.' 642 print 'Clang update was successful.'
305 return 0 643 return 0
306 644
307 645
308 def main(): 646 def main():
309 if not sys.platform in ['win32', 'cygwin']: 647 if not sys.platform in ['win32', 'cygwin']:
310 # For non-Windows, fall back to update.sh. 648 # For non-Windows, fall back to update.sh.
311 # TODO(hans): Make update.py replace update.sh completely. 649 # TODO(hans): Make update.py replace update.sh completely.
312 650
313 # This script is called by gclient. gclient opens its hooks subprocesses 651 # This script is called by gclient. gclient opens its hooks subprocesses
314 # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does 652 # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does
315 # custom output processing that breaks printing '\r' characters for 653 # custom output processing that breaks printing '\r' characters for
316 # single-line updating status messages as printed by curl and wget. 654 # 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 (!): 655 # 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 656 # gclient doesn't redirect stdin, and while stdin itself is read-only, a
319 # dup()ed sys.stdin is writable, try 657 # dup()ed sys.stdin is writable, try
320 # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi') 658 # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi')
321 # TODO: Fix gclient instead, http://crbug.com/95350 659 # TODO: Fix gclient instead, http://crbug.com/95350
322 try: 660 if '--no-stdin-hack' in sys.argv:
323 stderr = os.fdopen(os.dup(sys.stdin.fileno())) 661 sys.argv.remove('--no-stdin-hack')
324 except: 662 stderr = None
325 stderr = sys.stderr 663 else:
664 try:
665 stderr = os.fdopen(os.dup(sys.stdin.fileno()))
666 except:
667 stderr = sys.stderr
326 return subprocess.call( 668 return subprocess.call(
327 [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:], 669 [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:],
328 stderr=stderr) 670 stderr=stderr)
329 671
330 parser = argparse.ArgumentParser(description='Build Clang.') 672 parser = argparse.ArgumentParser(description='Build Clang.')
673 parser.add_argument('--bootstrap', action='store_true',
674 help='first build clang with CC, then with itself.')
675 parser.add_argument('--if-needed', action='store_true',
676 help="run only if the script thinks clang is needed")
677 parser.add_argument('--force-local-build', action='store_true',
678 help="don't try to download prebuild binaries")
679 parser.add_argument('--gcc-toolchain', help='set the version for which gcc '
680 'version be used for building; --gcc-toolchain=/opt/foo '
681 'picks /opt/foo/bin/gcc')
682 parser.add_argument('--print-revision', action='store_true',
683 help='print current clang revision and exit.')
684 parser.add_argument('--print-clang-version', action='store_true',
685 help='print current clang version (e.g. x.y.z) and exit.')
686 parser.add_argument('--run-tests', action='store_true',
687 help='run tests after building; only for local builds')
331 parser.add_argument('--tools', nargs='*', 688 parser.add_argument('--tools', nargs='*',
689 help='select which chrome tools to build',
332 default=['plugins', 'blink_gc_plugin']) 690 default=['plugins', 'blink_gc_plugin'])
333 # For now, this flag is only used for the non-Windows flow, but argparser gets 691 parser.add_argument('--without-patches', action='store_false',
334 # mad if it sees a flag it doesn't recognize. 692 help="don't apply patches (default)", dest='with_patches',
335 parser.add_argument('--if-needed', action='store_true') 693 default=True)
336 parser.add_argument('--print-revision', action='store_true') 694
337 parser.add_argument('--run-tests', action='store_true') 695 # For now, these flags are only used for the non-Windows flow, but argparser
696 # gets mad if it sees a flag it doesn't recognize.
697 parser.add_argument('--no-stdin-hack', action='store_true')
338 698
339 args = parser.parse_args() 699 args = parser.parse_args()
340 700
701 if args.if_needed:
702 is_clang_required = False
703 # clang is always used on Mac and Linux.
704 if sys.platform == 'darwin' or sys.platform.startswith('linux'):
705 is_clang_required = True
706 # clang requested via $GYP_DEFINES.
707 if re.search(r'\b(clang|asan|lsan|msan|tsan)=1',
708 os.environ.get('GYP_DEFINES', '')):
709 is_clang_required = True
710 # clang previously downloaded, keep it up-to-date.
711 # If you don't want this, delete third_party/llvm-build on your machine.
712 if os.path.isdir(LLVM_BUILD_DIR):
713 is_clang_required = True
714 if not is_clang_required:
715 return 0
716 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')):
717 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
718 return 0
719
720 global LLVM_WIN_REVISION, PACKAGE_VERSION
341 if args.print_revision: 721 if args.print_revision:
342 PrintRevision() 722 if use_head_revision:
723 print GetSvnRevision(LLVM_DIR)
724 else:
725 print PACKAGE_VERSION
343 return 0 726 return 0
344 727
345 if not re.search(r'\b(clang|asan)=1', os.environ.get('GYP_DEFINES', '')): 728 if args.print_clang_version:
346 print 'Skipping Clang update (clang=1 was not set in GYP_DEFINES).' 729 sys.stdout.write(VERSION)
347 return 0 730 return 0
348 731
349 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): 732 # Don't buffer stdout, so that print statements are immediately flushed.
350 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' 733 # Do this only after --print-revision has been handled, else we'll get
351 return 0 734 # an error message when this script is run from gn for some reason.
735 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
736
737 if use_head_revision:
738 # Use a real revision number rather than HEAD to make sure that the stamp
739 # file logic works.
740 LLVM_WIN_REVISION = GetSvnRevision(LLVM_REPO_URL)
741 PACKAGE_VERSION = LLVM_WIN_REVISION + '-0'
742
743 args.force_local_build = True
744 # Skip local patches when using HEAD: they probably don't apply anymore.
745 args.with_patches = False
352 746
353 return UpdateClang(args) 747 return UpdateClang(args)
354 748
355 749
356 if __name__ == '__main__': 750 if __name__ == '__main__':
357 sys.exit(main()) 751 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