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 |