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)
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
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.")
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)
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
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)
def __init__(self): self.profiles_dir = utils.out_path('clang-profiles') self.profiles_format = os.path.join(self.profiles_dir, '%4m.profraw')
def get_package_install_path(host: hosts.Host, package_name): return utils.out_path('install', host.os_tag, package_name)
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)
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