| #!/usr/bin/env python |
| # Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """This script will check out llvm and clang, and then package the results up |
| to a tgz file.""" |
| |
| import argparse |
| import fnmatch |
| import itertools |
| import os |
| import shutil |
| import subprocess |
| import sys |
| import tarfile |
| |
| # Path constants. |
| THIS_DIR = os.path.dirname(__file__) |
| CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) |
| THIRD_PARTY_DIR = os.path.join(THIS_DIR, '..', '..', '..', 'third_party') |
| BUILDTOOLS_DIR = os.path.join(THIS_DIR, '..', '..', '..', 'buildtools') |
| LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm') |
| LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap') |
| LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR, |
| 'llvm-bootstrap-install') |
| LLVM_BUILD_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-build') |
| LLVM_RELEASE_DIR = os.path.join(LLVM_BUILD_DIR, 'Release+Asserts') |
| EU_STRIP = os.path.join(BUILDTOOLS_DIR, 'third_party', 'eu-strip', 'bin', |
| 'eu-strip') |
| STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision') |
| |
| |
| def Tee(output, logfile): |
| logfile.write(output) |
| print output, |
| |
| |
| def TeeCmd(cmd, logfile, fail_hard=True): |
| """Runs cmd and writes the output to both stdout and logfile.""" |
| # Reading from PIPE can deadlock if one buffer is full but we wait on a |
| # different one. To work around this, pipe the subprocess's stderr to |
| # its stdout buffer and don't give it a stdin. |
| # shell=True is required in cmd.exe since depot_tools has an svn.bat, and |
| # bat files only work with shell=True set. |
| proc = subprocess.Popen(cmd, bufsize=1, shell=sys.platform == 'win32', |
| stdin=open(os.devnull), stdout=subprocess.PIPE, |
| stderr=subprocess.STDOUT) |
| for line in iter(proc.stdout.readline,''): |
| Tee(line, logfile) |
| if proc.poll() is not None: |
| break |
| exit_code = proc.wait() |
| if exit_code != 0 and fail_hard: |
| print 'Failed:', cmd |
| sys.exit(1) |
| |
| |
| def PrintTarProgress(tarinfo): |
| print 'Adding', tarinfo.name |
| return tarinfo |
| |
| |
| def GetExpectedStamp(): |
| rev_cmd = [sys.executable, os.path.join(THIS_DIR, 'update.py'), |
| '--print-revision'] |
| return subprocess.check_output(rev_cmd).rstrip() |
| |
| |
| def GetGsutilPath(): |
| if not 'find_depot_tools' in sys.modules: |
| sys.path.insert(0, os.path.join(CHROMIUM_DIR, 'build')) |
| global find_depot_tools |
| import find_depot_tools |
| depot_path = find_depot_tools.add_depot_tools_to_path() |
| if depot_path is None: |
| print ('depot_tools are not found in PATH. ' |
| 'Follow the instructions in this document ' |
| 'http://dev.chromium.org/developers/how-tos/install-depot-tools' |
| ' to install depot_tools and then try again.') |
| sys.exit(1) |
| gsutil_path = os.path.join(depot_path, 'gsutil.py') |
| return gsutil_path |
| |
| |
| def RunGsutil(args): |
| return subprocess.call([sys.executable, GetGsutilPath()] + args) |
| |
| |
| def GsutilArchiveExists(archive_name, platform): |
| gsutil_args = ['-q', 'stat', |
| 'gs://chromium-browser-clang-staging/%s/%s.tgz' % |
| (platform, archive_name)] |
| return RunGsutil(gsutil_args) == 0 |
| |
| |
| def MaybeUpload(args, archive_name, platform): |
| gsutil_args = ['cp', '-a', 'public-read', |
| '%s.tgz' % archive_name, |
| 'gs://chromium-browser-clang-staging/%s/%s.tgz' % |
| (platform, archive_name)] |
| if args.upload: |
| print 'Uploading %s to Google Cloud Storage...' % archive_name |
| exit_code = RunGsutil(gsutil_args) |
| if exit_code != 0: |
| print "gsutil failed, exit_code: %s" % exit_code |
| sys.exit(exit_code) |
| else: |
| print 'To upload, run:' |
| print ('gsutil %s' % ' '.join(gsutil_args)) |
| |
| |
| def UploadPDBToSymbolServer(): |
| assert sys.platform == 'win32' |
| # Upload PDB and binary to the symbol server on Windows. Put them into the |
| # chromium-browser-symsrv bucket, since chrome devs have that in their |
| # _NT_SYMBOL_PATH already. Executable and PDB must be at paths following a |
| # certain pattern for the Microsoft debuggers to be able to load them. |
| # Executable: |
| # chromium-browser-symsrv/clang-cl.exe/ABCDEFAB01234/clang-cl.ex_ |
| # ABCDEFAB is the executable's timestamp in %08X format, 01234 is the |
| # executable's image size in %x format. tools/symsrc/img_fingerprint.py |
| # can compute this ABCDEFAB01234 string for us, so use that. |
| # The .ex_ instead of .exe at the end means that the file is compressed. |
| # PDB: |
| # gs://chromium-browser-symsrv/clang-cl.exe.pdb/AABBCCDD/clang-cl.dll.pd_ |
| # AABBCCDD here is computed from the output of |
| # dumpbin /all mybinary.exe | find "Format: RSDS" |
| # but tools/symsrc/pdb_fingerprint_from_img.py can compute it already, so |
| # again just use that. |
| sys.path.insert(0, os.path.join(CHROMIUM_DIR, 'tools', 'symsrc')) |
| import img_fingerprint, pdb_fingerprint_from_img |
| |
| binaries = [ 'bin/clang-cl.exe', 'bin/lld-link.exe' ] |
| for binary_path in binaries: |
| binary_path = os.path.join(LLVM_RELEASE_DIR, binary_path) |
| binary_id = img_fingerprint.GetImgFingerprint(binary_path) |
| (pdb_id, pdb_path) = pdb_fingerprint_from_img.GetPDBInfoFromImg(binary_path) |
| |
| # The build process builds clang.exe and then copies it to clang-cl.exe |
| # (both are the same binary and they behave differently on what their |
| # filename is). Hence, the pdb is at clang.pdb, not at clang-cl.pdb. |
| # Likewise, lld-link.exe's PDB file is called lld.pdb. |
| |
| # Compress and upload. |
| for f, f_id in ((binary_path, binary_id), (pdb_path, pdb_id)): |
| subprocess.check_call( |
| ['makecab', '/D', 'CompressionType=LZX', '/D', 'CompressionMemory=21', |
| f, '/L', os.path.dirname(f)], stdout=open(os.devnull, 'w')) |
| f_cab = f[:-1] + '_' |
| |
| dest = '%s/%s/%s' % (os.path.basename(f), f_id, os.path.basename(f_cab)) |
| print 'Uploading %s to Google Cloud Storage...' % dest |
| gsutil_args = ['cp', '-n', '-a', 'public-read', f_cab, |
| 'gs://chromium-browser-symsrv/' + dest] |
| exit_code = RunGsutil(gsutil_args) |
| if exit_code != 0: |
| print "gsutil failed, exit_code: %s" % exit_code |
| sys.exit(exit_code) |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser(description='build and package clang') |
| parser.add_argument('--upload', action='store_true', |
| help='Upload the target archive to Google Cloud Storage.') |
| args = parser.parse_args() |
| |
| # Check that the script is not going to upload a toolchain built from HEAD. |
| use_head_revision = bool(int(os.environ.get('LLVM_FORCE_HEAD_REVISION', '0'))) |
| if args.upload and use_head_revision: |
| print ("--upload and LLVM_FORCE_HEAD_REVISION could not be used " |
| "at the same time.") |
| return 1 |
| |
| expected_stamp = GetExpectedStamp() |
| pdir = 'clang-' + expected_stamp |
| print pdir |
| |
| if sys.platform == 'darwin': |
| platform = 'Mac' |
| elif sys.platform == 'win32': |
| platform = 'Win' |
| else: |
| platform = 'Linux_x64' |
| |
| with open('buildlog.txt', 'w') as log: |
| Tee('Diff in llvm:\n', log) |
| TeeCmd(['svn', 'stat', LLVM_DIR], log, fail_hard=False) |
| TeeCmd(['svn', 'diff', LLVM_DIR], log, fail_hard=False) |
| Tee('Diff in llvm/tools/clang:\n', log) |
| TeeCmd(['svn', 'stat', os.path.join(LLVM_DIR, 'tools', 'clang')], |
| log, fail_hard=False) |
| TeeCmd(['svn', 'diff', os.path.join(LLVM_DIR, 'tools', 'clang')], |
| log, fail_hard=False) |
| # TODO(thakis): compiler-rt is in projects/compiler-rt on Windows but |
| # llvm/compiler-rt elsewhere. So this diff call is currently only right on |
| # Windows. |
| Tee('Diff in llvm/compiler-rt:\n', log) |
| TeeCmd(['svn', 'stat', os.path.join(LLVM_DIR, 'projects', 'compiler-rt')], |
| log, fail_hard=False) |
| TeeCmd(['svn', 'diff', os.path.join(LLVM_DIR, 'projects', 'compiler-rt')], |
| log, fail_hard=False) |
| Tee('Diff in llvm/projects/libcxx:\n', log) |
| TeeCmd(['svn', 'stat', os.path.join(LLVM_DIR, 'projects', 'libcxx')], |
| log, fail_hard=False) |
| TeeCmd(['svn', 'diff', os.path.join(LLVM_DIR, 'projects', 'libcxx')], |
| log, fail_hard=False) |
| |
| Tee('Starting build\n', log) |
| |
| # Do a clobber build. |
| shutil.rmtree(LLVM_BOOTSTRAP_DIR, ignore_errors=True) |
| shutil.rmtree(LLVM_BOOTSTRAP_INSTALL_DIR, ignore_errors=True) |
| shutil.rmtree(LLVM_BUILD_DIR, ignore_errors=True) |
| |
| opt_flags = [] |
| if sys.platform.startswith('linux'): |
| opt_flags += ['--lto-lld'] |
| build_cmd = [sys.executable, os.path.join(THIS_DIR, 'update.py'), |
| '--bootstrap', '--force-local-build', |
| '--run-tests'] + opt_flags |
| TeeCmd(build_cmd, log) |
| |
| stamp = open(STAMP_FILE).read().rstrip() |
| if stamp != expected_stamp: |
| print 'Actual stamp (%s) != expected stamp (%s).' % (stamp, expected_stamp) |
| return 1 |
| |
| shutil.rmtree(pdir, ignore_errors=True) |
| |
| # Copy a whitelist of files to the directory we're going to tar up. |
| # This supports the same patterns that the fnmatch module understands. |
| exe_ext = '.exe' if sys.platform == 'win32' else '' |
| want = ['bin/llvm-pdbutil' + exe_ext, |
| 'bin/llvm-symbolizer' + exe_ext, |
| 'bin/llvm-undname' + exe_ext, |
| # Copy built-in headers (lib/clang/3.x.y/include). |
| 'lib/clang/*/include/*', |
| 'lib/clang/*/share/asan_blacklist.txt', |
| 'lib/clang/*/share/cfi_blacklist.txt', |
| ] |
| if sys.platform == 'win32': |
| want.append('bin/clang-cl.exe') |
| want.append('bin/lld-link.exe') |
| else: |
| want.append('bin/clang') |
| if sys.platform == 'darwin': |
| want.extend([ |
| # AddressSanitizer runtime. |
| 'lib/clang/*/lib/darwin/libclang_rt.asan_iossim_dynamic.dylib', |
| 'lib/clang/*/lib/darwin/libclang_rt.asan_osx_dynamic.dylib', |
| |
| # Fuzzing instrumentation (-fsanitize=fuzzer-no-link). |
| 'lib/clang/*/lib/darwin/libclang_rt.fuzzer_no_main_osx.a', |
| |
| # OS X and iOS builtin libraries (iossim is lipo'd into ios) for the |
| # _IsOSVersionAtLeast runtime function. |
| 'lib/clang/*/lib/darwin/libclang_rt.ios.a', |
| 'lib/clang/*/lib/darwin/libclang_rt.osx.a', |
| |
| # Profile runtime (used by profiler and code coverage). |
| 'lib/clang/*/lib/darwin/libclang_rt.profile_iossim.a', |
| 'lib/clang/*/lib/darwin/libclang_rt.profile_osx.a', |
| ]) |
| elif sys.platform.startswith('linux'): |
| # Add llvm-ar and lld for LTO. |
| want.append('bin/llvm-ar') |
| want.append('bin/lld') |
| want.extend([ |
| # AddressSanitizer C runtime (pure C won't link with *_cxx). |
| 'lib/clang/*/lib/linux/libclang_rt.asan-i386.a', |
| 'lib/clang/*/lib/linux/libclang_rt.asan-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.asan-x86_64.a.syms', |
| |
| # AddressSanitizer C++ runtime. |
| 'lib/clang/*/lib/linux/libclang_rt.asan_cxx-i386.a', |
| 'lib/clang/*/lib/linux/libclang_rt.asan_cxx-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.asan_cxx-x86_64.a.syms', |
| |
| # AddressSanitizer Android runtime. |
| 'lib/clang/*/lib/linux/libclang_rt.asan-aarch64-android.so', |
| 'lib/clang/*/lib/linux/libclang_rt.asan-arm-android.so', |
| 'lib/clang/*/lib/linux/libclang_rt.asan-i686-android.so', |
| |
| # Fuzzing instrumentation (-fsanitize=fuzzer-no-link). |
| 'lib/clang/*/lib/linux/libclang_rt.fuzzer_no_main-x86_64.a', |
| |
| # HWASAN Android runtime. |
| 'lib/clang/*/lib/linux/libclang_rt.hwasan-aarch64-android.so', |
| |
| # MemorySanitizer C runtime (pure C won't link with *_cxx). |
| 'lib/clang/*/lib/linux/libclang_rt.msan-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.msan-x86_64.a.syms', |
| |
| # MemorySanitizer C++ runtime. |
| 'lib/clang/*/lib/linux/libclang_rt.msan_cxx-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.msan_cxx-x86_64.a.syms', |
| |
| # Profile runtime (used by profiler and code coverage). |
| 'lib/clang/*/lib/linux/libclang_rt.profile-i386.a', |
| 'lib/clang/*/lib/linux/libclang_rt.profile-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.profile-aarch64-android.a', |
| 'lib/clang/*/lib/linux/libclang_rt.profile-arm-android.a', |
| |
| # ThreadSanitizer C runtime (pure C won't link with *_cxx). |
| 'lib/clang/*/lib/linux/libclang_rt.tsan-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.tsan-x86_64.a.syms', |
| |
| # ThreadSanitizer C++ runtime. |
| 'lib/clang/*/lib/linux/libclang_rt.tsan_cxx-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.tsan_cxx-x86_64.a.syms', |
| |
| # UndefinedBehaviorSanitizer C runtime (pure C won't link with *_cxx). |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone-i386.a', |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone-x86_64.a.syms', |
| |
| # UndefinedBehaviorSanitizer C++ runtime. |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone_cxx-i386.a', |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone_cxx-x86_64.a', |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone_cxx-x86_64.a.syms', |
| |
| # UndefinedBehaviorSanitizer Android runtime, needed for CFI. |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone-aarch64-android.so', |
| 'lib/clang/*/lib/linux/libclang_rt.ubsan_standalone-arm-android.so', |
| |
| # Blacklist for MemorySanitizer (used on Linux only). |
| 'lib/clang/*/share/msan_blacklist.txt', |
| ]) |
| elif sys.platform == 'win32': |
| want.extend([ |
| # AddressSanitizer C runtime (pure C won't link with *_cxx). |
| 'lib/clang/*/lib/windows/clang_rt.asan-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.asan-x86_64.lib', |
| |
| # AddressSanitizer C++ runtime. |
| 'lib/clang/*/lib/windows/clang_rt.asan_cxx-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.asan_cxx-x86_64.lib', |
| |
| # Fuzzing instrumentation (-fsanitize=fuzzer-no-link). |
| 'lib/clang/*/lib/windows/clang_rt.fuzzer_no_main-x86_64.lib', |
| |
| # Thunk for AddressSanitizer needed for static build of a shared lib. |
| 'lib/clang/*/lib/windows/clang_rt.asan_dll_thunk-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.asan_dll_thunk-x86_64.lib', |
| |
| # AddressSanitizer runtime for component build. |
| 'lib/clang/*/lib/windows/clang_rt.asan_dynamic-i386.dll', |
| 'lib/clang/*/lib/windows/clang_rt.asan_dynamic-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.asan_dynamic-x86_64.dll', |
| 'lib/clang/*/lib/windows/clang_rt.asan_dynamic-x86_64.lib', |
| |
| # Thunk for AddressSanitizer for component build of a shared lib. |
| 'lib/clang/*/lib/windows/clang_rt.asan_dynamic_runtime_thunk-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.asan_dynamic_runtime_thunk-x86_64.lib', |
| |
| # Profile runtime (used by profiler and code coverage). |
| 'lib/clang/*/lib/windows/clang_rt.profile-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.profile-x86_64.lib', |
| |
| # UndefinedBehaviorSanitizer C runtime (pure C won't link with *_cxx). |
| 'lib/clang/*/lib/windows/clang_rt.ubsan_standalone-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.ubsan_standalone-x86_64.lib', |
| |
| # UndefinedBehaviorSanitizer C++ runtime. |
| 'lib/clang/*/lib/windows/clang_rt.ubsan_standalone_cxx-i386.lib', |
| 'lib/clang/*/lib/windows/clang_rt.ubsan_standalone_cxx-x86_64.lib', |
| ]) |
| |
| if sys.platform in ('linux2', 'darwin'): |
| # Include libclang_rt.builtins.a for Fuchsia targets. |
| want.extend(['lib/clang/*/aarch64-fuchsia/lib/libclang_rt.builtins.a', |
| 'lib/clang/*/x86_64-fuchsia/lib/libclang_rt.builtins.a', |
| ]) |
| |
| for root, dirs, files in os.walk(LLVM_RELEASE_DIR): |
| # root: third_party/llvm-build/Release+Asserts/lib/..., rel_root: lib/... |
| rel_root = root[len(LLVM_RELEASE_DIR)+1:] |
| rel_files = [os.path.join(rel_root, f) for f in files] |
| wanted_files = list(set(itertools.chain.from_iterable( |
| fnmatch.filter(rel_files, p) for p in want))) |
| if wanted_files: |
| # Guaranteed to not yet exist at this point: |
| os.makedirs(os.path.join(pdir, rel_root)) |
| for f in wanted_files: |
| src = os.path.join(LLVM_RELEASE_DIR, f) |
| dest = os.path.join(pdir, f) |
| shutil.copy(src, dest) |
| # Strip libraries. |
| if sys.platform == 'darwin' and f.endswith('.dylib'): |
| subprocess.call(['strip', '-x', dest]) |
| elif (sys.platform.startswith('linux') and |
| os.path.splitext(f)[1] in ['.so', '.a']): |
| subprocess.call([EU_STRIP, '-g', dest]) |
| |
| stripped_binaries = ['clang', |
| 'llvm-pdbutil', |
| 'llvm-symbolizer', |
| 'llvm-undname', |
| ] |
| if sys.platform.startswith('linux'): |
| stripped_binaries.append('lld') |
| stripped_binaries.append('llvm-ar') |
| for f in stripped_binaries: |
| if sys.platform != 'win32': |
| subprocess.call(['strip', os.path.join(pdir, 'bin', f)]) |
| |
| # Set up symlinks. |
| if sys.platform != 'win32': |
| os.symlink('clang', os.path.join(pdir, 'bin', 'clang++')) |
| os.symlink('clang', os.path.join(pdir, 'bin', 'clang-cl')) |
| |
| if sys.platform.startswith('linux'): |
| os.symlink('lld', os.path.join(pdir, 'bin', 'ld.lld')) |
| os.symlink('lld', os.path.join(pdir, 'bin', 'lld-link')) |
| |
| # Copy libc++ headers. |
| if sys.platform == 'darwin': |
| shutil.copytree(os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'include', 'c++'), |
| os.path.join(pdir, 'include', 'c++')) |
| |
| # Copy buildlog over. |
| shutil.copy('buildlog.txt', pdir) |
| |
| # Create archive. |
| tar_entries = ['bin', 'lib', 'buildlog.txt'] |
| if sys.platform == 'darwin': |
| tar_entries += ['include'] |
| with tarfile.open(pdir + '.tgz', 'w:gz') as tar: |
| for entry in tar_entries: |
| tar.add(os.path.join(pdir, entry), arcname=entry, filter=PrintTarProgress) |
| |
| MaybeUpload(args, pdir, platform) |
| |
| # Zip up llvm-code-coverage for code coverage. |
| code_coverage_dir = 'llvm-code-coverage-' + stamp |
| shutil.rmtree(code_coverage_dir, ignore_errors=True) |
| os.makedirs(os.path.join(code_coverage_dir, 'bin')) |
| for filename in ['llvm-cov', 'llvm-profdata']: |
| shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', filename + exe_ext), |
| os.path.join(code_coverage_dir, 'bin')) |
| with tarfile.open(code_coverage_dir + '.tgz', 'w:gz') as tar: |
| tar.add(os.path.join(code_coverage_dir, 'bin'), arcname='bin', |
| filter=PrintTarProgress) |
| MaybeUpload(args, code_coverage_dir, platform) |
| |
| # Zip up llvm-objdump and related tools for sanitizer coverage and Supersize. |
| objdumpdir = 'llvmobjdump-' + stamp |
| shutil.rmtree(objdumpdir, ignore_errors=True) |
| os.makedirs(os.path.join(objdumpdir, 'bin')) |
| for filename in ['llvm-bcanalyzer', 'llvm-cxxfilt', 'llvm-nm', 'llvm-objdump', |
| 'llvm-readobj']: |
| shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', filename + exe_ext), |
| os.path.join(objdumpdir, 'bin')) |
| llvmobjdump_stamp_file_base = 'llvmobjdump_build_revision' |
| llvmobjdump_stamp_file = os.path.join(objdumpdir, llvmobjdump_stamp_file_base) |
| with open(llvmobjdump_stamp_file, 'w') as f: |
| f.write(expected_stamp) |
| f.write('\n') |
| if sys.platform != 'win32': |
| os.symlink('llvm-readobj', os.path.join(objdumpdir, 'bin', 'llvm-readelf')) |
| with tarfile.open(objdumpdir + '.tgz', 'w:gz') as tar: |
| tar.add(os.path.join(objdumpdir, 'bin'), arcname='bin', |
| filter=PrintTarProgress) |
| tar.add(llvmobjdump_stamp_file, arcname=llvmobjdump_stamp_file_base, |
| filter=PrintTarProgress) |
| MaybeUpload(args, objdumpdir, platform) |
| |
| # Zip up llvm-cfi-verify for CFI coverage. |
| cfiverifydir = 'llvmcfiverify-' + stamp |
| shutil.rmtree(cfiverifydir, ignore_errors=True) |
| os.makedirs(os.path.join(cfiverifydir, 'bin')) |
| shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'llvm-cfi-verify' + |
| exe_ext), |
| os.path.join(cfiverifydir, 'bin')) |
| with tarfile.open(cfiverifydir + '.tgz', 'w:gz') as tar: |
| tar.add(os.path.join(cfiverifydir, 'bin'), arcname='bin', |
| filter=PrintTarProgress) |
| MaybeUpload(args, cfiverifydir, platform) |
| |
| # On Mac, lld isn't part of the main zip. Upload it in a separate zip. |
| if sys.platform == 'darwin': |
| llddir = 'lld-' + stamp |
| shutil.rmtree(llddir, ignore_errors=True) |
| os.makedirs(os.path.join(llddir, 'bin')) |
| shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'lld'), |
| os.path.join(llddir, 'bin')) |
| shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'llvm-ar'), |
| os.path.join(llddir, 'bin')) |
| os.symlink('lld', os.path.join(llddir, 'bin', 'lld-link')) |
| os.symlink('lld', os.path.join(llddir, 'bin', 'ld.lld')) |
| with tarfile.open(llddir + '.tgz', 'w:gz') as tar: |
| tar.add(os.path.join(llddir, 'bin'), arcname='bin', |
| filter=PrintTarProgress) |
| MaybeUpload(args, llddir, platform) |
| |
| # On Linux and Mac, package and upload llvm-strip in a separate zip. |
| # This is used for the Fuchsia build. |
| if sys.platform == 'darwin' or sys.platform.startswith('linux'): |
| stripdir = 'llvmstrip-' + stamp |
| shutil.rmtree(stripdir, ignore_errors=True) |
| os.makedirs(os.path.join(stripdir, 'bin')) |
| shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'llvm-strip'), |
| os.path.join(stripdir, 'bin')) |
| llvmstrip_stamp_file_base = 'llvmstrip_build_revision' |
| llvmstrip_stamp_file = os.path.join(stripdir, llvmstrip_stamp_file_base) |
| with open(llvmstrip_stamp_file, 'w') as f: |
| f.write(expected_stamp) |
| f.write('\n') |
| with tarfile.open(stripdir + '.tgz', 'w:gz') as tar: |
| tar.add(os.path.join(stripdir, 'bin'), arcname='bin', |
| filter=PrintTarProgress) |
| tar.add(llvmstrip_stamp_file, arcname=llvmstrip_stamp_file_base, |
| filter=PrintTarProgress) |
| MaybeUpload(args, stripdir, platform) |
| |
| # Zip up the translation_unit tool. |
| translation_unit_dir = 'translation_unit-' + stamp |
| shutil.rmtree(translation_unit_dir, ignore_errors=True) |
| os.makedirs(os.path.join(translation_unit_dir, 'bin')) |
| shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'translation_unit' + |
| exe_ext), |
| os.path.join(translation_unit_dir, 'bin')) |
| with tarfile.open(translation_unit_dir + '.tgz', 'w:gz') as tar: |
| tar.add(os.path.join(translation_unit_dir, 'bin'), arcname='bin', |
| filter=PrintTarProgress) |
| MaybeUpload(args, translation_unit_dir, platform) |
| |
| if sys.platform == 'win32' and args.upload: |
| UploadPDBToSymbolServer() |
| |
| # FIXME: Warn if the file already exists on the server. |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |