| 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 """This script is used to download prebuilt clang binaries. | 6 """This script is used to download prebuilt clang binaries. |
| 7 | 7 |
| 8 It is also used by package.py to build the prebuilt clang binaries.""" | 8 It is also used by package.py to build the prebuilt clang binaries.""" |
| 9 | 9 |
| 10 import argparse | 10 import argparse |
| 11 import distutils.spawn | 11 import distutils.spawn |
| 12 import glob | 12 import glob |
| 13 import os | 13 import os |
| 14 import pipes | 14 import pipes |
| 15 import re | 15 import re |
| 16 import shutil | 16 import shutil |
| 17 import subprocess | 17 import subprocess |
| 18 import stat | 18 import stat |
| 19 import sys | 19 import sys |
| 20 import tarfile | 20 import tarfile |
| 21 import tempfile | 21 import tempfile |
| 22 import time | 22 import time |
| 23 import urllib2 | 23 import urllib2 |
| 24 import zipfile | 24 import zipfile |
| 25 | 25 |
| 26 | 26 |
| 27 # Do NOT CHANGE this if you don't know what you're doing -- see | 27 # Do NOT CHANGE this if you don't know what you're doing -- see |
| 28 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md | 28 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md |
| 29 # Reverting problematic clang rolls is safe, though. | 29 # Reverting problematic clang rolls is safe, though. |
| 30 CLANG_REVISION = '303369' | 30 CLANG_REVISION = '303370' |
| 31 | 31 |
| 32 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ | 32 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ |
| 33 if use_head_revision: | 33 if use_head_revision: |
| 34 CLANG_REVISION = 'HEAD' | 34 CLANG_REVISION = 'HEAD' |
| 35 | 35 |
| 36 # This is incremented when pushing a new build of Clang at the same revision. | 36 # This is incremented when pushing a new build of Clang at the same revision. |
| 37 CLANG_SUB_REVISION=1 | 37 CLANG_SUB_REVISION=1 |
| 38 | 38 |
| 39 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION) | 39 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION) |
| 40 | 40 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 66 os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) | 66 os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) |
| 67 STAMP_FILE = os.path.normpath( | 67 STAMP_FILE = os.path.normpath( |
| 68 os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')) | 68 os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')) |
| 69 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils', 'Linux_x64', 'Release') | 69 BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils', 'Linux_x64', 'Release') |
| 70 BINUTILS_BIN_DIR = os.path.join(BINUTILS_DIR, 'bin') | 70 BINUTILS_BIN_DIR = os.path.join(BINUTILS_DIR, 'bin') |
| 71 BINUTILS_LIB_DIR = os.path.join(BINUTILS_DIR, 'lib') | 71 BINUTILS_LIB_DIR = os.path.join(BINUTILS_DIR, 'lib') |
| 72 BFD_PLUGINS_DIR = os.path.join(BINUTILS_LIB_DIR, 'bfd-plugins') | 72 BFD_PLUGINS_DIR = os.path.join(BINUTILS_LIB_DIR, 'bfd-plugins') |
| 73 VERSION = '5.0.0' | 73 VERSION = '5.0.0' |
| 74 ANDROID_NDK_DIR = os.path.join( | 74 ANDROID_NDK_DIR = os.path.join( |
| 75 CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk') | 75 CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk') |
| 76 FUCHSIA_SDK_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'fuchsia-sdk') |
| 76 | 77 |
| 77 # URL for pre-built binaries. | 78 # URL for pre-built binaries. |
| 78 CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE', | 79 CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE', |
| 79 'https://commondatastorage.googleapis.com/chromium-browser-clang') | 80 'https://commondatastorage.googleapis.com/chromium-browser-clang') |
| 80 | 81 |
| 81 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' | 82 LLVM_REPO_URL='https://llvm.org/svn/llvm-project' |
| 82 if 'LLVM_REPO_URL' in os.environ: | 83 if 'LLVM_REPO_URL' in os.environ: |
| 83 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] | 84 LLVM_REPO_URL = os.environ['LLVM_REPO_URL'] |
| 84 | 85 |
| 85 # Bump after VC updates. | 86 # Bump after VC updates. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 if not os.access(path, os.W_OK): | 180 if not os.access(path, os.W_OK): |
| 180 os.chmod(path, stat.S_IWUSR) | 181 os.chmod(path, stat.S_IWUSR) |
| 181 return func(path) | 182 return func(path) |
| 182 raise | 183 raise |
| 183 | 184 |
| 184 shutil.rmtree(dir, onerror=ChmodAndRetry) | 185 shutil.rmtree(dir, onerror=ChmodAndRetry) |
| 185 | 186 |
| 186 | 187 |
| 187 def RmCmakeCache(dir): | 188 def RmCmakeCache(dir): |
| 188 """Delete CMake cache related files from dir.""" | 189 """Delete CMake cache related files from dir.""" |
| 190 return |
| 189 for dirpath, dirs, files in os.walk(dir): | 191 for dirpath, dirs, files in os.walk(dir): |
| 190 if 'CMakeCache.txt' in files: | 192 if 'CMakeCache.txt' in files: |
| 191 os.remove(os.path.join(dirpath, 'CMakeCache.txt')) | 193 os.remove(os.path.join(dirpath, 'CMakeCache.txt')) |
| 192 if 'CMakeFiles' in dirs: | 194 if 'CMakeFiles' in dirs: |
| 193 RmTree(os.path.join(dirpath, 'CMakeFiles')) | 195 RmTree(os.path.join(dirpath, 'CMakeFiles')) |
| 194 | 196 |
| 195 | 197 |
| 196 def RunCommand(command, msvc_arch=None, env=None, fail_hard=True): | 198 def RunCommand(command, msvc_arch=None, env=None, fail_hard=True): |
| 197 """Run command and return success (True) or failure; or if fail_hard is | 199 """Run command and return success (True) or failure; or if fail_hard is |
| 198 True, exit on failure. If msvc_arch is set, runs the command in a | 200 True, exit on failure. If msvc_arch is set, runs the command in a |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 return 1 | 443 return 1 |
| 442 | 444 |
| 443 if args.with_android and not os.path.exists(ANDROID_NDK_DIR): | 445 if args.with_android and not os.path.exists(ANDROID_NDK_DIR): |
| 444 print 'Android NDK not found at ' + ANDROID_NDK_DIR | 446 print 'Android NDK not found at ' + ANDROID_NDK_DIR |
| 445 print 'The Android NDK is needed to build a Clang whose -fsanitize=address' | 447 print 'The Android NDK is needed to build a Clang whose -fsanitize=address' |
| 446 print 'works on Android. See ' | 448 print 'works on Android. See ' |
| 447 print 'https://www.chromium.org/developers/how-tos/android-build-instruction
s' | 449 print 'https://www.chromium.org/developers/how-tos/android-build-instruction
s' |
| 448 print 'for how to install the NDK, or pass --without-android.' | 450 print 'for how to install the NDK, or pass --without-android.' |
| 449 return 1 | 451 return 1 |
| 450 | 452 |
| 453 if args.with_fuchsia and not os.path.exists(FUCHSIA_SDK_DIR): |
| 454 print 'Fuchsia SDK not found at ' + FUCHSIA_SDK_DIR |
| 455 print 'The Fuchsia SDK is needed to build libclang_rt for Fuchsia.' |
| 456 print 'Install the Fuchsia SDK by adding fuchsia to the ' |
| 457 print 'target_os section in your .gclient and running hooks, ' |
| 458 print 'or pass --without-fuchsia.' |
| 459 # TODO(thakis): Link to "chromium/fuchsia build instructions" page once it |
| 460 # exists. |
| 461 return 1 |
| 462 |
| 451 DownloadHostGcc(args) | 463 DownloadHostGcc(args) |
| 452 AddCMakeToPath() | 464 AddCMakeToPath() |
| 453 AddGnuWinToPath() | 465 AddGnuWinToPath() |
| 454 | 466 |
| 455 DeleteChromeToolsShim() | 467 DeleteChromeToolsShim() |
| 456 | 468 |
| 457 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) | 469 Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) |
| 458 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) | 470 Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) |
| 459 if sys.platform != 'darwin': | 471 if sys.platform != 'darwin': |
| 460 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) | 472 Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 elif sys.platform.startswith('linux'): | 699 elif sys.platform.startswith('linux'): |
| 688 RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) | 700 RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')]) |
| 689 | 701 |
| 690 VeryifyVersionOfBuiltClangMatchesVERSION() | 702 VeryifyVersionOfBuiltClangMatchesVERSION() |
| 691 | 703 |
| 692 # Do an out-of-tree build of compiler-rt. | 704 # Do an out-of-tree build of compiler-rt. |
| 693 # On Windows, this is used to get the 32-bit ASan run-time. | 705 # On Windows, this is used to get the 32-bit ASan run-time. |
| 694 # TODO(hans): Remove once the regular build above produces this. | 706 # TODO(hans): Remove once the regular build above produces this. |
| 695 # On Mac and Linux, this is used to get the regular 64-bit run-time. | 707 # On Mac and Linux, this is used to get the regular 64-bit run-time. |
| 696 # Do a clobbered build due to cmake changes. | 708 # Do a clobbered build due to cmake changes. |
| 697 if os.path.isdir(COMPILER_RT_BUILD_DIR): | 709 #if os.path.isdir(COMPILER_RT_BUILD_DIR): |
| 698 RmTree(COMPILER_RT_BUILD_DIR) | 710 #RmTree(COMPILER_RT_BUILD_DIR) |
| 699 os.makedirs(COMPILER_RT_BUILD_DIR) | 711 #os.makedirs(COMPILER_RT_BUILD_DIR) |
| 700 os.chdir(COMPILER_RT_BUILD_DIR) | 712 os.chdir(COMPILER_RT_BUILD_DIR) |
| 701 # TODO(thakis): Add this once compiler-rt can build with clang-cl (see | 713 # TODO(thakis): Add this once compiler-rt can build with clang-cl (see |
| 702 # above). | 714 # above). |
| 703 #if args.bootstrap and sys.platform == 'win32': | 715 #if args.bootstrap and sys.platform == 'win32': |
| 704 # The bootstrap compiler produces 64-bit binaries by default. | 716 # The bootstrap compiler produces 64-bit binaries by default. |
| 705 #cflags += ['-m32'] | 717 #cflags += ['-m32'] |
| 706 #cxxflags += ['-m32'] | 718 #cxxflags += ['-m32'] |
| 707 compiler_rt_args = base_cmake_args + [ | 719 compiler_rt_args = base_cmake_args + [ |
| 708 '-DLLVM_ENABLE_THREADS=OFF', | 720 '-DLLVM_ENABLE_THREADS=OFF', |
| 709 '-DCMAKE_C_FLAGS=' + ' '.join(cflags), | 721 '-DCMAKE_C_FLAGS=' + ' '.join(cflags), |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 '-DANDROID=1'] | 829 '-DANDROID=1'] |
| 818 RmCmakeCache('.') | 830 RmCmakeCache('.') |
| 819 RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR]) | 831 RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR]) |
| 820 RunCommand(['ninja', 'libclang_rt.asan-%s-android.so' % target_arch]) | 832 RunCommand(['ninja', 'libclang_rt.asan-%s-android.so' % target_arch]) |
| 821 | 833 |
| 822 # And copy it into the main build tree. | 834 # And copy it into the main build tree. |
| 823 runtime = 'libclang_rt.asan-%s-android.so' % target_arch | 835 runtime = 'libclang_rt.asan-%s-android.so' % target_arch |
| 824 for root, _, files in os.walk(build_dir): | 836 for root, _, files in os.walk(build_dir): |
| 825 if runtime in files: | 837 if runtime in files: |
| 826 shutil.copy(os.path.join(root, runtime), asan_rt_lib_dst_dir) | 838 shutil.copy(os.path.join(root, runtime), asan_rt_lib_dst_dir) |
| 839 if args.with_fuchsia: |
| 840 # Fuchsia links against libclang_rt.builtins-<arch>.a instead of libgcc.a. |
| 841 for target_arch in ['aarch64', 'x86_64']: |
| 842 toolchain_dir = os.path.join( |
| 843 FUCHSIA_SDK_DIR, 'sysroot', '%s-fuchsia' % target_arch) |
| 844 # Build clang_rt runtime for Fuchsia in a separate build tree. |
| 845 build_dir = os.path.join(LLVM_BUILD_DIR, 'fuchsia-' + target_arch) |
| 846 if not os.path.exists(build_dir): |
| 847 os.mkdir(os.path.join(build_dir)) |
| 848 os.chdir(build_dir) |
| 849 # TODO(thakis): Might have to pass -B here once sysroot contains |
| 850 # binaries (e.g. gas for arm64?) |
| 851 cflags = ['--target=%s-fuchsia' % target_arch, |
| 852 '--sysroot=%s' % toolchain_dir] |
| 853 ldflags = ['--sysroot=%s' % toolchain_dir] |
| 854 fuchsia_args = base_cmake_args + [ |
| 855 '-DLLVM_ENABLE_THREADS=OFF', |
| 856 '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'), |
| 857 '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'), |
| 858 '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'), |
| 859 '-DCMAKE_C_FLAGS=' + ' '.join(cflags), |
| 860 '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags), |
| 861 '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags), |
| 862 '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags), |
| 863 '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags), |
| 864 ] |
| 865 RmCmakeCache('.') |
| 866 RunCommand(['cmake'] + fuchsia_args + [COMPILER_RT_DIR]) |
| 867 RunCommand(['ninja', 'libclang_rt.builtins-%s.a' % target_arch]) |
| 868 |
| 869 # And copy it into the main build tree. |
| 870 fuchsia_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang', |
| 871 VERSION, 'lib', 'fuchsia') |
| 872 runtime = 'libclang_rt.builtins-%s.a' % target_arch |
| 873 for root, _, files in os.walk(build_dir): |
| 874 if runtime in files: |
| 875 shutil.copy(os.path.join(root, runtime), fuchsia_lib_dst_dir) |
| 827 | 876 |
| 828 # Run tests. | 877 # Run tests. |
| 829 if args.run_tests or use_head_revision: | 878 if args.run_tests or use_head_revision: |
| 830 os.chdir(LLVM_BUILD_DIR) | 879 os.chdir(LLVM_BUILD_DIR) |
| 831 RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64') | 880 RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64') |
| 832 if args.run_tests: | 881 if args.run_tests: |
| 833 if sys.platform == 'win32': | 882 if sys.platform == 'win32': |
| 834 CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin')) | 883 CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin')) |
| 835 os.chdir(LLVM_BUILD_DIR) | 884 os.chdir(LLVM_BUILD_DIR) |
| 836 RunCommand(['ninja', 'check-all'], msvc_arch='x64') | 885 RunCommand(['ninja', 'check-all'], msvc_arch='x64') |
| (...skipping 24 matching lines...) Expand all Loading... |
| 861 parser.add_argument('--print-clang-version', action='store_true', | 910 parser.add_argument('--print-clang-version', action='store_true', |
| 862 help='print current clang version (e.g. x.y.z) and exit.') | 911 help='print current clang version (e.g. x.y.z) and exit.') |
| 863 parser.add_argument('--run-tests', action='store_true', | 912 parser.add_argument('--run-tests', action='store_true', |
| 864 help='run tests after building; only for local builds') | 913 help='run tests after building; only for local builds') |
| 865 parser.add_argument('--extra-tools', nargs='*', default=[], | 914 parser.add_argument('--extra-tools', nargs='*', default=[], |
| 866 help='select additional chrome tools to build') | 915 help='select additional chrome tools to build') |
| 867 parser.add_argument('--without-android', action='store_false', | 916 parser.add_argument('--without-android', action='store_false', |
| 868 help='don\'t build Android ASan runtime (linux only)', | 917 help='don\'t build Android ASan runtime (linux only)', |
| 869 dest='with_android', | 918 dest='with_android', |
| 870 default=sys.platform.startswith('linux')) | 919 default=sys.platform.startswith('linux')) |
| 920 parser.add_argument('--without-fuchsia', action='store_false', |
| 921 help='don\'t build Fuchsia clang_rt runtime (linux only)', |
| 922 dest='with_fuchsia', |
| 923 default=sys.platform.startswith('linux')) |
| 871 args = parser.parse_args() | 924 args = parser.parse_args() |
| 872 | 925 |
| 873 if args.lto_gold_plugin and not args.bootstrap: | 926 if args.lto_gold_plugin and not args.bootstrap: |
| 874 print '--lto-gold-plugin requires --bootstrap' | 927 print '--lto-gold-plugin requires --bootstrap' |
| 875 return 1 | 928 return 1 |
| 876 if args.lto_gold_plugin and not sys.platform.startswith('linux'): | 929 if args.lto_gold_plugin and not sys.platform.startswith('linux'): |
| 877 print '--lto-gold-plugin is only effective on Linux. Ignoring the option.' | 930 print '--lto-gold-plugin is only effective on Linux. Ignoring the option.' |
| 878 args.lto_gold_plugin = False | 931 args.lto_gold_plugin = False |
| 879 | 932 |
| 880 if args.if_needed: | 933 if args.if_needed: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 908 if use_head_revision: | 961 if use_head_revision: |
| 909 # Use a real revision number rather than HEAD to make sure that the stamp | 962 # Use a real revision number rather than HEAD to make sure that the stamp |
| 910 # file logic works. | 963 # file logic works. |
| 911 CLANG_REVISION = GetSvnRevision(LLVM_REPO_URL) | 964 CLANG_REVISION = GetSvnRevision(LLVM_REPO_URL) |
| 912 PACKAGE_VERSION = CLANG_REVISION + '-0' | 965 PACKAGE_VERSION = CLANG_REVISION + '-0' |
| 913 | 966 |
| 914 args.force_local_build = True | 967 args.force_local_build = True |
| 915 if 'OS=android' not in os.environ.get('GYP_DEFINES', ''): | 968 if 'OS=android' not in os.environ.get('GYP_DEFINES', ''): |
| 916 # Only build the Android ASan rt on ToT bots when targetting Android. | 969 # Only build the Android ASan rt on ToT bots when targetting Android. |
| 917 args.with_android = False | 970 args.with_android = False |
| 971 # Don't build fuchsia runtime on ToT bots at all. |
| 972 args.with_fuchsia = False |
| 918 | 973 |
| 919 return UpdateClang(args) | 974 return UpdateClang(args) |
| 920 | 975 |
| 921 | 976 |
| 922 if __name__ == '__main__': | 977 if __name__ == '__main__': |
| 923 sys.exit(main()) | 978 sys.exit(main()) |
| OLD | NEW |