예제 #1
0
    def mergeProfiles(self):
        stage1_install = utils.out_path('stage1-install')
        profdata = os.path.join(stage1_install, 'bin', 'llvm-profdata')

        profdata_file = build.pgo_profdata_filename()

        dist_dir = os.environ.get('DIST_DIR', utils.out_path())
        out_file = os.path.join(dist_dir, profdata_file)

        cmd = [profdata, 'merge', '-o', out_file, self.profiles_dir]
        subprocess.check_call(cmd)
예제 #2
0
def extract_packaged_clang(package_path):
    # Find package to extract
    tarballs = [f for f in os.listdir(package_path) if \
                    f.endswith('.tar.bz2') and 'linux' in f]
    if len(tarballs) != 1:
        raise RuntimeError('No clang packages (.tar.bz2) found in ' +
                           package_path)

    tarball = os.path.join(package_path, tarballs[0])

    # Extract package to $OUT_DIR/extracted
    extract_dir = utils.out_path('extracted')
    if os.path.exists(extract_dir):
        utils.rm_tree(extract_dir)
    build.check_create_path(extract_dir)

    args = ['tar', '-xjC', extract_dir, '-f', tarball]
    subprocess.check_call(args)

    # Find and return a singleton subdir
    extracted = os.listdir(extract_dir)
    if len(extracted) != 1:
        raise RuntimeError('Expected one file from package.  Found: ' +
                           ' '.join(extracted))

    clang_path = os.path.join(extract_dir, extracted[0])
    if not os.path.isdir(clang_path):
        raise RuntimeError('Extracted path is not a dir: ' + clang_path)

    return clang_path
예제 #3
0
def build_libcxxabi(toolchain: toolchains.Toolchain, build_arch: hosts.Arch) -> Path:
    # 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(toolchain.path, platform=True): # pylint: disable=not-an-iterable

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

        logger().info('Building libcxxabi for %s', arch.value)
        defines['LIBCXXABI_LIBCXX_INCLUDES'] = utils.llvm_path('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.value)
        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.llvm_path('libcxxabi'),
                     install=False)
        return Path(out_path)
    raise ValueError(f"{build_arch} is not supported.")
예제 #4
0
def build_libcxx(toolchain, clang_version):
    for (arch, llvm_triple, libcxx_defines,
         cflags) in cross_compile_configs(toolchain): # pylint: disable=not-an-iterable
        logger().info('Building libcxx for %s', arch.value)
        libcxx_path = utils.out_path('lib', 'libcxx-' + arch.value)

        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('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(),
                                            hosts.Arch.from_triple(llvm_triple))
        libcxx_install = os.path.join(toolchain, 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)
예제 #5
0
def build_clang(instrumented=False, pgo=True):
    stage2_install = utils.out_path('stage2-install')

    # Clone sources to build the current version, with patches.
    source_manager.setup_sources(source_dir=utils.llvm_path(),
                                 build_llvm_next=False)

    # LLVM tool llvm-profdata from stage1 is needed to merge the collected
    # profiles.  Build all LLVM tools if building instrumented stage2
    stage1 = builders.Stage1Builder()
    stage1.build_name = 'dev'
    stage1.svn_revision = 'dev'
    stage1.build_llvm_tools = instrumented
    stage1.debug_stage2 = False
    stage1.build()
    stage1_install = str(stage1.install_dir)

    profdata = None
    if pgo:
        long_version = build.extract_clang_long_version(stage1_install)
        profdata = build.pgo_profdata_file(long_version)

    stage2 = builders.Stage2Builder()
    stage2.build_name = 'dev'
    stage2.svn_revision = 'dev'
    stage2.build_lldb = False
    stage2.build_instrumented = instrumented
    stage2.profdata_file = Path(profdata) if profdata else None
    stage2.build()
    stage2_toolchain = toolchains.get_toolchain_from_builder(stage2)
    toolchains.set_runtime_toolchain(stage2_toolchain)
    stage2_install = str(stage2.install_dir)

    build.build_runtimes(stage2_install)

    build.package_toolchain(stage2_install,
                            'dev',
                            hosts.build_host(),
                            dist_dir=None,
                            strip=True,
                            create_tar=False)

    clang_path = build.get_package_install_path(hosts.build_host(),
                                                'clang-dev')
    version = build.extract_clang_version(clang_path)
    return clang_path, version
예제 #6
0
def install_wrappers(llvm_install_path):
    wrapper_path = utils.out_path('llvm_android_wrapper')
    wrapper_build_script = utils.android_path('external', 'toolchain-utils',
                                              'compiler_wrapper', 'build.py')
    # Note: The build script automatically determines the architecture
    # based on the host.
    go_env = dict(os.environ)
    go_env['PATH'] = go_bin_dir() + ':' + go_env['PATH']
    utils.check_call([sys.executable, wrapper_build_script,
                      '--config=android',
                      '--use_ccache=false',
                      '--use_llvm_next=' + str(BUILD_LLVM_NEXT).lower(),
                      '--output_file=' + wrapper_path], env=go_env)

    bisect_path = utils.android_path('toolchain', 'llvm_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)
예제 #7
0
 def __init__(self):
     self.profiles_dir = utils.out_path('clang-profiles')
     self.profiles_format = os.path.join(self.profiles_dir, '%4m.profraw')
예제 #8
0
def get_package_install_path(host: hosts.Host, package_name):
    return utils.out_path('install', host.os_tag, package_name)
예제 #9
0
def get_sysroot(arch: hosts.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.ndk_arch)
예제 #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