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)
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)
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
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
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
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
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)
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
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)
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