| Index: tools/clang/scripts/update.py
|
| diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
|
| index a83e6eba3307d8e28351d44d35b23599320a9f15..6e4514417756ac52d629279b778d2e4fbabe7e24 100755
|
| --- a/tools/clang/scripts/update.py
|
| +++ b/tools/clang/scripts/update.py
|
| @@ -51,10 +51,16 @@ LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
|
| CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
|
| LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
|
| 'Release+Asserts')
|
| -COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt')
|
| +COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'compiler-rt')
|
| CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
|
| LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
|
| -COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
|
| +# compiler-rt is built as part of the regular LLVM build on Windows to get
|
| +# the 64-bit runtime, and out-of-tree elsewhere.
|
| +# TODO(thakis): Try to unify this.
|
| +if sys.platform == 'win32':
|
| + COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
|
| +else:
|
| + COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'compiler-rt')
|
| LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx')
|
| LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
|
| LLVM_BUILD_TOOLS_DIR = os.path.abspath(
|
| @@ -62,6 +68,8 @@ LLVM_BUILD_TOOLS_DIR = os.path.abspath(
|
| STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')
|
| BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
|
| VERSION = '3.8.0'
|
| +ANDROID_NDK_DIR = os.path.join(
|
| + CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk')
|
|
|
| # URL for pre-built binaries.
|
| CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang'
|
| @@ -184,6 +192,7 @@ def CopyFile(src, dst):
|
| def CopyDirectoryContents(src, dst, filename_filter=None):
|
| """Copy the files from directory src to dst
|
| with an optional filename filter."""
|
| + dst = os.path.realpath(dst) # realpath() in case dst ends in /..
|
| if not os.path.exists(dst):
|
| os.makedirs(dst)
|
| for root, _, files in os.walk(src):
|
| @@ -322,14 +331,26 @@ def UpdateClang(args):
|
| DownloadAndUnpack(cds_full_url, LLVM_BUILD_DIR)
|
| print 'clang %s unpacked' % PACKAGE_VERSION
|
| # Download the gold plugin if requested to by an environment variable.
|
| - # This is used by the CFI ClusterFuzz bot.
|
| - if 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ:
|
| + # This is used by the CFI ClusterFuzz bot, and it's required for official
|
| + # builds on linux.
|
| + if 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ or (
|
| + sys.platform.startswith('linux') and
|
| + 'buildtype=Official' in sys.environ.get('GYP_DEFINES', '') and
|
| + 'branding=Chrome' in sys.environ.get('GYP_DEFINES', '')):
|
| RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
|
| WriteStampFile(PACKAGE_VERSION)
|
| return 0
|
| except urllib2.HTTPError:
|
| print 'Did not find prebuilt clang %s, building locally' % cds_file
|
|
|
| + if args.with_android and not os.path.exists(ANDROID_NDK_DIR):
|
| + print 'Android NDK not found at ' + ANDROID_NDK_DIR
|
| + print 'The Android NDK is needed to build a Clang whose -fsanitize=address'
|
| + print 'works on Android. See '
|
| + print 'http://code.google.com/p/chromium/wiki/AndroidBuildInstructions'
|
| + print 'for how to install the NDK, or pass --without-android.'
|
| + return 1
|
| +
|
| MaybeDownloadHostGcc(args)
|
| AddCMakeToPath()
|
|
|
| @@ -491,6 +512,10 @@ def UpdateClang(args):
|
| cflags += ['-DLLVM_FORCE_HEAD_REVISION']
|
| cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']
|
|
|
| + # Pin MSan to the old ABI.
|
| + # TODO(eugenis): Remove when MSan migrates to new ABI (crbug.com/560589).
|
| + cxxflags += [ '-DMSAN_LINUX_X86_64_OLD_MAPPING' ]
|
| +
|
| CreateChromeToolsShim()
|
|
|
| deployment_env = None
|
| @@ -498,7 +523,13 @@ def UpdateClang(args):
|
| deployment_env = os.environ.copy()
|
| deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
|
|
|
| - cmake_args = base_cmake_args + [
|
| + cmake_args = []
|
| + # TODO(thakis): Unconditionally append this to base_cmake_args instead once
|
| + # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
|
| + cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
|
| + if cc is not None: cc_args.append('-DCMAKE_C_COMPILER=' + cc)
|
| + if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
|
| + cmake_args += base_cmake_args + [
|
| '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
|
| '-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly',
|
| '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
|
| @@ -509,11 +540,6 @@ def UpdateClang(args):
|
| '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
|
| '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
|
| '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
|
| - # TODO(thakis): Unconditionally append this to base_cmake_args instead once
|
| - # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
|
| - cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
|
| - if cc is not None: cc_args.append('-DCMAKE_C_COMPILER=' + cc)
|
| - if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
|
|
|
| if not os.path.exists(LLVM_BUILD_DIR):
|
| os.makedirs(LLVM_BUILD_DIR)
|
| @@ -536,17 +562,21 @@ def UpdateClang(args):
|
| RunCommand(['ninja', 'cr-install'], msvc_arch='x64')
|
|
|
| if sys.platform == 'darwin':
|
| - CopyFile(os.path.join(LLVM_BUILD_DIR, 'libc++.1.dylib'),
|
| + CopyFile(os.path.join(libcxxbuild, 'libc++.1.dylib'),
|
| os.path.join(LLVM_BUILD_DIR, 'bin'))
|
| # See http://crbug.com/256342
|
| RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
|
| elif sys.platform.startswith('linux'):
|
| RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
|
|
|
| - # Do an x86 build of compiler-rt to get the 32-bit ASan run-time.
|
| + # Do an out-of-tree build of compiler-rt.
|
| + # On Windows, this is used to get the 32-bit ASan run-time.
|
| # TODO(hans): Remove once the regular build above produces this.
|
| - if not os.path.exists(COMPILER_RT_BUILD_DIR):
|
| - os.makedirs(COMPILER_RT_BUILD_DIR)
|
| + # On Mac and Linux, this is used to get the regular 64-bit run-time.
|
| + # Do a clobbered build due to cmake changes.
|
| + if os.path.isdir(COMPILER_RT_BUILD_DIR):
|
| + RmTree(COMPILER_RT_BUILD_DIR)
|
| + os.makedirs(COMPILER_RT_BUILD_DIR)
|
| os.chdir(COMPILER_RT_BUILD_DIR)
|
| # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
|
| # above).
|
| @@ -561,10 +591,14 @@ def UpdateClang(args):
|
| compiler_rt_args += ['-DLLVM_CONFIG_PATH=' +
|
| os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config'),
|
| '-DSANITIZER_MIN_OSX_VERSION="10.7"']
|
| - RunCommand(['cmake'] + compiler_rt_args + [LLVM_DIR],
|
| - msvc_arch='x86', env=deployment_env)
|
| + # compiler-rt is part of the llvm checkout on Windows but a stand-alone
|
| + # directory elsewhere, see the TODO above COMPILER_RT_DIR.
|
| + RunCommand(['cmake'] + compiler_rt_args +
|
| + [LLVM_DIR if sys.platform == 'win32' else COMPILER_RT_DIR],
|
| + msvc_arch='x86', env=deployment_env)
|
| RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')
|
|
|
| + # Copy select output to the main tree.
|
| # TODO(hans): Make this (and the .gypi and .isolate files) version number
|
| # independent.
|
| if sys.platform == 'win32':
|
| @@ -574,17 +608,26 @@ def UpdateClang(args):
|
| else:
|
| assert sys.platform.startswith('linux')
|
| platform = 'linux'
|
| - asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
|
| - VERSION, 'lib', platform)
|
| + asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', platform)
|
| + if sys.platform == 'win32':
|
| + # TODO(thakis): This too is due to compiler-rt being part of the checkout
|
| + # on Windows, see TODO above COMPILER_RT_DIR.
|
| + asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
|
| + VERSION, 'lib', platform)
|
| asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
|
| VERSION, 'lib', platform)
|
| - CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir,
|
| - r'^.*-i386\.lib$')
|
| - CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir,
|
| - r'^.*-i386\.dll$')
|
| + # Blacklists:
|
| + CopyDirectoryContents(os.path.join(asan_rt_lib_src_dir, '..', '..'),
|
| + os.path.join(asan_rt_lib_dst_dir, '..', '..'),
|
| + r'^.*blacklist\.txt$')
|
| + # Headers:
|
| + if sys.platform != 'win32':
|
| + CopyDirectoryContents(
|
| + os.path.join(COMPILER_RT_BUILD_DIR, 'include/sanitizer'),
|
| + os.path.join(LLVM_BUILD_DIR, 'lib/clang', VERSION, 'include/sanitizer'))
|
| + # Static and dynamic libraries:
|
| + CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir)
|
|
|
| - CopyFile(os.path.join(asan_rt_lib_src_dir, '..', '..', 'asan_blacklist.txt'),
|
| - os.path.join(asan_rt_lib_dst_dir, '..', '..'))
|
|
|
| if sys.platform == 'win32':
|
| # Make an extra copy of the sanitizer headers, to be put on the include path
|
| @@ -601,15 +644,63 @@ def UpdateClang(args):
|
| CopyFile(os.path.join(sanitizer_include_dir, f),
|
| aux_sanitizer_include_dir)
|
|
|
| + if args.with_android:
|
| + make_toolchain = os.path.join(
|
| + ANDROID_NDK_DIR, 'build', 'tools', 'make-standalone-toolchain.sh')
|
| + for target_arch in ['aarch64', 'arm', 'i686']:
|
| + # Make standalone Android toolchain for target_arch.
|
| + toolchain_dir = os.path.join(
|
| + LLVM_BUILD_DIR, 'android-toolchain-' + target_arch)
|
| + RunCommand([
|
| + make_toolchain,
|
| + '--platform=android-' + ('21' if target_arch == 'aarch64' else '19'),
|
| + '--install-dir="%s"' % toolchain_dir,
|
| + '--system=linux-x86_64',
|
| + '--stl=stlport',
|
| + '--toolchain=' + {
|
| + 'aarch64': 'aarch64-linux-android-4.9',
|
| + 'arm': 'arm-linux-androideabi-4.9',
|
| + 'i686': 'x86-4.9',
|
| + }[target_arch]])
|
| + # Android NDK r9d copies a broken unwind.h into the toolchain, see
|
| + # http://crbug.com/357890
|
| + for f in glob.glob(os.path.join(toolchain_dir, 'include/c++/*/unwind.h')):
|
| + os.remove(f)
|
| +
|
| + # Build ASan runtime for Android in a separate build tree.
|
| + build_dir = os.path.join(LLVM_BUILD_DIR, 'android-' + target_arch)
|
| + if not os.path.exists(build_dir):
|
| + os.mkdir(os.path.join(build_dir))
|
| + os.chdir(build_dir)
|
| + if os.path.exists('CMakeCache.txt'):
|
| + os.remove('CMakeCache.txt')
|
| +
|
| + cflags = ['--target=%s-linux-androideabi' % target_arch,
|
| + '--sysroot=%s/sysroot' % toolchain_dir,
|
| + '-B%s' % toolchain_dir]
|
| + android_args = base_cmake_args + [
|
| + '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
|
| + '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
|
| + '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
|
| + '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
|
| + '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
|
| + '-DANDROID=1']
|
| + RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR])
|
| + RunCommand(['ninja', 'libclang_rt.asan-%s-android.so' % target_arch])
|
| +
|
| + # And copy it into the main build tree.
|
| + runtime = 'libclang_rt.asan-%s-android.so' % target_arch
|
| + for root, _, files in os.walk(build_dir):
|
| + if runtime in files:
|
| + shutil.copy(os.path.join(root, runtime), asan_rt_lib_dst_dir)
|
| +
|
| # Run tests.
|
| if args.run_tests or use_head_revision:
|
| os.chdir(LLVM_BUILD_DIR)
|
| - RunCommand(GetVSVersion().SetupScript('x64') +
|
| - ['&&', 'ninja', 'cr-check-all'])
|
| + RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64')
|
| if args.run_tests:
|
| os.chdir(LLVM_BUILD_DIR)
|
| - RunCommand(GetVSVersion().SetupScript('x64') +
|
| - ['&&', 'ninja', 'check-all'])
|
| + RunCommand(['ninja', 'check-all'], msvc_arch='x64')
|
|
|
| WriteStampFile(PACKAGE_VERSION)
|
| print 'Clang update was successful.'
|
| @@ -661,6 +752,10 @@ def main():
|
| parser.add_argument('--tools', nargs='*',
|
| help='select which chrome tools to build',
|
| default=['plugins', 'blink_gc_plugin'])
|
| + parser.add_argument('--without-android', action='store_false',
|
| + help='don\tt build Android ASan runtime (linux only)',
|
| + dest='with_android',
|
| + default=sys.platform.startswith('linux'))
|
|
|
| # For now, these flags are only used for the non-Windows flow, but argparser
|
| # gets mad if it sees a flag it doesn't recognize.
|
| @@ -711,6 +806,9 @@ def main():
|
| PACKAGE_VERSION = LLVM_WIN_REVISION + '-0'
|
|
|
| args.force_local_build = True
|
| + if 'OS=android' not in os.environ.get('GYP_DEFINES', ''):
|
| + # Only build the Android ASan rt on ToT bots when targetting Android.
|
| + args.with_android = False
|
|
|
| return UpdateClang(args)
|
|
|
|
|