Ejemplo n.º 1
0
def setup_sources(source_dir, build_llvm_next):
    """Setup toolchain sources into source_dir.

    Copy toolchain/llvm-project into source_dir.
    Apply patches per the specification in
    toolchain/llvm_android/patches/PATCHES.json.  The function overwrites
    source_dir only if necessary to avoid recompiles during incremental builds.
    """

    copy_from = utils.android_path('toolchain', 'llvm-project')

    # Copy llvm source tree to a temporary directory.
    tmp_source_dir = source_dir.rstrip('/') + '.tmp'
    if os.path.exists(tmp_source_dir):
        utils.rm_tree(tmp_source_dir)

    # mkdir parent of tmp_source_dir if necessary - so we can call 'cp' below.
    tmp_source_parent = os.path.dirname(tmp_source_dir)
    if not os.path.exists(tmp_source_parent):
        os.makedirs(tmp_source_parent)

    # Use 'cp' instead of shutil.copytree.  The latter uses copystat and retains
    # timestamps from the source.  We instead use rsync below to only update
    # changed files into source_dir.  Using 'cp' will ensure all changed files
    # get a newer timestamp than files in $source_dir.
    # Note: Darwin builds don't copy symlinks with -r.  Use -R instead.
    subprocess.check_call(['cp', '-Rf', copy_from, tmp_source_dir])

    # patch source tree
    patch_dir = utils.android_path('toolchain', 'llvm_android', 'patches')
    patch_json = os.path.join(patch_dir, 'PATCHES.json')
    svn_version = android_version.get_svn_revision(build_llvm_next)
    # strip the leading 'r' and letter suffix, e.g., r377782b => 377782
    svn_version = svn_version[1:].rstrip(string.ascii_lowercase)

    apply_patches(tmp_source_dir, svn_version, patch_json, patch_dir)

    # Copy tmp_source_dir to source_dir if they are different.  This avoids
    # invalidating prior build outputs.
    if not os.path.exists(source_dir):
        os.rename(tmp_source_dir, source_dir)
    else:
        # Without a trailing '/' in $SRC, rsync copies $SRC to
        # $DST/BASENAME($SRC) instead of $DST.
        tmp_source_dir = tmp_source_dir.rstrip('/') + '/'

        # rsync to update only changed files.  Use '-c' to use checksums to find
        # if files have changed instead of only modification time and size -
        # which could have inconsistencies.  Use '--delete' to ensure files not
        # in tmp_source_dir are deleted from $source_dir.
        subprocess.check_call([
            'rsync', '-r', '--delete', '--links', '-c', tmp_source_dir,
            source_dir
        ])

        utils.rm_tree(tmp_source_dir)
Ejemplo n.º 2
0
def build_llvm_for_windows(enable_assertions: bool, build_name: str,
                           build_lldb: bool,
                           swig_builder: Optional[builders.SwigBuilder]):
    config_list: List[configs.Config]
    if win_sdk.is_enabled():
        config_list = [configs.MSVCConfig()]
    else:
        config_list = [configs.MinGWConfig()]

    win_builder = builders.WindowsToolchainBuilder(config_list)
    if win_builder.install_dir.exists():
        shutil.rmtree(win_builder.install_dir)

    if not win_sdk.is_enabled():
        # Build and install libcxxabi and libcxx and use them to build Clang.
        libcxx_builder = builders.LibCxxBuilder(config_list)
        libcxxabi_builder = builders.LibCxxAbiBuilder(config_list)
        libcxxabi_builder.enable_assertions = enable_assertions
        libcxxabi_builder.build()

        libcxx_builder.libcxx_abi_path = libcxxabi_builder.install_dir
        libcxx_builder.enable_assertions = enable_assertions
        libcxx_builder.build()
        win_builder.libcxx_path = libcxx_builder.install_dir

    lldb_bins: Set[str] = set()
    libxml2_builder = builders.LibXml2Builder(config_list)
    libxml2_builder.build()
    win_builder.libxml2 = libxml2_builder
    for lib in libxml2_builder.install_libraries:
        lldb_bins.add(lib.name)

    win_builder.build_lldb = build_lldb
    if build_lldb:
        assert swig_builder is not None
        win_builder.libedit = None
        win_builder.swig_executable = swig_builder.install_dir / 'bin' / 'swig'

        xz_builder = builders.XzBuilder(config_list)
        xz_builder.build()
        win_builder.liblzma = xz_builder

        lldb_bins.add('liblldb.dll')

    win_builder.build_name = build_name
    win_builder.svn_revision = android_version.get_svn_revision()
    win_builder.enable_assertions = enable_assertions
    win_builder.build()

    return (win_builder, lldb_bins)
Ejemplo n.º 3
0
def build_llvm() -> builders.Stage2Builder:
    stage2 = builders.Stage2Builder()
    stage2.toolchain_name = 'prebuilt'
    stage2.build_name = 'stage2'
    stage2.svn_revision = android_version.get_svn_revision()

    # Differences from production toolchain:
    #   - sources are built directly from toolchain/llvm-project
    #   - built from prebuilt instead of a stage1 toolchain.
    #   - assertions enabled since some code is enabled only with assertions.
    #   - LTO is unnecessary.
    #   - skip lldb since it depends on several other libraries.
    #   - extra targets so we get cross-references for more sources.
    stage2.src_dir = paths.TOOLCHAIN_LLVM_PATH / 'llvm'
    stage2.enable_assertions = True
    stage2.lto = False
    stage2.build_lldb = False
    stage2.ninja_targets = ['all', 'UnitTests']
    stage2.build()
    return stage2
Ejemplo n.º 4
0
def build_llvm_for_windows(enable_assertions,
                           build_name):
    win_builder = builders.WindowsToolchainBuilder()
    if win_builder.install_dir.exists():
        shutil.rmtree(win_builder.install_dir)

    # Build and install libcxxabi and libcxx and use them to build Clang.
    libcxxabi_builder = builders.LibCxxAbiBuilder()
    libcxxabi_builder.enable_assertions = enable_assertions
    libcxxabi_builder.build()

    libcxx_builder = builders.LibCxxBuilder()
    libcxx_builder.enable_assertions = enable_assertions
    libcxx_builder.build()

    win_builder.build_name = build_name
    win_builder.svn_revision = android_version.get_svn_revision(BUILD_LLVM_NEXT)
    win_builder.build_lldb = BUILD_LLDB
    win_builder.enable_assertions = enable_assertions
    win_builder.build()

    return win_builder.install_dir
Ejemplo n.º 5
0
import os
import string
import subprocess

import android_version
import hosts
import utils
import source_manager

_LLVM_ANDROID_PATH = utils.android_path('toolchain', 'llvm_android')
_PATCH_DIR = os.path.join(_LLVM_ANDROID_PATH, 'patches')
_PATCH_JSON = os.path.join(_PATCH_DIR, 'PATCHES.json')

# strip the leading 'r' and letter suffix, e.g., r377782b => 377782
_SVN_REVISION = (android_version.get_svn_revision()[1:].rstrip(
    string.ascii_lowercase))


def get_removed_patches(output):
    """Parse the list of removed patches from patch_manager.py's output.
    """
    marker = 'removed from the patch metadata file:\n'
    marker_start = output.find(marker)
    if marker_start == -1:
        return None
    removed = output[marker_start + len(marker):].splitlines()
    return [p.strip() for p in removed]


def trim_patches_json():
    """Invoke patch_manager.py with failure_mode=remove_patches
Ejemplo n.º 6
0
def main():
    args = parse_args()
    if args.skip_build:
        # Skips all builds
        BuilderRegistry.add_filter(lambda name: False)
    elif args.skip:
        BuilderRegistry.add_skips(args.skip)
    elif args.build:
        BuilderRegistry.add_builds(args.build)
    do_runtimes = not args.skip_runtimes
    do_package = not args.skip_package
    do_strip = not args.no_strip
    do_strip_host_package = do_strip and not args.debug and not args.build_llvm_next
    build_lldb = 'lldb' not in args.no_build

    android_version.set_llvm_next(args.build_llvm_next)

    need_host = hosts.build_host().is_darwin or ('linux' not in args.no_build)
    need_windows = hosts.build_host().is_linux and ('windows'
                                                    not in args.no_build)

    logging.basicConfig(level=logging.DEBUG)

    logger().info(
        'do_build=%r do_stage1=%r do_stage2=%r do_runtimes=%r do_package=%r need_windows=%r'
        % (not args.skip_build, BuilderRegistry.should_build('stage1'),
           BuilderRegistry.should_build('stage2'), do_runtimes, do_package,
           need_windows))

    # Clone sources to be built and apply patches.
    if not args.skip_source_setup:
        source_manager.setup_sources(source_dir=paths.LLVM_PATH)

    # Build the stage1 Clang for the build host
    instrumented = hosts.build_host().is_linux and args.build_instrumented

    stage1 = builders.Stage1Builder()
    stage1.build_name = 'stage1'
    stage1.svn_revision = android_version.get_svn_revision()
    # Build lldb for lldb-tblgen. It will be used to build lldb-server and windows lldb.
    stage1.build_lldb = build_lldb
    stage1.build_android_targets = args.debug or instrumented
    stage1.build()
    set_default_toolchain(stage1.installed_toolchain)

    if build_lldb:
        # Swig is needed for both host and windows lldb.
        swig_builder = builders.SwigBuilder()
        swig_builder.build()
    else:
        swig_builder = None

    if need_host:
        if not args.no_pgo:
            profdata = extract_profdata()
        else:
            profdata = None

        stage2 = builders.Stage2Builder()
        stage2.build_name = args.build_name
        stage2.svn_revision = android_version.get_svn_revision()
        stage2.debug_build = args.debug
        stage2.enable_assertions = args.enable_assertions
        stage2.lto = not args.no_lto
        stage2.build_instrumented = instrumented
        stage2.profdata_file = profdata if profdata else None

        libxml2_builder = builders.LibXml2Builder()
        libxml2_builder.build()
        stage2.libxml2 = libxml2_builder

        stage2.build_lldb = build_lldb
        if build_lldb:
            stage2.swig_executable = swig_builder.install_dir / 'bin' / 'swig'

            xz_builder = builders.XzBuilder()
            xz_builder.build()
            stage2.liblzma = xz_builder

            libncurses = builders.LibNcursesBuilder()
            libncurses.build()
            stage2.libncurses = libncurses

            libedit_builder = builders.LibEditBuilder()
            libedit_builder.libncurses = libncurses
            libedit_builder.build()
            stage2.libedit = libedit_builder

        stage2_tags = []
        # Annotate the version string if there is no profdata.
        if profdata is None:
            stage2_tags.append('NO PGO PROFILE')
        # Annotate the version string if this is an llvm-next build.
        if args.build_llvm_next:
            stage2_tags.append('ANDROID_LLVM_NEXT')
        stage2.build_tags = stage2_tags

        stage2.build()
        if not (stage2.build_instrumented or stage2.debug_build):
            set_default_toolchain(stage2.installed_toolchain)

        Builder.output_toolchain = stage2.installed_toolchain
        if hosts.build_host().is_linux and do_runtimes:
            build_runtimes(build_lldb_server=build_lldb)

    if need_windows:
        if args.windows_sdk:
            win_sdk.set_path(Path(args.windows_sdk))
        win_builder, win_lldb_bins = build_llvm_for_windows(
            enable_assertions=args.enable_assertions,
            build_name=args.build_name,
            build_lldb=build_lldb,
            swig_builder=swig_builder)

    if do_package and need_host:
        package_toolchain(stage2,
                          strip=do_strip_host_package,
                          create_tar=args.create_tar,
                          llvm_next=args.build_llvm_next)

    if do_package and need_windows:
        package_toolchain(win_builder,
                          necessary_bin_files=win_lldb_bins,
                          strip=do_strip,
                          create_tar=args.create_tar)

    return 0
Ejemplo n.º 7
0
def package_toolchain(toolchain_builder: LLVMBuilder,
                      necessary_bin_files: Optional[Set[str]] = None,
                      strip=True,
                      create_tar=True,
                      llvm_next=False):
    dist_dir = Path(utils.ORIG_ENV.get('DIST_DIR', paths.OUT_DIR))
    build_dir = toolchain_builder.install_dir
    host = toolchain_builder.config_list[0].target_os
    build_name = toolchain_builder.build_name
    version = toolchain_builder.installed_toolchain.version

    package_name = 'clang-' + build_name

    install_dir = paths.get_package_install_path(host, package_name)
    install_host_dir = install_dir.parent

    # Remove any previously installed toolchain so it doesn't pollute the
    # build.
    if install_host_dir.exists():
        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 host.is_windows else ''
    script_ext = '.cmd' if host.is_windows else '.sh'
    shlib_ext = '.dll' if host.is_windows else '.so' if host.is_linux else '.dylib'

    if not necessary_bin_files:
        necessary_bin_files = set()

    # Next, we remove unnecessary binaries.
    necessary_bin_files |= {
        'clang' + ext,
        'clang++' + ext,
        'clang-' + version.major_version() + ext,
        'clang-check' + ext,
        'clang-cl' + ext,
        'clang-format' + ext,
        'clang-tidy' + ext,
        'clangd' + ext,
        'dsymutil' + ext,
        'git-clang-format',  # No extension here
        'ld.lld' + ext,
        'ld64.lld' + ext,
        'lld' + ext,
        'lld-link' + ext,
        'llvm-addr2line' + ext,
        'llvm-ar' + ext,
        'llvm-as' + ext,
        'llvm-cfi-verify' + ext,
        'llvm-config' + ext,
        'llvm-cov' + ext,
        'llvm-cxxfilt' + ext,
        'llvm-dis' + ext,
        'llvm-dwarfdump' + ext,
        'llvm-dwp' + ext,
        'llvm-lib' + ext,
        'llvm-link' + ext,
        'llvm-lipo' + ext,
        'llvm-modextract' + ext,
        'llvm-nm' + ext,
        'llvm-objcopy' + ext,
        'llvm-objdump' + ext,
        'llvm-profdata' + ext,
        'llvm-ranlib' + ext,
        'llvm-rc' + ext,
        'llvm-readelf' + ext,
        'llvm-readobj' + ext,
        'llvm-size' + ext,
        'llvm-strings' + ext,
        'llvm-strip' + ext,
        'llvm-symbolizer' + ext,
        'sancov' + ext,
        'sanstats' + ext,
        'scan-build' + ext,
        'scan-view' + ext,
    }

    if toolchain_builder.build_lldb:
        necessary_bin_files.update({
            'lldb-argdumper' + ext,
            'lldb' + ext,
            'lldb' + script_ext,
        })

    if host.is_windows:
        windows_exclude_bin_files = {
            'clang-' + version.major_version() + ext,
            'clangd' + ext,
            'scan-build' + ext,
            'scan-view' + ext,
        }
        necessary_bin_files -= windows_exclude_bin_files

    # scripts that should not be stripped
    script_bins = {
        'git-clang-format',
        'scan-build',
        'scan-view',
        'lldb' + script_ext,
    }

    bin_dir = install_dir / 'bin'
    lib_dir = install_dir / 'lib64'
    strip_cmd = Builder.toolchain.strip

    for binary in bin_dir.iterdir():
        if binary.is_file():
            if binary.name not in necessary_bin_files:
                binary.unlink()
            elif binary.is_symlink():
                continue
            elif strip and binary.name not in script_bins:
                # Strip all non-global symbols and debug info.
                # These specific flags prevent Darwin executables from being
                # stripped of additional global symbols that might be used
                # by plugins.
                utils.check_call([strip_cmd, '-S', '-x', binary])
                # Strip mutates binary, need to codesign the binary again.
                if host.is_darwin:
                    darwin_codesign(binary)

    # FIXME: check that all libs under lib64/clang/<version>/ are created.
    for necessary_bin_file in necessary_bin_files:
        if not (bin_dir / necessary_bin_file).is_file():
            raise RuntimeError(
                f'Did not find {necessary_bin_file} in {bin_dir}')

    necessary_lib_files = set()
    if not (host.is_windows and win_sdk.is_enabled()):
        necessary_lib_files |= {
            'libc++.a',
            'libc++abi.a',
        }

    if host.is_windows:
        necessary_lib_files.add('LLVMgold' + shlib_ext)

    if host.is_windows and not win_sdk.is_enabled():
        necessary_lib_files.add('libwinpthread-1' + shlib_ext)
        # For Windows, add other relevant libraries.
        install_winpthreads(bin_dir, lib_dir)

    # Remove unnecessary static libraries.
    remove_static_libraries(lib_dir, necessary_lib_files)

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

    # Check necessary lib files exist.
    for necessary_lib_file in necessary_lib_files:
        if not (lib_dir / necessary_lib_file).is_file():
            raise RuntimeError(
                f'Did not find {necessary_lib_file} in {lib_dir}')

    # Next, we copy over stdatomic.h and bits/stdatomic.h from bionic.
    libc_include_path = paths.ANDROID_DIR / 'bionic' / 'libc' / 'include'
    header_path = lib_dir / 'clang' / version.long_version() / 'include'

    shutil.copy2(libc_include_path / 'stdatomic.h', header_path)

    bits_install_path = header_path / 'bits'
    bits_install_path.mkdir(parents=True, exist_ok=True)
    bits_stdatomic_path = libc_include_path / 'bits' / 'stdatomic.h'
    shutil.copy2(bits_stdatomic_path, bits_install_path)

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

    # Add an AndroidVersion.txt file.
    version_file_path = install_dir / 'AndroidVersion.txt'
    with version_file_path.open('w') as version_file:
        version_file.write(f'{version.long_version()}\n')
        svn_revision = android_version.get_svn_revision()
        version_file.write(f'based on {svn_revision}\n')

    # Create RBE input files.
    if host.is_linux:
        with (install_dir / 'bin' /
              'remote_toolchain_inputs').open('w') as inputs_file:
            dependencies = (
                'clang\n'
                'clang++\n'
                'clang.real\n'
                'clang++.real\n'
                'clang-tidy\n'
                'clang-tidy.real\n'
                '../lib64/libc++.so.1\n'
                'lld\n'
                'ld64.lld\n'
                'ld.lld\n'
                f'../lib64/clang/{version.long_version()}/share\n'
                f'../lib64/clang/{version.long_version()}/lib/linux\n'
                f'../lib64/clang/{version.long_version()}/include\n'
                f'../lib64/libxml2.so.{builders.LibXml2Builder.lib_version}\n')
            inputs_file.write(dependencies)

    # Package up the resulting trimmed install/ directory.
    if create_tar:
        tarball_name = package_name + '-' + host.os_tag + '.tar.bz2'
        package_path = dist_dir / tarball_name
        logger().info(f'Packaging {package_path}')
        args = [
            'tar', '-cjC', install_host_dir, '-f', package_path, package_name
        ]
        utils.check_call(args)
Ejemplo n.º 8
0
def pgo_profdata_filename():
    svn_revision = android_version.get_svn_revision(BUILD_LLVM_NEXT)
    base_revision = svn_revision.rstrip(string.ascii_lowercase)
    return '%s.profdata' % base_revision
Ejemplo n.º 9
0
def package_toolchain(build_dir, build_name, host: hosts.Host, dist_dir, strip=True, create_tar=True):
    package_name = 'clang-' + build_name
    version = extract_clang_version(build_dir)

    install_dir = get_package_install_path(host, package_name)
    install_host_dir = os.path.realpath(os.path.join(install_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 host.is_windows else ''
    shlib_ext = '.dll' if host.is_windows else '.so' if host.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-cl' + 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-addr2line' + ext,
        'llvm-ar' + ext,
        'llvm-as' + ext,
        'llvm-cfi-verify' + ext,
        'llvm-config' + ext,
        'llvm-cov' + ext,
        'llvm-dis' + ext,
        'llvm-dwarfdump' + ext,
        'llvm-lib' + ext,
        'llvm-link' + ext,
        'llvm-modextract' + ext,
        'llvm-nm' + ext,
        'llvm-objcopy' + ext,
        'llvm-objdump' + ext,
        'llvm-profdata' + ext,
        'llvm-ranlib' + ext,
        'llvm-rc' + ext,
        'llvm-readelf' + ext,
        'llvm-readobj' + ext,
        'llvm-size' + ext,
        'llvm-strings' + ext,
        'llvm-strip' + ext,
        'llvm-symbolizer' + ext,
        'sancov' + ext,
        'sanstats' + ext,
        'scan-build' + ext,
        'scan-view' + ext,
    }

    if BUILD_LLDB:
        necessary_bin_files.update({
            'lldb-argdumper' + ext,
            'lldb' + ext,
        })

    if host.is_windows:
        windows_blacklist_bin_files = {
            'clang-' + version.major_version() + ext,
            'scan-build' + ext,
            'scan-view' + ext,
        }
        necessary_bin_files -= windows_blacklist_bin_files

    if BUILD_LLDB:
        install_lldb_deps(Path(install_dir), host)
        if host.is_windows:
            windows_additional_bin_files = {
                'liblldb' + shlib_ext,
                'python38' + shlib_ext
            }
            necessary_bin_files |= windows_additional_bin_files

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

    bin_dir = os.path.join(install_dir, 'bin')
    lib_dir = os.path.join(install_dir, 'lib64')
    strip_cmd = toolchains.get_runtime_toolchain().strip

    for bin_filename in os.listdir(bin_dir):
        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 and bin_filename not in script_bins:
                # Strip all non-global symbols and debug info.
                # These specific flags prevent Darwin executables from being
                # stripped of additional global symbols that might be used
                # by plugins.
                utils.check_call([strip_cmd, '-S', '-x', binary])

    # FIXME: check that all libs under lib64/clang/<version>/ are created.
    for necessary_bin_file in necessary_bin_files:
        if not os.path.isfile(os.path.join(bin_dir, necessary_bin_file)):
            raise RuntimeError('Did not find %s in %s' % (necessary_bin_file, bin_dir))

    necessary_lib_files = {
        'libc++.a',
        'libc++abi.a',
    }

    if host.is_windows:
        necessary_lib_files |= {
            'LLVMgold' + shlib_ext,
            'libwinpthread-1' + shlib_ext,
        }
        # For Windows, add other relevant libraries.
        install_winpthreads(bin_dir, lib_dir)

    # Remove unnecessary static libraries.
    remove_static_libraries(lib_dir, necessary_lib_files)

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

    # Check necessary lib files exist.
    for necessary_lib_file in necessary_lib_files:
        if not os.path.isfile(os.path.join(lib_dir, necessary_lib_file)):
            raise RuntimeError('Did not find %s in %s' % (necessary_lib_file, lib_dir))

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

    stdatomic_path = utils.android_path(libc_include_path, 'stdatomic.h')
    install_file(stdatomic_path, header_path)

    bits_install_path = os.path.join(header_path, 'bits')
    if not os.path.isdir(bits_install_path):
        os.mkdir(bits_install_path)
    bits_stdatomic_path = utils.android_path(libc_include_path, 'bits', 'stdatomic.h')
    install_file(bits_stdatomic_path, bits_install_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()))
        svn_revision = android_version.get_svn_revision(BUILD_LLVM_NEXT)
        version_file.write('based on {}\n'.format(svn_revision))

    # Create RBE input files.
    if host.is_linux:
        with open(os.path.join(install_dir, 'bin', 'remote_toolchain_inputs'), 'w') as inputs_file:
            dependencies = ('clang\n'
                            'clang++\n'
                            'clang.real\n'
                            'clang++.real\n'
                            'clang-tidy\n'
                            'clang-tidy.real\n'
                            '../lib64/libc++.so.1\n'
                            'lld\n'
                            'ld64.lld\n'
                            'ld.lld\n'
                           )
            blacklist_dir = os.path.join('../', 'lib64', 'clang', version.long_version(), 'share\n')
            libs_dir = os.path.join('../', 'lib64', 'clang', version.long_version(), 'lib', 'linux\n')
            dependencies += (blacklist_dir + libs_dir)
            inputs_file.write(dependencies)

    # Package up the resulting trimmed install/ directory.
    if create_tar:
        tarball_name = package_name + '-' + host.os_tag
        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]
        utils.check_call(args)
Ejemplo n.º 10
0
def main():
    args = parse_args()
    if args.skip_build:
        # Skips all builds
        BuilderRegistry.add_filter(lambda name: False)
    elif args.skip:
        BuilderRegistry.add_skips(args.skip)
    elif args.build:
        BuilderRegistry.add_builds(args.build)
    do_runtimes = not args.skip_runtimes
    do_package = not args.skip_package
    do_strip = not args.no_strip
    do_strip_host_package = do_strip and not args.debug

    # TODO (Pirama): Avoid using global statement
    global BUILD_LLDB, BUILD_LLVM_NEXT
    BUILD_LLDB = 'lldb' not in args.no_build
    BUILD_LLVM_NEXT = args.build_llvm_next

    need_host = hosts.build_host().is_darwin or ('linux' not in args.no_build)
    need_windows = hosts.build_host().is_linux and ('windows' 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)

    logger().info('do_build=%r do_stage1=%r do_stage2=%r do_runtimes=%r do_package=%r need_windows=%r' %
                  (not args.skip_build, BuilderRegistry.should_build('stage1'), BuilderRegistry.should_build('stage2'),
                  do_runtimes, do_package, need_windows))

    # Clone sources to be built and apply patches.
    source_manager.setup_sources(source_dir=utils.llvm_path(),
                                 build_llvm_next=args.build_llvm_next)

    # Build the stage1 Clang for the build host
    instrumented = hosts.build_host().is_linux and args.build_instrumented

    # Windows libs are built with stage1 toolchain. llvm-config is required.
    stage1_build_llvm_tools = instrumented or \
                              need_windows or \
                              args.debug

    stage1 = builders.Stage1Builder()
    stage1.build_name = args.build_name
    stage1.svn_revision = android_version.get_svn_revision(BUILD_LLVM_NEXT)
    stage1.build_llvm_tools = stage1_build_llvm_tools
    stage1.build_android_targets = args.debug or instrumented
    stage1.use_goma_for_stage1 = USE_GOMA_FOR_STAGE1
    stage1.build()
    stage1_toolchain = toolchains.get_toolchain_from_builder(stage1)
    toolchains.set_runtime_toolchain(stage1_toolchain)
    stage1_install = str(stage1.install_dir)

    if BUILD_LLDB:
        builders.SwigBuilder().build()
        if BuilderRegistry.should_build('stage2'):
            # libedit is not needed for windows lldb.
            builders.LibEditBuilder().build()

    if need_host:
        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)

        stage2 = builders.Stage2Builder()
        stage2.build_name = args.build_name
        stage2.svn_revision = android_version.get_svn_revision(BUILD_LLVM_NEXT)
        stage2.build_lldb = BUILD_LLDB
        stage2.debug_build = args.debug
        stage2.enable_assertions = args.enable_assertions
        stage2.lto = not args.no_lto
        stage2.build_instrumented = instrumented
        stage2.profdata_file = Path(profdata) if profdata else None

        # Annotate the version string if there is no profdata.
        if profdata is None:
            stage2.build_name += ', NO PGO PROFILE, '

        stage2.build()
        if not (stage2.build_instrumented or stage2.debug_build):
            stage2_toolchain = toolchains.get_toolchain_from_builder(stage2)
            toolchains.set_runtime_toolchain(stage2_toolchain)
        stage2_install = str(stage2.install_dir)

        if hosts.build_host().is_linux and do_runtimes:
            runtimes_toolchain = stage2_install
            if args.debug or instrumented:
                runtimes_toolchain = stage1_install
            build_runtimes(runtimes_toolchain, args)

    if need_windows:
        windows64_install = build_llvm_for_windows(
            enable_assertions=args.enable_assertions,
            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,
            hosts.build_host(),
            dist_dir,
            strip=do_strip_host_package)

    if do_package and need_windows:
        package_toolchain(
            windows64_install,
            args.build_name,
            hosts.Host.Windows,
            dist_dir,
            strip=do_strip)

    return 0