OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """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 os | 10 import os |
10 import re | 11 import re |
11 import shutil | 12 import shutil |
12 import subprocess | 13 import subprocess |
13 import stat | 14 import stat |
14 import sys | 15 import sys |
15 import time | 16 import time |
16 | 17 |
17 # 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 |
18 # https://code.google.com/p/chromium/wiki/UpdatingClang | 19 # https://code.google.com/p/chromium/wiki/UpdatingClang |
19 # Reverting problematic clang rolls is safe, though. | 20 # Reverting problematic clang rolls is safe, though. |
20 # 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. |
21 LLVM_WIN_REVISION = 'HEAD' | 22 LLVM_WIN_REVISION = 'HEAD' |
22 | 23 |
23 # 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 |
24 # 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. |
25 if (re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')) and | 26 if (re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')) and |
26 not 'LLVM_FORCE_HEAD_REVISION' in os.environ): | 27 not 'LLVM_FORCE_HEAD_REVISION' in os.environ): |
27 LLVM_WIN_REVISION = '233530' | 28 LLVM_WIN_REVISION = '233530' |
28 | 29 |
29 # Path constants. (All of these should be absolute paths.) | 30 # Path constants. (All of these should be absolute paths.) |
30 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) | 31 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) |
31 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) | 32 CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) |
32 LLVM_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm') | 33 LLVM_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm') |
34 CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools') | |
33 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build', | 35 LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build', |
34 'Release+Asserts') | 36 'Release+Asserts') |
35 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') | 37 COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') |
36 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang') | 38 CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang') |
37 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld') | 39 LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld') |
38 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt') | 40 COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt') |
39 STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision') | 41 STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision') |
40 VERSION = '3.7.0' | 42 VERSION = '3.7.0' |
41 | 43 |
42 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' | 44 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 return | 124 return |
123 | 125 |
124 if os.path.isdir(dir): | 126 if os.path.isdir(dir): |
125 print "Removing %s." % (dir) | 127 print "Removing %s." % (dir) |
126 RmTree(dir) | 128 RmTree(dir) |
127 | 129 |
128 print "Retrying." | 130 print "Retrying." |
129 RunCommand(command) | 131 RunCommand(command) |
130 | 132 |
131 | 133 |
134 def DeleteChromeToolsShim(): | |
135 shutil.rmtree(CHROME_TOOLS_SHIM_DIR) | |
136 | |
137 | |
138 def CreateChromeToolsShim(): | |
139 """Hooks the Chrome tools into the LLVM build. | |
140 | |
141 Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build | |
142 detects implicit tools in the tools subdirectory, so this helper install a | |
143 shim CMakeLists.txt that forwards to the real directory for the Chrome tools. | |
144 | |
145 Note that the shim directory name intentionally has no _ or _. The implicit | |
Nico
2015/04/07 04:18:55
_ or _?
dcheng
2015/04/07 07:22:53
Hmm. I copy pasted this from update.sh... and sure
| |
146 tool detection logic munges them in a weird way.""" | |
Nico
2015/04/07 04:18:55
assert not '_'in CHROME_TOOLS_SHIM_DIR
?
dcheng
2015/04/07 07:22:53
Done.
| |
147 os.mkdir(CHROME_TOOLS_SHIM_DIR) | |
148 with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f: | |
Nico
2015/04/07 04:18:55
f.write('# Automatically generated by tools/clang/
dcheng
2015/04/07 07:22:53
Done.
| |
149 f.write("# Since tools/clang isn't actually a subdirectory, use the two\n") | |
Nico
2015/04/07 04:18:55
nit: single quotes
dcheng
2015/04/07 07:22:53
Rephrased the text to avoid single quotes so I swi
| |
150 f.write("# argument version to specify where build artifacts go. CMake\n") | |
151 f.write("# disallows reuse of the same binary dir for multiple source\n") | |
152 f.write("# dirs, so the build artifacts need to go into a subdirectory.\n") | |
153 f.write("add_subdirectory(${CHROMIUM_TOOLS_SRC} ") | |
154 f.write("${CMAKE_CURRENT_BINARY_DIR}/a)\n") | |
155 | |
156 | |
132 def AddCMakeToPath(): | 157 def AddCMakeToPath(): |
133 """Look for CMake and add it to PATH if it's not there already.""" | 158 """Look for CMake and add it to PATH if it's not there already.""" |
134 try: | 159 try: |
135 # First check if cmake is already on PATH. | 160 # First check if cmake is already on PATH. |
136 subprocess.call(['cmake', '--version']) | 161 subprocess.call(['cmake', '--version']) |
137 return | 162 return |
138 except OSError as e: | 163 except OSError as e: |
139 if e.errno != os.errno.ENOENT: | 164 if e.errno != os.errno.ENOENT: |
140 raise | 165 raise |
141 | 166 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 # svn.bat in depot_tools will be ignored. | 199 # svn.bat in depot_tools will be ignored. |
175 default_pathext = ('.com', '.exe', '.bat', '.cmd') | 200 default_pathext = ('.com', '.exe', '.bat', '.cmd') |
176 for path in os.environ.get('PATH', '').split(os.pathsep): | 201 for path in os.environ.get('PATH', '').split(os.pathsep): |
177 for ext in default_pathext: | 202 for ext in default_pathext: |
178 candidate = os.path.join(path, 'svn' + ext) | 203 candidate = os.path.join(path, 'svn' + ext) |
179 if os.path.isfile(candidate): | 204 if os.path.isfile(candidate): |
180 return '-DSubversion_SVN_EXECUTABLE=%s' % candidate | 205 return '-DSubversion_SVN_EXECUTABLE=%s' % candidate |
181 return '' | 206 return '' |
182 | 207 |
183 | 208 |
184 def UpdateClang(): | 209 def UpdateClang(args): |
185 print 'Updating Clang to %s...' % (LLVM_WIN_REVISION) | 210 print 'Updating Clang to %s...' % (LLVM_WIN_REVISION) |
186 if LLVM_WIN_REVISION != 'HEAD' and ReadStampFile() == LLVM_WIN_REVISION: | 211 if LLVM_WIN_REVISION != 'HEAD' and ReadStampFile() == LLVM_WIN_REVISION: |
187 print 'Already up to date.' | 212 print 'Already up to date.' |
188 return 0 | 213 return 0 |
189 | 214 |
190 AddCMakeToPath() | 215 AddCMakeToPath() |
191 ClobberChromiumBuildFiles() | 216 if args.clobber: |
217 ClobberChromiumBuildFiles() | |
192 | 218 |
193 # Reset the stamp file in case the build is unsuccessful. | 219 # Reset the stamp file in case the build is unsuccessful. |
194 WriteStampFile('') | 220 WriteStampFile('') |
195 | 221 |
222 DeleteChromeToolsShim(); | |
196 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) | 223 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) |
197 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) | 224 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) |
198 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) | 225 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) |
199 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) | 226 Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) |
227 CreateChromeToolsShim(); | |
200 | 228 |
201 if not os.path.exists(LLVM_BUILD_DIR): | 229 if not os.path.exists(LLVM_BUILD_DIR): |
202 os.makedirs(LLVM_BUILD_DIR) | 230 os.makedirs(LLVM_BUILD_DIR) |
203 os.chdir(LLVM_BUILD_DIR) | 231 os.chdir(LLVM_BUILD_DIR) |
204 | 232 |
233 cmake_args = ['-GNinja', '-DCMAKE_BUILD_TYPE=Release', | |
234 '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(), | |
235 '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join( | |
236 CHROMIUM_DIR, 'tools', 'clang')] | |
237 if args.tools: | |
238 cmake_args.append('-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)) | |
239 | |
205 RunCommand(GetVSVersion().SetupScript('x64') + | 240 RunCommand(GetVSVersion().SetupScript('x64') + |
206 ['&&', 'cmake', '-GNinja', '-DCMAKE_BUILD_TYPE=Release', | 241 ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) |
207 '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(), LLVM_DIR]) | |
208 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all']) | 242 RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all']) |
209 | 243 |
210 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time. | 244 # Do an x86 build of compiler-rt to get the 32-bit ASan run-time. |
211 # TODO(hans): Remove once the regular build above produces this. | 245 # TODO(hans): Remove once the regular build above produces this. |
212 if not os.path.exists(COMPILER_RT_BUILD_DIR): | 246 if not os.path.exists(COMPILER_RT_BUILD_DIR): |
213 os.makedirs(COMPILER_RT_BUILD_DIR) | 247 os.makedirs(COMPILER_RT_BUILD_DIR) |
214 os.chdir(COMPILER_RT_BUILD_DIR) | 248 os.chdir(COMPILER_RT_BUILD_DIR) |
215 RunCommand(GetVSVersion().SetupScript('x86') + | 249 RunCommand(GetVSVersion().SetupScript('x86') + |
216 ['&&', 'cmake', '-GNinja', '-DCMAKE_BUILD_TYPE=Release', | 250 ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) |
217 '-DLLVM_ENABLE_ASSERTIONS=ON', LLVM_DIR]) | |
218 RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt']) | 251 RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt']) |
219 | 252 |
220 # TODO(hans): Make this (and the .gypi and .isolate files) version number | 253 # TODO(hans): Make this (and the .gypi and .isolate files) version number |
221 # independent. | 254 # independent. |
222 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang', | 255 asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang', |
223 VERSION, 'lib', 'windows') | 256 VERSION, 'lib', 'windows') |
224 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', | 257 asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', |
225 VERSION, 'lib', 'windows') | 258 VERSION, 'lib', 'windows') |
226 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir, | 259 CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir, |
227 r'^.*-i386\.lib$') | 260 r'^.*-i386\.lib$') |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 stderr=os.fdopen(os.dup(sys.stdin.fileno()))) | 302 stderr=os.fdopen(os.dup(sys.stdin.fileno()))) |
270 | 303 |
271 if not re.search(r'\b(clang|asan)=1', os.environ.get('GYP_DEFINES', '')): | 304 if not re.search(r'\b(clang|asan)=1', os.environ.get('GYP_DEFINES', '')): |
272 print 'Skipping Clang update (clang=1 was not set in GYP_DEFINES).' | 305 print 'Skipping Clang update (clang=1 was not set in GYP_DEFINES).' |
273 return 0 | 306 return 0 |
274 | 307 |
275 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): | 308 if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')): |
276 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' | 309 print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).' |
277 return 0 | 310 return 0 |
278 | 311 |
279 return UpdateClang() | 312 parser = argparse.ArgumentParser(description='Build Clang.') |
313 parser.add_argument('--no-clobber', dest='clobber', action='store_false') | |
dcheng
2015/04/06 23:09:10
I added this argument, because it makes tool testi
| |
314 parser.add_argument('--tools', nargs='*') | |
315 return UpdateClang(parser.parse_args()) | |
280 | 316 |
281 | 317 |
282 if __name__ == '__main__': | 318 if __name__ == '__main__': |
283 sys.exit(main()) | 319 sys.exit(main()) |
OLD | NEW |