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

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

Issue 1141793003: Update from https://crrev.com/329939 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 7 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/posix-print-revision.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 os 10 import os
11 import re 11 import re
12 import shutil 12 import shutil
13 import subprocess 13 import subprocess
14 import stat 14 import stat
15 import sys 15 import sys
16 import time 16 import time
17 17
18 # Do NOT CHANGE this if you don't know what you're doing -- see 18 # Do NOT CHANGE this if you don't know what you're doing -- see
19 # https://code.google.com/p/chromium/wiki/UpdatingClang 19 # https://code.google.com/p/chromium/wiki/UpdatingClang
20 # Reverting problematic clang rolls is safe, though. 20 # Reverting problematic clang rolls is safe, though.
21 # Note: this revision is only used for Windows. Other platforms use update.sh. 21 # Note: this revision is only used for Windows. Other platforms use update.sh.
22 LLVM_WIN_REVISION = 'HEAD' 22 LLVM_WIN_REVISION = 'HEAD'
23 23
24 # ASan on Windows is useful enough to use it even while the clang/win is still 24 # ASan on Windows is useful enough to use it even while the clang/win is still
25 # in bringup. Use a pinned revision to make it slightly more stable. 25 # in bringup. Use a pinned revision to make it slightly more stable.
26 if (re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')) and 26 use_head_revision = ('LLVM_FORCE_HEAD_REVISION' in os.environ or
27 not 'LLVM_FORCE_HEAD_REVISION' in os.environ): 27 not re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')))
28
29 if not use_head_revision:
28 LLVM_WIN_REVISION = '235968' 30 LLVM_WIN_REVISION = '235968'
29 31
30 # Path constants. (All of these should be absolute paths.) 32 # Path constants. (All of these should be absolute paths.)
31 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) 33 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
32 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) 34 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
33 LLVM_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm') 35 LLVM_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm')
34 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools') 36 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
35 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build', 37 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
36 'Release+Asserts') 38 'Release+Asserts')
37 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') 39 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt')
(...skipping 18 matching lines...) Expand all
56 58
57 59
58 def WriteStampFile(s): 60 def WriteStampFile(s):
59 """Write s to the stamp file.""" 61 """Write s to the stamp file."""
60 if not os.path.exists(LLVM_BUILD_DIR): 62 if not os.path.exists(LLVM_BUILD_DIR):
61 os.makedirs(LLVM_BUILD_DIR) 63 os.makedirs(LLVM_BUILD_DIR)
62 with open(STAMP_FILE, 'w') as f: 64 with open(STAMP_FILE, 'w') as f:
63 f.write(s) 65 f.write(s)
64 66
65 67
68 def PrintRevision():
69 """Print the current Clang revision."""
70 # gyp runs update.py --print-revision even when clang isn't used.
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)
79 assert m
80 print m.group(1)
81
82
66 def RmTree(dir): 83 def RmTree(dir):
67 """Delete dir.""" 84 """Delete dir."""
68 def ChmodAndRetry(func, path, _): 85 def ChmodAndRetry(func, path, _):
69 # Subversion can leave read-only files around. 86 # Subversion can leave read-only files around.
70 if not os.access(path, os.W_OK): 87 if not os.access(path, os.W_OK):
71 os.chmod(path, stat.S_IWUSR) 88 os.chmod(path, stat.S_IWUSR)
72 return func(path) 89 return func(path)
73 raise 90 raise
74 91
75 shutil.rmtree(dir, onerror=ChmodAndRetry) 92 shutil.rmtree(dir, onerror=ChmodAndRetry)
76 93
77 94
78 def ClobberChromiumBuildFiles():
79 """Clobber Chomium build files."""
80 print 'Clobbering Chromium build files...'
81 out_dir = os.path.join(CHROMIUM_DIR, 'out')
82 if os.path.isdir(out_dir):
83 RmTree(out_dir)
84 print 'Removed Chromium out dir: %s.' % (out_dir)
85
86
87 def RunCommand(command, fail_hard=True): 95 def RunCommand(command, fail_hard=True):
88 """Run command and return success (True) or failure; or if fail_hard is 96 """Run command and return success (True) or failure; or if fail_hard is
89 True, exit on failure.""" 97 True, exit on failure."""
90 98
91 print 'Running %s' % (str(command)) 99 print 'Running %s' % (str(command))
92 if subprocess.call(command, shell=True) == 0: 100 if subprocess.call(command, shell=True) == 0:
93 return True 101 return True
94 print 'Failed.' 102 print 'Failed.'
95 if fail_hard: 103 if fail_hard:
96 sys.exit(1) 104 sys.exit(1)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 def AddCMakeToPath(): 168 def AddCMakeToPath():
161 """Look for CMake and add it to PATH if it's not there already.""" 169 """Look for CMake and add it to PATH if it's not there already."""
162 try: 170 try:
163 # First check if cmake is already on PATH. 171 # First check if cmake is already on PATH.
164 subprocess.call(['cmake', '--version']) 172 subprocess.call(['cmake', '--version'])
165 return 173 return
166 except OSError as e: 174 except OSError as e:
167 if e.errno != os.errno.ENOENT: 175 if e.errno != os.errno.ENOENT:
168 raise 176 raise
169 177
170 cmake_locations = ['C:\\Program Files (x86)\\CMake\\bin', 178 cmake_dir = 'C:\\Program Files (x86)\\CMake\\bin'
171 'C:\\Program Files (x86)\\CMake 2.8\\bin'] 179 if os.path.isdir(cmake_dir):
172 for d in cmake_locations: 180 os.environ['PATH'] = os.environ.get('PATH', '') + os.pathsep + cmake_dir
173 if os.path.isdir(d): 181 return
174 os.environ['PATH'] = os.environ.get('PATH', '') + os.pathsep + d
175 return
176 print 'Failed to find CMake!' 182 print 'Failed to find CMake!'
177 sys.exit(1) 183 sys.exit(1)
178 184
179 185
180 vs_version = None 186 vs_version = None
181 def GetVSVersion(): 187 def GetVSVersion():
182 global vs_version 188 global vs_version
183 if vs_version: 189 if vs_version:
184 return vs_version 190 return vs_version
185 191
(...skipping 23 matching lines...) Expand all
209 return '' 215 return ''
210 216
211 217
212 def UpdateClang(args): 218 def UpdateClang(args):
213 print 'Updating Clang to %s...' % (LLVM_WIN_REVISION) 219 print 'Updating Clang to %s...' % (LLVM_WIN_REVISION)
214 if LLVM_WIN_REVISION != 'HEAD' and ReadStampFile() == LLVM_WIN_REVISION: 220 if LLVM_WIN_REVISION != 'HEAD' and ReadStampFile() == LLVM_WIN_REVISION:
215 print 'Already up to date.' 221 print 'Already up to date.'
216 return 0 222 return 0
217 223
218 AddCMakeToPath() 224 AddCMakeToPath()
219 if args.clobber:
220 ClobberChromiumBuildFiles()
221
222 # Reset the stamp file in case the build is unsuccessful. 225 # Reset the stamp file in case the build is unsuccessful.
223 WriteStampFile('') 226 WriteStampFile('')
224 227
225 DeleteChromeToolsShim(); 228 DeleteChromeToolsShim();
226 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) 229 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
227 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) 230 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
228 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) 231 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
229 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) 232 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
230 CreateChromeToolsShim(); 233 CreateChromeToolsShim();
231 234
232 if not os.path.exists(LLVM_BUILD_DIR): 235 if not os.path.exists(LLVM_BUILD_DIR):
233 os.makedirs(LLVM_BUILD_DIR) 236 os.makedirs(LLVM_BUILD_DIR)
234 os.chdir(LLVM_BUILD_DIR) 237 os.chdir(LLVM_BUILD_DIR)
235 238
239 # If building at head, define a macro that plugins can use for #ifdefing
240 # out code that builds at head, but not at CLANG_REVISION or vice versa.
241 cflags = cxxflags = ''
242
243 # TODO(thakis): Set this only conditionally if use_head_revision once posix
244 # and win clang are in sync. At the moment, the plugins only build at clang
245 # head on posix, but they build at both head and the pinned win version :-/
246 cflags += ' -DLLVM_FORCE_HEAD_REVISION'
247 cxxflags += ' -DLLVM_FORCE_HEAD_REVISION'
248
236 cmake_args = ['-GNinja', '-DCMAKE_BUILD_TYPE=Release', 249 cmake_args = ['-GNinja', '-DCMAKE_BUILD_TYPE=Release',
237 '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(), 250 '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(),
251 '-DCMAKE_C_FLAGS=' + cflags,
252 '-DCMAKE_CXX_FLAGS=' + cxxflags,
238 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join( 253 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(
239 CHROMIUM_DIR, 'tools', 'clang'), 254 CHROMIUM_DIR, 'tools', 'clang'),
240 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)] 255 '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
241 256
242 RunCommand(GetVSVersion().SetupScript('x64') + 257 RunCommand(GetVSVersion().SetupScript('x64') +
243 ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) 258 ['&&', 'cmake'] + cmake_args + [LLVM_DIR])
244 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all']) 259 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all'])
245 260
246 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time. 261 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time.
247 # TODO(hans): Remove once the regular build above produces this. 262 # TODO(hans): Remove once the regular build above produces this.
(...skipping 25 matching lines...) Expand all
273 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', 288 aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
274 VERSION, 'include_sanitizer', 289 VERSION, 'include_sanitizer',
275 'sanitizer') 290 'sanitizer')
276 if not os.path.exists(aux_sanitizer_include_dir): 291 if not os.path.exists(aux_sanitizer_include_dir):
277 os.makedirs(aux_sanitizer_include_dir) 292 os.makedirs(aux_sanitizer_include_dir)
278 for _, _, files in os.walk(sanitizer_include_dir): 293 for _, _, files in os.walk(sanitizer_include_dir):
279 for f in files: 294 for f in files:
280 CopyFile(os.path.join(sanitizer_include_dir, f), 295 CopyFile(os.path.join(sanitizer_include_dir, f),
281 aux_sanitizer_include_dir) 296 aux_sanitizer_include_dir)
282 297
298 if args.run_tests:
299 os.chdir(LLVM_BUILD_DIR)
300 RunCommand(GetVSVersion().SetupScript('x64') +
301 ['&&', 'ninja', 'cr-check-all'])
302
283 WriteStampFile(LLVM_WIN_REVISION) 303 WriteStampFile(LLVM_WIN_REVISION)
284 print 'Clang update was successful.' 304 print 'Clang update was successful.'
285 return 0 305 return 0
286 306
287 307
288 def main(): 308 def main():
289 if not sys.platform in ['win32', 'cygwin']: 309 if not sys.platform in ['win32', 'cygwin']:
290 # For non-Windows, fall back to update.sh. 310 # For non-Windows, fall back to update.sh.
291 # TODO(hans): Make update.py replace update.sh completely. 311 # TODO(hans): Make update.py replace update.sh completely.
292 312
293 # This script is called by gclient. gclient opens its hooks subprocesses 313 # This script is called by gclient. gclient opens its hooks subprocesses
294 # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does 314 # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does
295 # custom output processing that breaks printing '\r' characters for 315 # custom output processing that breaks printing '\r' characters for
296 # single-line updating status messages as printed by curl and wget. 316 # single-line updating status messages as printed by curl and wget.
297 # Work around this by setting stderr of the update.sh process to stdin (!): 317 # Work around this by setting stderr of the update.sh process to stdin (!):
298 # gclient doesn't redirect stdin, and while stdin itself is read-only, a 318 # gclient doesn't redirect stdin, and while stdin itself is read-only, a
299 # dup()ed sys.stdin is writable, try 319 # dup()ed sys.stdin is writable, try
300 # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi') 320 # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi')
301 # TODO: Fix gclient instead, http://crbug.com/95350 321 # TODO: Fix gclient instead, http://crbug.com/95350
322 try:
323 stderr = os.fdopen(os.dup(sys.stdin.fileno()))
324 except:
325 stderr = sys.stderr
302 return subprocess.call( 326 return subprocess.call(
303 [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:], 327 [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:],
304 stderr=os.fdopen(os.dup(sys.stdin.fileno()))) 328 stderr=stderr)
329
330 parser = argparse.ArgumentParser(description='Build Clang.')
331 parser.add_argument('--tools', nargs='*',
332 default=['plugins', 'blink_gc_plugin'])
333 # For now, this flag is only used for the non-Windows flow, but argparser gets
334 # mad if it sees a flag it doesn't recognize.
335 parser.add_argument('--if-needed', action='store_true')
336 parser.add_argument('--print-revision', action='store_true')
337 parser.add_argument('--run-tests', action='store_true')
338
339 args = parser.parse_args()
340
341 if args.print_revision:
342 PrintRevision()
343 return 0
305 344
306 if not re.search(r'\b(clang|asan)=1', os.environ.get('GYP_DEFINES', '')): 345 if not re.search(r'\b(clang|asan)=1', os.environ.get('GYP_DEFINES', '')):
307 print 'Skipping Clang update (clang=1 was not set in GYP_DEFINES).' 346 print 'Skipping Clang update (clang=1 was not set in GYP_DEFINES).'
308 return 0 347 return 0
309 348
310 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): 349 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')):
311 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' 350 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
312 return 0 351 return 0
313 352
314 parser = argparse.ArgumentParser(description='Build Clang.') 353 return UpdateClang(args)
315 parser.add_argument('--no-clobber', dest='clobber', action='store_false')
316 parser.add_argument('--tools', nargs='*', default=['plugins'])
317 # For now, this flag is only used for the non-Windows flow, but argparser gets
318 # mad if it sees a flag it doesn't recognize.
319 parser.add_argument('--if-needed', action='store_true')
320 return UpdateClang(parser.parse_args())
321 354
322 355
323 if __name__ == '__main__': 356 if __name__ == '__main__':
324 sys.exit(main()) 357 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/clang/scripts/posix-print-revision.py ('k') | tools/clang/scripts/update.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698