#!/usr/bin/env python
#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# pylint: disable=not-callable, relative-import, line-too-long

import argparse
import datetime
import glob
import logging
import os
import shutil
import string
import subprocess
import textwrap
import utils

import android_version
from version import Version

import mapfile

ORIG_ENV = dict(os.environ)

# Remove GOMA from our environment for building anything from stage2 onwards,
# since it is using a non-GOMA compiler (from stage1) to do the compilation.
USE_GOMA_FOR_STAGE1 = False
if ('USE_GOMA' in ORIG_ENV) and (ORIG_ENV['USE_GOMA'] is 'true'):
    USE_GOMA_FOR_STAGE1 = True
    del ORIG_ENV['USE_GOMA']

STAGE2_TARGETS = 'AArch64;ARM;BPF;X86'


def logger():
    """Returns the module level logger."""
    return logging.getLogger(__name__)


def check_call(cmd, *args, **kwargs):
    """subprocess.check_call with logging."""
    logger().info('check_call:%s %s',
                  datetime.datetime.now().strftime("%H:%M:%S"),
                  subprocess.list2cmdline(cmd))
    subprocess.check_call(cmd, *args, **kwargs)


def check_output(cmd, *args, **kwargs):
    """subprocess.check_output with logging."""
    logger().info('check_output:%s %s',
                  datetime.datetime.now().strftime("%H:%M:%S"),
                  subprocess.list2cmdline(cmd))
    return subprocess.check_output(cmd, *args, **kwargs)


def install_file(src, dst):
    """Proxy for shutil.copy2 with logging and dry-run support."""
    logger().info('copy %s %s', src, dst)
    shutil.copy2(src, dst)


def remove(path):
    """Proxy for os.remove with logging."""
    logger().debug('remove %s', path)
    os.remove(path)


def extract_clang_version(clang_install):
    version_file = os.path.join(clang_install, 'include', 'clang', 'Basic',
                                'Version.inc')
    return Version(version_file)


def extract_clang_long_version(clang_install):
    return extract_clang_version(clang_install).long_version()


def pgo_profdata_filename():
    base_revision = android_version.svn_revision.rstrip(string.ascii_lowercase)
    return '%s.profdata' % base_revision

def pgo_profdata_file(profdata_file):
    profile = utils.android_path('prebuilts', 'clang', 'host', 'linux-x86',
                                 'profiles', profdata_file)
    return profile if os.path.exists(profile) else None


def ndk_base():
    ndk_version = 'r16'
    return utils.android_path('toolchain/prebuilts/ndk', ndk_version)


def android_api(arch, platform=False):
    if platform:
        return '26'
    elif arch in ['arm', 'i386', 'x86']:
        return '14'
    else:
        return '21'


def ndk_path(arch, platform=False):
    platform_level = 'android-' + android_api(arch, platform)
    return os.path.join(ndk_base(), 'platforms', platform_level)


def ndk_libcxx_headers():
    return os.path.join(ndk_base(), 'sources', 'cxx-stl', 'llvm-libc++',
                        'include')


def ndk_libcxxabi_headers():
    return os.path.join(ndk_base(), 'sources', 'cxx-stl', 'llvm-libc++abi',
                        'include')


def ndk_toolchain_lib(arch, toolchain_root, host_tag):
    toolchain_lib = os.path.join(ndk_base(), 'toolchains', toolchain_root,
                                 'prebuilt', 'linux-x86_64', host_tag)
    if arch in ['arm', 'i386']:
        toolchain_lib = os.path.join(toolchain_lib, 'lib')
    else:
        toolchain_lib = os.path.join(toolchain_lib, 'lib64')
    return toolchain_lib


def support_headers():
    return os.path.join(ndk_base(), 'sources', 'android', 'support', 'include')


# This is the baseline stable version of Clang to start our stage-1 build.
def clang_prebuilt_version():
    return 'clang-r353983b'


def clang_prebuilt_base_dir():
    return utils.android_path('prebuilts/clang/host',
                              utils.build_os_type(), clang_prebuilt_version())


def clang_prebuilt_bin_dir():
    return utils.android_path(clang_prebuilt_base_dir(), 'bin')


def clang_prebuilt_lib_dir():
    return utils.android_path(clang_prebuilt_base_dir(), 'lib64')


def arch_from_triple(triple):
    arch = triple.split('-')[0]
    if arch == 'i686':
        arch = 'i386'
    return arch


def clang_resource_dir(version, arch):
    return os.path.join('lib64', 'clang', version, 'lib', 'linux', arch)


def clang_prebuilt_libcxx_headers():
    return utils.android_path(clang_prebuilt_base_dir(), 'include', 'c++', 'v1')


def libcxx_header_dirs(ndk_cxx):
    if ndk_cxx:
        return [
            ndk_libcxx_headers(),
            ndk_libcxxabi_headers(),
            support_headers()
        ]
    else:
        # <prebuilts>/include/c++/v1 includes the cxxabi headers
        return [
            clang_prebuilt_libcxx_headers(),
            utils.android_path('bionic', 'libc', 'include')
        ]


def cmake_prebuilt_bin_dir():
    return utils.android_path('prebuilts/cmake', utils.build_os_type(), 'bin')


def cmake_bin_path():
    return os.path.join(cmake_prebuilt_bin_dir(), 'cmake')


def ninja_bin_path():
    return os.path.join(cmake_prebuilt_bin_dir(), 'ninja')


def check_create_path(path):
    if not os.path.exists(path):
        os.makedirs(path)


def get_sysroot(arch, platform=False):
    sysroots = utils.out_path('sysroots')
    platform_or_ndk = 'platform' if platform else 'ndk'
    return os.path.join(sysroots, platform_or_ndk, arch)


def debug_prefix_flag():
    return '-fdebug-prefix-map={}='.format(utils.android_path())


def create_sysroots():
    # Construct the sysroots from scratch, since symlinks can't nest within
    # the right places (without altering source prebuilts).
    configs = [
        ('arm', 'arm-linux-androideabi'),
        ('arm64', 'aarch64-linux-android'),
        ('x86_64', 'x86_64-linux-android'),
        ('x86', 'i686-linux-android'),
    ]

    # TODO(srhines): We destroy and recreate the sysroots each time, but this
    # could check for differences and only replace files if needed.
    sysroots_out = utils.out_path('sysroots')
    if os.path.exists(sysroots_out):
        shutil.rmtree(sysroots_out)
    check_create_path(sysroots_out)

    base_header_path = os.path.join(ndk_base(), 'sysroot', 'usr', 'include')
    for (arch, target) in configs:
        # Also create sysroots for each of platform and the NDK.
        for platform_or_ndk in ['platform', 'ndk']:
            platform = platform_or_ndk == 'platform'
            base_lib_path = \
                utils.android_path(ndk_base(), 'platforms',
                                   'android-' + android_api(arch, platform))
            dest_usr = os.path.join(get_sysroot(arch, platform), 'usr')

            # Copy over usr/include.
            dest_usr_include = os.path.join(dest_usr, 'include')
            shutil.copytree(base_header_path, dest_usr_include, symlinks=True)

            # Copy over usr/include/asm.
            asm_headers = os.path.join(base_header_path, target, 'asm')
            dest_usr_include_asm = os.path.join(dest_usr_include, 'asm')
            shutil.copytree(asm_headers, dest_usr_include_asm, symlinks=True)

            # Copy over usr/lib.
            arch_lib_path = os.path.join(base_lib_path, 'arch-' + arch,
                                         'usr', 'lib')
            dest_usr_lib = os.path.join(dest_usr, 'lib')
            shutil.copytree(arch_lib_path, dest_usr_lib, symlinks=True)

            # For only x86_64, we also need to copy over usr/lib64
            if arch == 'x86_64':
                arch_lib64_path = os.path.join(base_lib_path, 'arch-' + arch,
                                               'usr', 'lib64')
                dest_usr_lib64 = os.path.join(dest_usr, 'lib64')
                shutil.copytree(arch_lib64_path, dest_usr_lib64, symlinks=True)

            if platform:
                # Create a stub library for the platform's libc++.
                platform_stubs = utils.out_path('platform_stubs', arch)
                check_create_path(platform_stubs)
                libdir = dest_usr_lib64 if arch == 'x86_64' else dest_usr_lib
                with open(os.path.join(platform_stubs, 'libc++.c'), 'w') as f:
                    f.write(textwrap.dedent("""\
                        void __cxa_atexit() {}
                        void __cxa_demangle() {}
                        void __cxa_finalize() {}
                        void __dynamic_cast() {}
                        void _ZTIN10__cxxabiv117__class_type_infoE() {}
                        void _ZTIN10__cxxabiv120__si_class_type_infoE() {}
                        void _ZTIN10__cxxabiv121__vmi_class_type_infoE() {}
                        void _ZTISt9type_info() {}
                    """))
                check_call([utils.out_path('stage2-install', 'bin', 'clang'),
                            '--target=' + target,
                            '-fuse-ld=lld', '-nostdlib', '-shared',
                            '-Wl,-soname,libc++.so',
                            '-o', os.path.join(libdir, 'libc++.so'),
                            os.path.join(platform_stubs, 'libc++.c')])

                # For arm64 and x86_64, build static cxxabi library from
                # toolchain/libcxxabi and use it when building runtimes.  This
                # should affect all compiler-rt runtimes that use libcxxabi
                # (e.g. asan, hwasan, scudo, tsan, ubsan, xray).
                if arch not in ('arm64', 'x86_64'):
                    with open(os.path.join(libdir, 'libc++abi.so'), 'w') as f:
                        f.write('INPUT(-lc++)')
                else:
                    # We can build libcxxabi only after the sysroots are
                    # created.  Build it for the current arch and copy it to
                    # <libdir>.
                    out_dir = build_libcxxabi(utils.out_path('stage2-install'), arch)
                    out_path = utils.out_path(out_dir, 'lib', 'libc++abi.a')
                    shutil.copy2(out_path, os.path.join(libdir))


def update_cmake_sysroot_flags(defines, sysroot):
    defines['CMAKE_SYSROOT'] = sysroot
    defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY'
    defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY'
    defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY'
    defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER'


def rm_cmake_cache(cacheDir):
    for dirpath, dirs, files in os.walk(cacheDir): # pylint: disable=not-an-iterable
        if 'CMakeCache.txt' in files:
            os.remove(os.path.join(dirpath, 'CMakeCache.txt'))
        if 'CMakeFiles' in dirs:
            utils.rm_tree(os.path.join(dirpath, 'CMakeFiles'))


# Base cmake options such as build type that are common across all invocations
def base_cmake_defines():
    defines = {}

    defines['CMAKE_BUILD_TYPE'] = 'Release'
    defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF'
    # https://github.com/android-ndk/ndk/issues/574 - Don't depend on libtinfo.
    defines['LLVM_ENABLE_TERMINFO'] = 'OFF'
    defines['LLVM_ENABLE_THREADS'] = 'ON'
    defines['LLVM_LIBDIR_SUFFIX'] = '64'
    defines['LLVM_VERSION_PATCH'] = android_version.patch_level
    defines['CLANG_VERSION_PATCHLEVEL'] = android_version.patch_level
    defines['CLANG_REPOSITORY_STRING'] = 'https://android.googlesource.com/toolchain/clang'
    defines['LLVM_REPOSITORY_STRING'] = 'https://android.googlesource.com/toolchain/llvm'
    defines['BUG_REPORT_URL'] = 'https://github.com/android-ndk/ndk/issues'

    # http://b/111885871 - Disable building xray because of MacOS issues.
    defines['COMPILER_RT_BUILD_XRAY'] = 'OFF'
    return defines


def invoke_cmake(out_path, defines, env, cmake_path, target=None, install=True):
    flags = ['-G', 'Ninja']

    # Specify CMAKE_PREFIX_PATH so 'cmake -G Ninja ...' can find the ninja
    # executable.
    flags += ['-DCMAKE_PREFIX_PATH=' + cmake_prebuilt_bin_dir()]

    for key in defines:
        newdef = '-D' + key + '=' + defines[key]
        flags += [newdef]
    flags += [cmake_path]

    check_create_path(out_path)
    # TODO(srhines): Enable this with a flag, because it forces clean builds
    # due to the updated cmake generated files.
    #rm_cmake_cache(out_path)

    if target:
        ninja_target = [target]
    else:
        ninja_target = []

    check_call([cmake_bin_path()] + flags, cwd=out_path, env=env)
    check_call([ninja_bin_path()] + ninja_target, cwd=out_path, env=env)
    if install:
        check_call([ninja_bin_path(), 'install'], cwd=out_path, env=env)


def cross_compile_configs(stage2_install, platform=False):
    configs = [
        ('arm', 'arm', 'arm/arm-linux-androideabi-4.9/arm-linux-androideabi',
         'arm-linux-android', '-march=armv7-a'),
        ('aarch64', 'arm64',
         'aarch64/aarch64-linux-android-4.9/aarch64-linux-android',
         'aarch64-linux-android', ''),
        ('x86_64', 'x86_64',
         'x86/x86_64-linux-android-4.9/x86_64-linux-android',
         'x86_64-linux-android', ''),
        ('i386', 'x86', 'x86/x86_64-linux-android-4.9/x86_64-linux-android',
         'i686-linux-android', '-m32'),
    ]

    cc = os.path.join(stage2_install, 'bin', 'clang')
    cxx = os.path.join(stage2_install, 'bin', 'clang++')

    for (arch, ndk_arch, toolchain_path, llvm_triple, extra_flags) in configs:
        toolchain_root = utils.android_path('prebuilts/gcc',
                                            utils.build_os_type())
        toolchain_bin = os.path.join(toolchain_root, toolchain_path, 'bin')
        sysroot = get_sysroot(ndk_arch, platform)

        defines = {}
        defines['CMAKE_C_COMPILER'] = cc
        defines['CMAKE_CXX_COMPILER'] = cxx

        # Include the directory with libgcc.a to the linker search path.
        toolchain_builtins = os.path.join(
            toolchain_root, toolchain_path, '..', 'lib', 'gcc',
            os.path.basename(toolchain_path), '4.9.x')
        # The 32-bit libgcc.a is sometimes in a separate subdir
        if arch == 'i386':
            toolchain_builtins = os.path.join(toolchain_builtins, '32')

        if ndk_arch == 'arm':
            toolchain_lib = ndk_toolchain_lib(arch, 'arm-linux-androideabi-4.9',
                                              'arm-linux-androideabi')
        elif ndk_arch == 'x86' or ndk_arch == 'x86_64':
            toolchain_lib = ndk_toolchain_lib(arch, ndk_arch + '-4.9',
                                              llvm_triple)
        else:
            toolchain_lib = ndk_toolchain_lib(arch, llvm_triple + '-4.9',
                                              llvm_triple)

        ldflags = [
            '-L' + toolchain_builtins, '-Wl,-z,defs',
            '-L' + toolchain_lib,
            '-fuse-ld=lld',
            '-Wl,--gc-sections',
            '-Wl,--build-id=sha1',
        ]
        if not platform:
            libcxx_libs = os.path.join(ndk_base(), 'sources', 'cxx-stl',
                                       'llvm-libc++', 'libs')
            if ndk_arch == 'arm':
                libcxx_libs = os.path.join(libcxx_libs, 'armeabi')
            elif ndk_arch == 'arm64':
                libcxx_libs = os.path.join(libcxx_libs, 'arm64-v8a')
            else:
                libcxx_libs = os.path.join(libcxx_libs, ndk_arch)
            ldflags += ['-L', libcxx_libs]

        defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags)
        defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags)
        defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags)
        update_cmake_sysroot_flags(defines, sysroot)

        cflags = [
            debug_prefix_flag(),
            '--target=%s' % llvm_triple,
            '-B%s' % toolchain_bin,
            '-D__ANDROID_API__=%s' % android_api(arch, platform=platform),
            '-ffunction-sections',
            '-fdata-sections',
            extra_flags,
        ]
        yield (arch, llvm_triple, defines, cflags)


def build_asan_test(stage2_install):
    # We can not build asan_test using current CMake building system. Since
    # those files are not used to build AOSP, we just simply touch them so that
    # we can pass the build checks.
    for arch in ('aarch64', 'arm', 'i686'):
        asan_test_path = os.path.join(stage2_install, 'test', arch, 'bin')
        check_create_path(asan_test_path)
        asan_test_bin_path = os.path.join(asan_test_path, 'asan_test')
        open(asan_test_bin_path, 'w+').close()

def build_sanitizer_map_file(san, arch, lib_dir):
    lib_file = os.path.join(lib_dir, 'libclang_rt.{}-{}-android.so'.format(san, arch))
    map_file = os.path.join(lib_dir, 'libclang_rt.{}-{}-android.map.txt'.format(san, arch))
    mapfile.create_map_file(lib_file, map_file)

def build_sanitizer_map_files(stage2_install, clang_version):
    lib_dir = os.path.join(stage2_install,
                           clang_resource_dir(clang_version.long_version(), ''))
    for arch in ('aarch64', 'arm', 'i686', 'x86_64'):
        build_sanitizer_map_file('asan', arch, lib_dir)
    build_sanitizer_map_file('hwasan', 'aarch64', lib_dir)

def create_hwasan_symlink(stage2_install, clang_version):
    lib_dir = os.path.join(stage2_install,
                           clang_resource_dir(clang_version.long_version(), ''))
    os.symlink('libclang_rt.hwasan-aarch64-android.a',
               lib_dir + 'libclang_rt.hwasan_static-aarch64-android.a')

def build_libcxx(stage2_install, clang_version):
    for (arch, llvm_triple, libcxx_defines,
         cflags) in cross_compile_configs(stage2_install): # pylint: disable=not-an-iterable
        logger().info('Building libcxx for %s', arch)
        libcxx_path = utils.out_path('lib', 'libcxx-' + arch)

        libcxx_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
        libcxx_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
        libcxx_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)
        libcxx_defines['CMAKE_BUILD_TYPE'] = 'Release'

        libcxx_env = dict(ORIG_ENV)

        libcxx_cmake_path = utils.llvm_path('projects', 'libcxx')
        rm_cmake_cache(libcxx_path)

        invoke_cmake(
            out_path=libcxx_path,
            defines=libcxx_defines,
            env=libcxx_env,
            cmake_path=libcxx_cmake_path,
            install=False)
        # We need to install libcxx manually.
        install_subdir = clang_resource_dir(clang_version.long_version(),
                                            arch_from_triple(llvm_triple))
        libcxx_install = os.path.join(stage2_install, install_subdir)

        libcxx_libs = os.path.join(libcxx_path, 'lib')
        check_create_path(libcxx_install)
        for f in os.listdir(libcxx_libs):
            if f.startswith('libc++'):
                shutil.copy2(os.path.join(libcxx_libs, f), libcxx_install)


def build_crts(stage2_install, clang_version, ndk_cxx=False):
    llvm_config = os.path.join(stage2_install, 'bin', 'llvm-config')
    # Now build compiler-rt for each arch
    for (arch, llvm_triple, crt_defines,
         cflags) in cross_compile_configs(stage2_install, platform=(not ndk_cxx)): # pylint: disable=not-an-iterable
        logger().info('Building compiler-rt for %s', arch)
        crt_path = utils.out_path('lib', 'clangrt-' + arch)
        crt_install = os.path.join(stage2_install, 'lib64', 'clang',
                                   clang_version.long_version())
        if ndk_cxx:
            crt_path += '-ndk-cxx'
            crt_install = crt_path + '-install'

        crt_defines['ANDROID'] = '1'
        crt_defines['LLVM_CONFIG_PATH'] = llvm_config
        crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'ON'
        # FIXME: Disable WError build until upstream fixed the compiler-rt
        # personality routine warnings caused by r309226.
        # crt_defines['COMPILER_RT_ENABLE_WERROR'] = 'ON'

        cflags.append('-isystem ' + support_headers())
        cflags.append('-funwind-tables')

        crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
        crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
        crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)
        crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags)
        crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = llvm_triple
        crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'OFF'
        crt_defines['CMAKE_INSTALL_PREFIX'] = crt_install

        # Build libfuzzer separately.
        crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF'

        crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi'
        libs = []
        if arch == 'arm':
            libs += ['-latomic']
        if ndk_cxx:
            libs += ['-landroid_support']
        crt_defines['SANITIZER_COMMON_LINK_LIBS'] = ' '.join(libs)
        if not ndk_cxx:
            crt_defines['COMPILER_RT_HWASAN_WITH_INTERCEPTORS'] = 'OFF'

        crt_defines.update(base_cmake_defines())

        crt_env = dict(ORIG_ENV)

        crt_cmake_path = utils.llvm_path('projects', 'compiler-rt')
        rm_cmake_cache(crt_path)
        invoke_cmake(
            out_path=crt_path,
            defines=crt_defines,
            env=crt_env,
            cmake_path=crt_cmake_path)

        if ndk_cxx:
            src_dir = os.path.join(crt_install, 'lib', 'linux')
            dst_dir = os.path.join(stage2_install, 'runtimes_ndk_cxx')
            check_create_path(dst_dir)
            for f in os.listdir(src_dir):
                shutil.copy2(os.path.join(src_dir, f), os.path.join(dst_dir, f))


def build_libfuzzers(stage2_install, clang_version, ndk_cxx=False):
    llvm_config = os.path.join(stage2_install, 'bin', 'llvm-config')

    for (arch, llvm_triple, libfuzzer_defines, cflags) in cross_compile_configs( # pylint: disable=not-an-iterable
            stage2_install, platform=(not ndk_cxx)):
        logger().info('Building libfuzzer for %s (ndk_cxx? %s)', arch, ndk_cxx)

        libfuzzer_path = utils.out_path('lib', 'libfuzzer-' + arch)
        if ndk_cxx:
            libfuzzer_path += '-ndk-cxx'

        libfuzzer_defines['ANDROID'] = '1'
        libfuzzer_defines['LLVM_CONFIG_PATH'] = llvm_config

        cflags.extend('-isystem ' + d for d in libcxx_header_dirs(ndk_cxx))

        libfuzzer_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
        libfuzzer_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
        libfuzzer_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)
        if ndk_cxx:
          libfuzzer_defines['CMAKE_CXX_FLAGS'] += ' -stdlib=libstdc++'

        # lib/Fuzzer/CMakeLists.txt does not call cmake_minimum_required() to
        # set a minimum version.  Explicitly request a policy that'll pass
        # CMAKE_*_LINKER_FLAGS to the trycompile() step.
        libfuzzer_defines['CMAKE_POLICY_DEFAULT_CMP0056'] = 'NEW'

        libfuzzer_cmake_path = utils.llvm_path('projects', 'compiler-rt')
        libfuzzer_env = dict(ORIG_ENV)
        rm_cmake_cache(libfuzzer_path)
        invoke_cmake(
            out_path=libfuzzer_path,
            defines=libfuzzer_defines,
            env=libfuzzer_env,
            cmake_path=libfuzzer_cmake_path,
            target='fuzzer',
            install=False)
        # We need to install libfuzzer manually.
        sarch = arch
        if sarch == 'i386':
            sarch = 'i686'
        static_lib_filename = 'libclang_rt.fuzzer-' + sarch + '-android.a'
        static_lib = os.path.join(libfuzzer_path, 'lib', 'linux', static_lib_filename)
        triple_arch = arch_from_triple(llvm_triple)
        if ndk_cxx:
            lib_subdir = os.path.join('runtimes_ndk_cxx', triple_arch)
        else:
            lib_subdir = clang_resource_dir(clang_version.long_version(),
                                            triple_arch)
        lib_dir = os.path.join(stage2_install, lib_subdir)

        check_create_path(lib_dir)
        shutil.copy2(static_lib, os.path.join(lib_dir, 'libFuzzer.a'))

    # Install libfuzzer headers.
    header_src = utils.llvm_path('projects', 'compiler-rt', 'lib', 'fuzzer')
    header_dst = os.path.join(stage2_install, 'prebuilt_include', 'llvm', 'lib',
                              'Fuzzer')
    check_create_path(header_dst)
    for f in os.listdir(header_src):
        if f.endswith('.h') or f.endswith('.def'):
            shutil.copy2(os.path.join(header_src, f), header_dst)


def build_libcxxabi(stage2_install, build_arch):
    # Normalize arm64/aarch64
    if build_arch == 'arm64':
        build_arch = 'aarch64'

    # TODO: Refactor cross_compile_configs to support per-arch queries in
    # addition to being a generator.
    for (arch, llvm_triple, defines, cflags) in \
         cross_compile_configs(stage2_install, platform=True): # pylint: disable=not-an-iterable

        # Build only the requested arch.
        if arch != build_arch:
            continue

        logger().info('Building libcxxabi for %s', arch)
        defines['LIBCXXABI_LIBCXX_INCLUDES'] = utils.android_path('toolchain', 'libcxx', 'include')
        defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF'
        defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
        defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)

        out_path = utils.out_path('lib', 'libcxxabi-' + arch)
        if os.path.exists(out_path):
            utils.rm_tree(out_path)

        invoke_cmake(out_path=out_path,
                     defines=defines,
                     env=dict(ORIG_ENV),
                     cmake_path=utils.android_path('toolchain', 'libcxxabi'),
                     install=False)
        return out_path


def build_libomp(stage2_install, clang_version, ndk_cxx=False):

    for (arch, llvm_triple, libomp_defines, cflags) in cross_compile_configs( # pylint: disable=not-an-iterable
            stage2_install, platform=(not ndk_cxx)):

        logger().info('Building libomp for %s (ndk_cxx? %s)', arch, ndk_cxx)
        cflags.extend('-isystem ' + d for d in libcxx_header_dirs(ndk_cxx))
        cflags.append('-fPIC')

        libomp_path = utils.out_path('lib', 'libomp-' + arch)
        if ndk_cxx:
            libomp_path += '-ndk-cxx'

        libomp_defines['ANDROID'] = '1'
        libomp_defines['CMAKE_BUILD_TYPE'] = 'Release'
        libomp_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
        libomp_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
        libomp_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + ' -stdlib=libstdc++'
        libomp_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE'
        libomp_defines['OPENMP_ENABLE_LIBOMPTARGET'] = 'FALSE'

        # Minimum version for OpenMP's CMake is too low for the CMP0056 policy
        # to be ON by default.
        libomp_defines['CMAKE_POLICY_DEFAULT_CMP0056'] = 'NEW'

        libomp_cmake_path = utils.llvm_path('projects', 'openmp')
        libomp_env = dict(ORIG_ENV)
        rm_cmake_cache(libomp_path)
        invoke_cmake(
            out_path=libomp_path,
            defines=libomp_defines,
            env=libomp_env,
            cmake_path=libomp_cmake_path,
            install=False)

        # We need to install libomp manually.
        static_lib = os.path.join(libomp_path, 'runtime', 'src', 'libomp.a')
        triple_arch = arch_from_triple(llvm_triple)
        if ndk_cxx:
            lib_subdir = os.path.join('runtimes_ndk_cxx', triple_arch)
        else:
            lib_subdir = clang_resource_dir(clang_version.long_version(),
                                            triple_arch)
        lib_dir = os.path.join(stage2_install, lib_subdir)

        check_create_path(lib_dir)
        shutil.copy2(static_lib, os.path.join(lib_dir, 'libomp.a'))


def build_crts_host_i686(stage2_install, clang_version):
    logger().info('Building compiler-rt for host-i686')

    llvm_config = os.path.join(stage2_install, 'bin', 'llvm-config')

    crt_install = os.path.join(stage2_install, 'lib64', 'clang',
                               clang_version.long_version())
    crt_cmake_path = utils.llvm_path('projects', 'compiler-rt')

    cflags, ldflags = host_gcc_toolchain_flags(utils.build_os_type(), is_32_bit=True)

    crt_defines = base_cmake_defines()
    crt_defines['CMAKE_C_COMPILER'] = os.path.join(stage2_install, 'bin',
                                                   'clang')
    crt_defines['CMAKE_CXX_COMPILER'] = os.path.join(stage2_install, 'bin',
                                                     'clang++')

    # Skip building runtimes for i386
    crt_defines['COMPILER_RT_DEFAULT_TARGET_ONLY'] = 'ON'

    # Due to CMake and Clang oddities, we need to explicitly set
    # CMAKE_C_COMPILER_TARGET and use march=i686 in cflags below instead of
    # relying on auto-detection from the Compiler-rt CMake files.
    crt_defines['CMAKE_C_COMPILER_TARGET'] = 'i386-linux-gnu'

    crt_defines['CMAKE_SYSROOT'] = host_sysroot()

    cflags.append('--target=i386-linux-gnu')
    cflags.append('-march=i686')

    crt_defines['LLVM_CONFIG_PATH'] = llvm_config
    crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'ON'
    crt_defines['COMPILER_RT_ENABLE_WERROR'] = 'ON'
    crt_defines['CMAKE_INSTALL_PREFIX'] = crt_install
    crt_defines['SANITIZER_CXX_ABI'] = 'libstdc++'

    crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF'

    # Set the compiler and linker flags
    crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
    crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
    crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)

    crt_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags)
    crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags)
    crt_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags)

    crt_env = dict(ORIG_ENV)

    crt_path = utils.out_path('lib', 'clangrt-i386-host')
    rm_cmake_cache(crt_path)
    invoke_cmake(
        out_path=crt_path,
        defines=crt_defines,
        env=crt_env,
        cmake_path=crt_cmake_path)


def build_llvm(targets,
               build_dir,
               install_dir,
               build_name,
               extra_defines=None,
               extra_env=None):
    cmake_defines = base_cmake_defines()
    cmake_defines['CMAKE_INSTALL_PREFIX'] = install_dir
    cmake_defines['LLVM_TARGETS_TO_BUILD'] = targets
    cmake_defines['LLVM_BUILD_LLVM_DYLIB'] = 'ON'
    cmake_defines['CLANG_VENDOR'] = 'Android (' + build_name + ' based on ' + \
        android_version.svn_revision + ') '
    cmake_defines['LLVM_BINUTILS_INCDIR'] = utils.android_path(
        'toolchain/binutils/binutils-2.27/include')

    if extra_defines is not None:
        cmake_defines.update(extra_defines)

    env = dict(ORIG_ENV)
    if extra_env is not None:
        env.update(extra_env)

    invoke_cmake(
        out_path=build_dir,
        defines=cmake_defines,
        env=env,
        cmake_path=utils.llvm_path())


def windows_cflags(is_32_bit):
    triple = 'i686-windows-gnu' if is_32_bit else 'x86_64-pc-windows-gnu'

    cflags = ['--target='+triple, '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64',
              '-D_WIN32_WINNT=0x0600', '-DWINVER=0x0600',
              '-D__MSVCRT_VERSION__=0x1400']

    # Use sjlj exceptions, the model implemented in 32-bit libgcc_eh
    if is_32_bit:
        cflags.append('-fsjlj-exceptions')

    return cflags


def build_libs_for_windows(libname,
                           enable_assertions,
                           install_dir,
                           is_32_bit=False):

    cflags, ldflags = host_gcc_toolchain_flags('windows-x86', is_32_bit)

    cflags.extend(windows_cflags(is_32_bit))

    cmake_defines = dict()
    cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows'
    cmake_defines['CMAKE_C_COMPILER'] = os.path.join(
        clang_prebuilt_bin_dir(), 'clang')
    cmake_defines['CMAKE_CXX_COMPILER'] = os.path.join(
        clang_prebuilt_bin_dir(), 'clang++')

    windows_sysroot = utils.android_path('prebuilts', 'gcc', 'linux-x86', 'host',
                                         'x86_64-w64-mingw32-4.8',
                                         'x86_64-w64-mingw32')
    update_cmake_sysroot_flags(cmake_defines, windows_sysroot)

    # Build only the static library.
    cmake_defines[libname.upper() + '_ENABLE_SHARED'] = 'OFF'

    if enable_assertions:
        cmake_defines[libname.upper() + '_ENABLE_ASSERTIONS'] = 'ON'

    if libname == 'libcxx':
        cmake_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON'
        cmake_defines['LIBCXX_CXX_ABI'] = 'libcxxabi'
        cmake_defines['LIBCXX_HAS_WIN32_THREAD_API'] = 'ON'

        # Use cxxabi header from the source directory since it gets installed
        # into install_dir only during libcxx's install step.  But use the
        # library from install_dir.
        cmake_defines['LIBCXX_CXX_ABI_INCLUDE_PATHS'] = utils.android_path('toolchain', 'libcxxabi', 'include')
        cmake_defines['LIBCXX_CXX_ABI_LIBRARY_PATH'] = os.path.join(install_dir, 'lib')

        # Disable libcxxabi visibility annotations since we're only building it
        # statically.
        cflags.append('-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS')

    elif libname == 'libcxxabi':
        cmake_defines['LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS'] = 'OFF'
        cmake_defines['LIBCXXABI_LIBCXX_INCLUDES'] = utils.android_path('toolchain', 'libcxx', 'include')

        # Disable libcxx visibility annotations and enable WIN32 threads.  These
        # are needed because the libcxxabi build happens before libcxx and uses
        # headers directly from the sources.
        cflags.append('-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS')
        cflags.append('-D_LIBCPP_HAS_THREAD_API_WIN32')

    cmake_defines['CMAKE_INSTALL_PREFIX'] = install_dir
    cmake_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
    cmake_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)
    cmake_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags)
    cmake_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags)
    cmake_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags)

    out_path = utils.out_path('lib', 'windows-' + libname)
    if is_32_bit:
        out_path += '-32'
    if os.path.exists(out_path):
        utils.rm_tree(out_path)

    invoke_cmake(out_path=out_path,
                 defines=cmake_defines,
                 env=dict(ORIG_ENV),
                 cmake_path=utils.android_path('toolchain', libname),
                 install=True)


def build_llvm_for_windows(stage1_install,
                           targets,
                           enable_assertions,
                           build_dir,
                           install_dir,
                           build_name,
                           is_32_bit=False):

    # Build and install libcxxabi and libcxx and use them to build Clang.
    build_libs_for_windows('libcxxabi',
                           enable_assertions,
                           install_dir,
                           is_32_bit)

    build_libs_for_windows('libcxx',
                           enable_assertions,
                           install_dir,
                           is_32_bit)

    # Write a NATIVE.cmake in windows_path that contains the compilers used
    # to build native tools such as llvm-tblgen and llvm-config.  This is
    # used below via the CMake variable CROSS_TOOLCHAIN_FLAGS_NATIVE.
    cc = os.path.join(stage1_install, 'bin', 'clang')
    cxx = os.path.join(stage1_install, 'bin', 'clang++')
    check_create_path(build_dir)
    native_cmake_file_path = os.path.join(build_dir, 'NATIVE.cmake')
    native_cmake_text = ('set(CMAKE_C_COMPILER {cc})\n'
                         'set(CMAKE_CXX_COMPILER {cxx})\n').format(
                             cc=cc, cxx=cxx)

    with open(native_cmake_file_path, 'w') as native_cmake_file:
        native_cmake_file.write(native_cmake_text)

    # Extra cmake defines to use while building for Windows
    windows_extra_defines = dict()
    windows_extra_defines['CMAKE_C_COMPILER'] = cc
    windows_extra_defines['CMAKE_CXX_COMPILER'] = cxx
    windows_extra_defines['CMAKE_SYSTEM_NAME'] = 'Windows'
    # Don't build compiler-rt, libcxx etc. for Windows
    windows_extra_defines['LLVM_BUILD_RUNTIME'] = 'OFF'
    # Build clang-tidy/clang-format for Windows.
    windows_extra_defines['LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD'] = 'ON'
    windows_extra_defines['LLVM_TOOL_OPENMP_BUILD'] = 'OFF'
    # Don't build tests for Windows.
    windows_extra_defines['LLVM_INCLUDE_TESTS'] = 'OFF'
    # Use libc++ for Windows.
    windows_extra_defines['LLVM_ENABLE_LIBCXX'] = 'ON'

    # Do not build LLVM.dll, which cannot build with lld because lld doesn't
    # silently ignore --version-script for Windows.  It's not necessary for the
    # Android toolchain anyway.
    windows_extra_defines['LLVM_BUILD_LLVM_DYLIB'] = 'OFF'

    windows_sysroot = utils.android_path('prebuilts', 'gcc', 'linux-x86',
                                         'host', 'x86_64-w64-mingw32-4.8',
                                         'x86_64-w64-mingw32')
    update_cmake_sysroot_flags(windows_extra_defines, windows_sysroot)

    # Set CMake path, toolchain file for native compilation (to build tablegen
    # etc).  Also disable libfuzzer build during native compilation.
    windows_extra_defines['CROSS_TOOLCHAIN_FLAGS_NATIVE'] = \
        '-DCMAKE_PREFIX_PATH=' + cmake_prebuilt_bin_dir() + ';' + \
        '-DCOMPILER_RT_BUILD_LIBFUZZER=OFF;'+ \
        '-DCMAKE_TOOLCHAIN_FILE=' + native_cmake_file_path

    if enable_assertions:
        windows_extra_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON'

    cflags, ldflags = host_gcc_toolchain_flags('windows-x86', is_32_bit)
    cflags.extend(windows_cflags(is_32_bit))
    cxxflags = list(cflags)

    # Use -fuse-cxa-atexit to allow static TLS destructors.  This is needed for
    # clang-tools-extra/clangd/Context.cpp
    cxxflags.append('-fuse-cxa-atexit')

    # Explicitly add the path to libc++ headers.  We don't need to configure
    # options like visibility annotations, win32 threads etc. because the
    # __generated_config header in the patch captures all the options used when
    # building libc++.
    cxxflags.extend(('-I', os.path.join(install_dir, 'include', 'c++', 'v1')))

    ldflags.extend((
        '-Wl,--dynamicbase',
        '-Wl,--nxcompat',
        # Use ucrt to find locale functions needed by libc++.
        '-lucrt', '-lucrtbase',
        # Use static-libgcc to avoid runtime dependence on libgcc_eh.
        '-static-libgcc',
        # pthread is needed by libgcc_eh
        '-lpthread',
        # Add path to libc++, libc++abi.
        '-L', os.path.join(install_dir, 'lib')))

    if is_32_bit:
        # 32-bit libraries belong in lib/.
        windows_extra_defines['LLVM_LIBDIR_SUFFIX'] = ''
    else:
        ldflags.append('-Wl,--high-entropy-va')

    # Include zlib's header and library path
    zlib_path = utils.android_path('prebuilts', 'clang', 'host', 'windows-x86',
                                   'toolchain-prebuilts', 'zlib')
    if is_32_bit:
        zlib_path = zlib_path.replace('windows-x86', 'windows-x86_32')
    zlib_inc = os.path.join(zlib_path, 'include')
    zlib_lib = os.path.join(zlib_path, 'lib')

    cflags.extend(['-I', zlib_inc])
    cxxflags.extend(['-I', zlib_inc])
    ldflags.extend(['-L', zlib_lib])

    windows_extra_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
    windows_extra_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
    windows_extra_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags)
    windows_extra_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags)
    windows_extra_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags)
    windows_extra_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags)

    windows_extra_env = dict()
    if USE_GOMA_FOR_STAGE1:
        windows_extra_env['USE_GOMA'] = 'true'

    build_llvm(
        targets=targets,
        build_dir=build_dir,
        install_dir=install_dir,
        build_name=build_name,
        extra_defines=windows_extra_defines,
        extra_env=windows_extra_env)


def host_sysroot():
    if utils.host_is_darwin():
        return ""
    else:
        return utils.android_path('prebuilts/gcc', utils.build_os_type(),
                                  'host/x86_64-linux-glibc2.17-4.8/sysroot')


def host_gcc_toolchain_flags(host_os, is_32_bit=False):
    def formatFlags(flags, **values):
        flagsStr = ' '.join(flags)
        flagsStr = flagsStr.format(**values)
        return flagsStr.split(' ')

    cflags = [debug_prefix_flag()]
    ldflags = []

    if host_os == 'darwin-x86':
        xcrun_command = ['xcrun', '--show-sdk-path']
        macSdkRoot = (check_output(xcrun_command)).strip()
        # We were using 10.8, but we need 10.9 to use ~type_info() from libcxx.
        macMinVersion = '10.9'

        cflags.extend(('-isysroot {macSdkRoot}',
                       '-mmacosx-version-min={macMinVersion}',
                       '-DMACOSX_DEPLOYMENT_TARGET={macMinVersion}',
                       ))
        ldflags.extend(('-isysroot {macSdkRoot}',
                        '-Wl,-syslibroot,{macSdkRoot}',
                        '-mmacosx-version-min={macMinVersion}',
                        ))

        cflags = formatFlags(cflags, macSdkRoot=macSdkRoot,
                             macMinVersion=macMinVersion)
        ldflags = formatFlags(ldflags, macSdkRoot=macSdkRoot,
                              macMinVersion=macMinVersion)
        return cflags, ldflags

    # GCC toolchain flags for Linux and Windows
    if host_os == 'linux-x86':
        gccRoot = utils.android_path('prebuilts/gcc', utils.build_os_type(),
                                     'host/x86_64-linux-glibc2.17-4.8')
        gccTriple = 'x86_64-linux'
        gccVersion = '4.8.3'

        # gcc-toolchain is only needed for Linux
        cflags.append('--gcc-toolchain={gccRoot}')
    elif host_os == 'windows-x86':
        gccRoot = utils.android_path('prebuilts/gcc', utils.build_os_type(),
                                     'host/x86_64-w64-mingw32-4.8')
        gccTriple = 'x86_64-w64-mingw32'
        gccVersion = '4.8.3'

    cflags.append('-B{gccRoot}/{gccTriple}/bin')

    gccLibDir = '{gccRoot}/lib/gcc/{gccTriple}/{gccVersion}'
    gccBuiltinDir = '{gccRoot}/{gccTriple}/lib64'
    if is_32_bit:
        gccLibDir += '/32'
        gccBuiltinDir = gccBuiltinDir.replace('lib64', 'lib32')

    ldflags.extend(('-B' + gccLibDir,
                    '-L' + gccLibDir,
                    '-B' + gccBuiltinDir,
                    '-L' + gccBuiltinDir,
                    '-fuse-ld=lld',
                    ))

    cflags = formatFlags(cflags, gccRoot=gccRoot, gccTriple=gccTriple,
                         gccVersion=gccVersion)
    ldflags = formatFlags(ldflags, gccRoot=gccRoot, gccTriple=gccTriple,
                          gccVersion=gccVersion)
    return cflags, ldflags


def build_stage1(stage1_install, build_name, build_llvm_tools=False):
    # Build/install the stage 1 toolchain
    cflags, ldflags = host_gcc_toolchain_flags(utils.build_os_type())

    stage1_path = utils.out_path('stage1')
    stage1_targets = 'X86'

    stage1_extra_defines = dict()
    stage1_extra_defines['LLVM_BUILD_RUNTIME'] = 'ON'
    stage1_extra_defines['CLANG_ENABLE_ARCMT'] = 'OFF'
    stage1_extra_defines['CLANG_ENABLE_STATIC_ANALYZER'] = 'OFF'
    stage1_extra_defines['CMAKE_C_COMPILER'] = os.path.join(
        clang_prebuilt_bin_dir(), 'clang')
    stage1_extra_defines['CMAKE_CXX_COMPILER'] = os.path.join(
        clang_prebuilt_bin_dir(), 'clang++')
    stage1_extra_defines['LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD'] = 'OFF'
    stage1_extra_defines['LLVM_TOOL_OPENMP_BUILD'] = 'OFF'

    update_cmake_sysroot_flags(stage1_extra_defines, host_sysroot())

    if not utils.host_is_darwin():
        stage1_extra_defines['LLVM_ENABLE_LLD'] = 'ON'

    if build_llvm_tools:
        stage1_extra_defines['LLVM_BUILD_TOOLS'] = 'ON'
    else:
        stage1_extra_defines['LLVM_BUILD_TOOLS'] = 'OFF'

    # Have clang use libc++, ...
    stage1_extra_defines['LLVM_ENABLE_LIBCXX'] = 'ON'

    # ... and point CMake to the libc++.so from the prebuilts.  Install an rpath
    # to prevent linking with the newly-built libc++.so
    ldflags.append('-L' + clang_prebuilt_lib_dir())
    ldflags.append('-Wl,-rpath,' + clang_prebuilt_lib_dir())

    # Make libc++.so a symlink to libc++.so.x instead of a linker script that
    # also adds -lc++abi.  Statically link libc++abi to libc++ so it is not
    # necessary to pass -lc++abi explicitly.  This is needed only for Linux.
    if utils.host_is_linux():
        stage1_extra_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF'
        stage1_extra_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON'

    # Do not build compiler-rt for Darwin.  We don't ship host (or any
    # prebuilt) runtimes for Darwin anyway.  Attempting to build these will
    # fail compilation of lib/builtins/atomic_*.c that only get built for
    # Darwin and fail compilation due to us using the bionic version of
    # stdatomic.h.
    if utils.host_is_darwin():
        stage1_extra_defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON'

    # Don't build libfuzzer, since it's broken on Darwin and we don't need it
    # anyway.
    stage1_extra_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF'

    # Set the compiler and linker flags
    stage1_extra_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
    stage1_extra_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
    stage1_extra_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)

    stage1_extra_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags)
    stage1_extra_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags)
    stage1_extra_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags)

    stage1_extra_env = dict()
    if USE_GOMA_FOR_STAGE1:
        stage1_extra_env['USE_GOMA'] = 'true'

    build_llvm(
        targets=stage1_targets,
        build_dir=stage1_path,
        install_dir=stage1_install,
        build_name=build_name,
        extra_defines=stage1_extra_defines,
        extra_env=stage1_extra_env)


def build_stage2(stage1_install,
                 stage2_install,
                 stage2_targets,
                 build_name,
                 enable_assertions=False,
                 debug_build=False,
                 no_lto=False,
                 build_instrumented=False,
                 profdata_file=None):
    cflags, ldflags = host_gcc_toolchain_flags(utils.build_os_type())

    # Build/install the stage2 toolchain
    stage2_cc = os.path.join(stage1_install, 'bin', 'clang')
    stage2_cxx = os.path.join(stage1_install, 'bin', 'clang++')
    stage2_path = utils.out_path('stage2')

    stage2_extra_defines = dict()
    stage2_extra_defines['CMAKE_C_COMPILER'] = stage2_cc
    stage2_extra_defines['CMAKE_CXX_COMPILER'] = stage2_cxx
    stage2_extra_defines['LLVM_BUILD_RUNTIME'] = 'ON'
    stage2_extra_defines['LLVM_ENABLE_LIBCXX'] = 'ON'
    stage2_extra_defines['SANITIZER_ALLOW_CXXABI'] = 'OFF'
    stage2_extra_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE'

    update_cmake_sysroot_flags(stage2_extra_defines, host_sysroot())

    if not utils.host_is_darwin():
        stage2_extra_defines['LLVM_ENABLE_LLD'] = 'ON'

        # lld, lto and pgo instrumentation doesn't work together
        # http://b/79419131
        if not build_instrumented and not no_lto:
            stage2_extra_defines['LLVM_ENABLE_LTO'] = 'Thin'

    # Don't build libfuzzer, since it's broken on Darwin and we don't need it
    # anyway.
    stage2_extra_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF'

    if enable_assertions:
        stage2_extra_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON'

    if debug_build:
        stage2_extra_defines['CMAKE_BUILD_TYPE'] = 'Debug'

    if build_instrumented:
        stage2_extra_defines['LLVM_BUILD_INSTRUMENTED'] = 'ON'

        # llvm-profdata is only needed to finish CMake configuration
        # (tools/clang/utils/perf-training/CMakeLists.txt) and not needed for
        # build
        llvm_profdata = os.path.join(stage1_install, 'bin', 'llvm-profdata')
        stage2_extra_defines['LLVM_PROFDATA'] = llvm_profdata

        # Building libcxx, libcxxabi with instrumentation causes linker errors
        # because these are built with -nodefaultlibs and prevent libc symbols
        # needed by libclang_rt.profile from being resolved.  Manually adding
        # the libclang_rt.profile to linker flags fixes the issue.
        version = extract_clang_long_version(stage1_install)
        resource_dir = clang_resource_dir(version, '')
        ldflags.append(os.path.join(stage1_install, resource_dir,
                                    'libclang_rt.profile-x86_64.a'))

    if profdata_file:
        if build_instrumented:
            raise RuntimeError(
                'Cannot simultaneously instrument and use profiles')

        stage2_extra_defines['LLVM_PROFDATA_FILE'] = profdata_file
        cflags.append('-Wno-profile-instr-out-of-date')
        cflags.append('-Wno-profile-instr-unprofiled')

    # Make libc++.so a symlink to libc++.so.x instead of a linker script that
    # also adds -lc++abi.  Statically link libc++abi to libc++ so it is not
    # necessary to pass -lc++abi explicitly.  This is needed only for Linux.
    if utils.host_is_linux():
        stage2_extra_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON'
        stage2_extra_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF'

    # Do not build compiler-rt for Darwin.  We don't ship host (or any
    # prebuilt) runtimes for Darwin anyway.  Attempting to build these will
    # fail compilation of lib/builtins/atomic_*.c that only get built for
    # Darwin and fail compilation due to us using the bionic version of
    # stdatomic.h.
    if utils.host_is_darwin():
        stage2_extra_defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON'

    # Point CMake to the libc++ from stage1.  It is possible that once built,
    # the newly-built libc++ may override this because of the rpath pointing to
    # $ORIGIN/../lib64.  That'd be fine because both libraries are built from
    # the same sources.
    ldflags.append('-L' + os.path.join(stage1_install, 'lib64'))
    stage2_extra_env = dict()
    stage2_extra_env['LD_LIBRARY_PATH'] = os.path.join(stage1_install, 'lib64')

    # Set the compiler and linker flags
    stage2_extra_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags)
    stage2_extra_defines['CMAKE_C_FLAGS'] = ' '.join(cflags)
    stage2_extra_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags)

    stage2_extra_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags)
    stage2_extra_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags)
    stage2_extra_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags)

    build_llvm(
        targets=stage2_targets,
        build_dir=stage2_path,
        install_dir=stage2_install,
        build_name=build_name,
        extra_defines=stage2_extra_defines,
        extra_env=stage2_extra_env)


def build_runtimes(stage2_install):
    create_sysroots()
    version = extract_clang_version(stage2_install)
    build_crts(stage2_install, version)
    build_crts(stage2_install, version, ndk_cxx=True)
    build_crts_host_i686(stage2_install, version)
    build_libfuzzers(stage2_install, version)
    build_libfuzzers(stage2_install, version, ndk_cxx=True)
    build_libomp(stage2_install, version)
    build_libomp(stage2_install, version, ndk_cxx=True)
    # Bug: http://b/64037266. `strtod_l` is missing in NDK r15. This will break
    # libcxx build.
    # build_libcxx(stage2_install, version)
    build_asan_test(stage2_install)
    build_sanitizer_map_files(stage2_install, version)
    create_hwasan_symlink(stage2_install, version)

def install_wrappers(llvm_install_path):
    wrapper_path = utils.llvm_path('android', 'compiler_wrapper.py')
    bisect_path = utils.llvm_path('android', 'bisect_driver.py')
    bin_path = os.path.join(llvm_install_path, 'bin')
    clang_path = os.path.join(bin_path, 'clang')
    clangxx_path = os.path.join(bin_path, 'clang++')
    clang_tidy_path = os.path.join(bin_path, 'clang-tidy')

    # Rename clang and clang++ to clang.real and clang++.real.
    # clang and clang-tidy may already be moved by this script if we use a
    # prebuilt clang. So we only move them if clang.real and clang-tidy.real
    # doesn't exist.
    if not os.path.exists(clang_path + '.real'):
        shutil.move(clang_path, clang_path + '.real')
    if not os.path.exists(clang_tidy_path + '.real'):
        shutil.move(clang_tidy_path, clang_tidy_path + '.real')
    utils.remove(clang_path)
    utils.remove(clangxx_path)
    utils.remove(clang_tidy_path)
    utils.remove(clangxx_path + '.real')
    os.symlink('clang.real', clangxx_path + '.real')

    shutil.copy2(wrapper_path, clang_path)
    shutil.copy2(wrapper_path, clangxx_path)
    shutil.copy2(wrapper_path, clang_tidy_path)
    install_file(bisect_path, bin_path)


# Normalize host libraries (libLLVM, libclang, libc++, libc++abi) so that there
# is just one library, whose SONAME entry matches the actual name.
def normalize_llvm_host_libs(install_dir, host, version):
    if host == 'linux-x86':
        libs = {'libLLVM': 'libLLVM-{version}svn.so',
                'libclang': 'libclang.so.{version}svn',
                'libclang_cxx': 'libclang_cxx.so.{version}svn',
                'libc++': 'libc++.so.{version}',
                'libc++abi': 'libc++abi.so.{version}'
               }
    else:
        libs = {'libc++': 'libc++.{version}.dylib',
                'libc++abi': 'libc++abi.{version}.dylib'
               }

    def getVersions(libname):
        if not libname.startswith('libc++'):
            return version.short_version(), version.major
        else:
            return '1.0', '1'

    libdir = os.path.join(install_dir, 'lib64')
    for libname, libformat in libs.iteritems():
        short_version, major = getVersions(libname)

        soname_lib = os.path.join(libdir, libformat.format(version=major))
        if libname.startswith('libclang'):
            real_lib = soname_lib[:-3]
        else:
            real_lib = os.path.join(libdir, libformat.format(version=short_version))

        if libname not in ('libLLVM',):
            # Rename the library to match its SONAME
            if not os.path.isfile(real_lib):
                raise RuntimeError(real_lib + ' must be a regular file')
            if not os.path.islink(soname_lib):
                raise RuntimeError(soname_lib + ' must be a symlink')

            shutil.move(real_lib, soname_lib)

        # Retain only soname_lib and delete other files for this library.  We
        # still need libc++.so or libc++.dylib symlinks for a subsequent stage1
        # build using these prebuilts (where CMake tries to find C++ atomics
        # support) to succeed.
        libcxx_name = 'libc++.so' if host == 'linux-x86' else 'libc++.dylib'
        all_libs = [lib for lib in os.listdir(libdir) if
                    lib != libcxx_name and
                    (lib.startswith(libname + '.') or # so libc++abi is ignored
                     lib.startswith(libname + '-'))]

        for lib in all_libs:
            lib = os.path.join(libdir, lib)
            if lib != soname_lib:
                remove(lib)


def install_license_files(install_dir):
    projects = (
        'llvm',
        'llvm/projects/compiler-rt',
        'llvm/projects/libcxx',
        'llvm/projects/libcxxabi',
        'llvm/projects/openmp',
        'llvm/tools/clang',
        'llvm/tools/clang/tools/extra',
        'llvm/tools/lld',
    )

    # Get generic MODULE_LICENSE_* files from our android subdirectory.
    toolchain_path = utils.android_path('toolchain')
    llvm_android_path = os.path.join(toolchain_path, 'llvm', 'android')
    license_pattern = os.path.join(llvm_android_path, 'MODULE_LICENSE_*')
    for license_file in glob.glob(license_pattern):
        install_file(license_file, install_dir)

    # Fetch all the LICENSE.* files under our projects and append them into a
    # single NOTICE file for the resulting prebuilts.
    notices = []
    for project in projects:
        project_path = os.path.join(toolchain_path, project)
        license_pattern = os.path.join(project_path, 'LICENSE.*')
        for license_file in glob.glob(license_pattern):
            with open(license_file) as notice_file:
                notices.append(notice_file.read())
    with open(os.path.join(install_dir, 'NOTICE'), 'w') as notice_file:
        notice_file.write('\n'.join(notices))


def install_winpthreads(is_windows32, install_dir):
    """Installs the winpthreads runtime to the Windows bin directory."""
    lib_name = 'libwinpthread-1.dll'
    mingw_dir = utils.android_path(
        'prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8',
        'x86_64-w64-mingw32')
    # Yes, this indeed may be found in bin/ because the executables are the
    # 64-bit version by default.
    pthread_dir = 'lib32' if is_windows32 else 'bin'
    lib_path = os.path.join(mingw_dir, pthread_dir, lib_name)

    lib_install = os.path.join(install_dir, 'bin', lib_name)
    install_file(lib_path, lib_install)


def remove_static_libraries(static_lib_dir):
    if os.path.isdir(static_lib_dir):
        lib_files = os.listdir(static_lib_dir)
        for lib_file in lib_files:
            if lib_file.endswith('.a'):
                static_library = os.path.join(static_lib_dir, lib_file)
                remove(static_library)


def package_toolchain(build_dir, build_name, host, dist_dir, strip=True):
    is_windows32 = host == 'windows-x86'
    is_windows64 = host == 'windows-x86-64'
    is_windows = is_windows32 or is_windows64
    is_linux = host == 'linux-x86'
    package_name = 'clang-' + build_name
    install_host_dir = utils.out_path('install', host)
    install_dir = os.path.join(install_host_dir, package_name)
    version = extract_clang_version(build_dir)

    # Remove any previously installed toolchain so it doesn't pollute the
    # build.
    if os.path.exists(install_host_dir):
        shutil.rmtree(install_host_dir)

    # First copy over the entire set of output objects.
    shutil.copytree(build_dir, install_dir, symlinks=True)

    ext = '.exe' if is_windows else ''
    shlib_ext = '.dll' if is_windows else '.so' if is_linux else '.dylib'

    # Next, we remove unnecessary binaries.
    necessary_bin_files = [
        'clang' + ext,
        'clang++' + ext,
        'clang-' + version.major_version() + ext,
        'clang-check' + ext,
        'clang-format' + ext,
        'clang-tidy' + ext,
        'dsymutil' + ext,
        'git-clang-format',  # No extension here
        'ld.lld' + ext,
        'ld64.lld' + ext,
        'lld' + ext,
        'lld-link' + ext,
        'llvm-ar' + ext,
        'llvm-as' + ext,
        'llvm-cfi-verify' + ext,
        'llvm-config' + ext,
        'llvm-cov' + ext,
        'llvm-dis' + ext,
        'llvm-link' + ext,
        'llvm-modextract' + ext,
        'llvm-nm' + ext,
        'llvm-objcopy' + ext,
        'llvm-objdump' + ext,
        'llvm-profdata' + ext,
        'llvm-readobj' + ext,
        'llvm-strip' + ext,
        'llvm-symbolizer' + ext,
        'sancov' + ext,
        'sanstats' + ext,
        'scan-build' + ext,
        'scan-view' + ext,
        'LLVMgold' + shlib_ext,
    ]

    # scripts that should not be stripped
    script_bins = [
        'git-clang-format',
        'scan-build',
        'scan-view',
    ]

    bin_dir = os.path.join(install_dir, 'bin')
    bin_files = os.listdir(bin_dir)
    for bin_filename in bin_files:
        binary = os.path.join(bin_dir, bin_filename)
        if os.path.isfile(binary):
            if bin_filename not in necessary_bin_files:
                remove(binary)
            elif strip:
                if bin_filename not in script_bins:
                    check_call(['strip', binary])

    # Next, we remove unnecessary static libraries.
    if is_windows32:
        lib_dir = 'lib'
    else:
        lib_dir = 'lib64'
    remove_static_libraries(os.path.join(install_dir, lib_dir))

    # For Windows, add other relevant libraries.
    if is_windows:
        install_winpthreads(is_windows32, install_dir)

    if not is_windows:
        install_wrappers(install_dir)
        normalize_llvm_host_libs(install_dir, host, version)

    # Next, we copy over stdatomic.h from bionic.
    stdatomic_path = utils.android_path('bionic', 'libc', 'include',
                                        'stdatomic.h')
    resdir_top = os.path.join(install_dir, lib_dir, 'clang')
    header_path = os.path.join(resdir_top, version.long_version(), 'include')
    install_file(stdatomic_path, header_path)

    # Install license files as NOTICE in the toolchain install dir.
    install_license_files(install_dir)

    # Add an AndroidVersion.txt file.
    version_file_path = os.path.join(install_dir, 'AndroidVersion.txt')
    with open(version_file_path, 'w') as version_file:
        version_file.write('{}\n'.format(version.long_version()))
        version_file.write('based on {}\n'.format(android_version.svn_revision))

    # Package up the resulting trimmed install/ directory.
    tarball_name = package_name + '-' + host
    package_path = os.path.join(dist_dir, tarball_name) + '.tar.bz2'
    logger().info('Packaging %s', package_path)
    args = ['tar', '-cjC', install_host_dir, '-f', package_path, package_name]
    check_call(args)


def parse_args():
    known_platforms = ('linux', 'windows', 'windows-x86', 'windows-x86-64')
    known_platforms_str = ', '.join(known_platforms)

    # Simple argparse.Action to allow comma-separated values (e.g.
    # --option=val1,val2)
    class CommaSeparatedListAction(argparse.Action):
        def __call__(self, parser, namespace, values, option_string):
            for value in values.split(','):
                if value not in known_platforms:
                    error = '\'{}\' invalid.  Choose from {}'.format(
                                value, known_platforms)
                    raise argparse.ArgumentError(self, error)
            setattr(namespace, self.dest, values.split(','))


    """Parses and returns command line arguments."""
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '-v',
        '--verbose',
        action='count',
        default=0,
        help='Increase log level. Defaults to logging.INFO.')
    parser.add_argument(
        '--build-name', default='dev', help='Release name for the package.')

    parser.add_argument(
        '--enable-assertions',
        action='store_true',
        default=False,
        help='Enable assertions (only affects stage2)')

    parser.add_argument(
        '--no-lto',
        action='store_true',
        default=False,
        help='Disable LTO to speed up build (only affects stage2)')

    parser.add_argument(
        '--debug',
        action='store_true',
        default=False,
        help='Build debuggable Clang and LLVM tools (only affects stage2)')

    parser.add_argument(
        '--build-instrumented',
        action='store_true',
        default=False,
        help='Build LLVM tools with PGO instrumentation')

    # Options to skip build or packaging (can't skip both, or the script does
    # nothing).
    build_package_group = parser.add_mutually_exclusive_group()
    build_package_group.add_argument(
        '--skip-build',
        '-sb',
        action='store_true',
        default=False,
        help='Skip the build, and only do the packaging step')
    build_package_group.add_argument(
        '--skip-package',
        '-sp',
        action='store_true',
        default=False,
        help='Skip the packaging, and only do the build step')

    parser.add_argument(
        '--no-strip',
        action='store_true',
        default=False,
        help='Don\'t strip binaries/libraries')

    parser.add_argument(
        '--no-build',
        action=CommaSeparatedListAction,
        default=list(),
        help='Don\'t build toolchain for specified platforms.  Choices: ' + \
            known_platforms_str)

    parser.add_argument(
        '--check-pgo-profile',
        action='store_true',
        default=False,
        help='Fail if expected PGO profile doesn\'t exist')

    return parser.parse_args()


def main():
    args = parse_args()
    do_build = not args.skip_build
    do_package = not args.skip_package
    do_strip = not args.no_strip
    do_strip_host_package = do_strip and not args.debug

    need_host = utils.host_is_darwin() or ('linux' not in args.no_build)
    need_windows_32 = utils.host_is_linux() and \
        ('windows' not in args.no_build) and \
        ('windows-x86' not in args.no_build)
    need_windows_64 = utils.host_is_linux() and \
        ('windows' not in args.no_build) and \
        ('windows-x86-64' not in args.no_build)

    log_levels = [logging.INFO, logging.DEBUG]
    verbosity = min(args.verbose, len(log_levels) - 1)
    log_level = log_levels[verbosity]
    logging.basicConfig(level=log_level)

    stage1_install = utils.out_path('stage1-install')
    stage2_install = utils.out_path('stage2-install')
    windows32_install = utils.out_path('windows-x86-install')
    windows64_install = utils.out_path('windows-x86-64-install')

    # Build the stage1 Clang for the build host
    instrumented = utils.host_is_linux() and args.build_instrumented
    build_stage1(stage1_install, args.build_name,
                 build_llvm_tools=instrumented)

    if do_build and need_host:
        if os.path.exists(stage2_install):
            utils.rm_tree(stage2_install)

        profdata_filename = pgo_profdata_filename()
        profdata = pgo_profdata_file(profdata_filename)
        # Do not use PGO profiles if profdata file doesn't exist unless failure
        # is explicitly requested via --check-pgo-profile.
        if profdata is None and args.check_pgo_profile:
            raise RuntimeError('Profdata file does not exist for ' +
                               profdata_filename)

        build_stage2(stage1_install, stage2_install, STAGE2_TARGETS,
                     args.build_name, args.enable_assertions,
                     args.debug, args.no_lto, instrumented, profdata)

        if utils.host_is_linux():
            build_runtimes(stage2_install)

    if do_build and need_windows_32:
        if os.path.exists(windows32_install):
            utils.rm_tree(windows32_install)

        windows32_path = utils.out_path('windows-x86')
        build_llvm_for_windows(
            stage1_install=stage1_install,
            targets=STAGE2_TARGETS,
            enable_assertions=args.enable_assertions,
            build_dir=windows32_path,
            install_dir=windows32_install,
            build_name=args.build_name,
            is_32_bit=True)

    if do_build and need_windows_64:
        if os.path.exists(windows64_install):
            utils.rm_tree(windows64_install)

        windows64_path = utils.out_path('windows-x86-64')
        build_llvm_for_windows(
            stage1_install=stage1_install,
            targets=STAGE2_TARGETS,
            enable_assertions=args.enable_assertions,
            build_dir=windows64_path,
            install_dir=windows64_install,
            build_name=args.build_name)

    dist_dir = ORIG_ENV.get('DIST_DIR', utils.out_path())
    if do_package and need_host:
        package_toolchain(
            stage2_install,
            args.build_name,
            utils.build_os_type(),
            dist_dir,
            strip=do_strip_host_package)

    if do_package and need_windows_32:
        package_toolchain(
            windows32_install,
            args.build_name,
            'windows-x86',
            dist_dir,
            strip=do_strip)

    if do_package and need_windows_64:
        package_toolchain(
            windows64_install,
            args.build_name,
            'windows-x86-64',
            dist_dir,
            strip=do_strip)

    return 0


if __name__ == '__main__':
    main()
