#!/usr/bin/env python
# utils/build-script - The ultimate tool for building Swift -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

from __future__ import print_function

import argparse
import os
import pipes
import platform
import sys
import time

from build_swift import driver_arguments

from swift_build_support.swift_build_support import (
    arguments,
    debug,
    diagnostics,
    migration,
    products,
    shell,
    tar,
    targets,
    workspace
)

from swift_build_support.swift_build_support.SwiftBuildSupport import (
    HOME,
    SWIFT_BUILD_ROOT,
    SWIFT_REPO_NAME,
    SWIFT_SOURCE_ROOT,
    get_all_preset_names,
    get_preset_options,
)

from swift_build_support.swift_build_support.cmake import CMake
from swift_build_support.swift_build_support.targets import \
    StdlibDeploymentTarget
from swift_build_support.swift_build_support.toolchain import host_toolchain

build_script_impl = os.path.join(
    SWIFT_SOURCE_ROOT, SWIFT_REPO_NAME, "utils", "build-script-impl")


def exit_rejecting_arguments(message, parser=None):
    print(message, file=sys.stderr)
    if parser:
        parser.print_usage(sys.stderr)
    sys.exit(2)  # 2 is the same as `argparse` error exit code.


def call_without_sleeping(command, env=None, dry_run=False, echo=False):
    """
    Execute a command during which system sleep is disabled.

    By default, this ignores the state of the `shell.dry_run` flag.
    """

    # Disable system sleep, if possible.
    if platform.system() == 'Darwin':
        # Don't mutate the caller's copy of the arguments.
        command = ["caffeinate"] + list(command)

    shell.call(command, env=env, dry_run=dry_run, echo=echo)


class HostSpecificConfiguration(object):

    """Configuration information for an individual host."""

    def __init__(self, host_target, invocation):
        """Initialize for the given `host_target`."""

        # Compute the set of deployment targets to configure/build.
        args = invocation.args
        if host_target == args.host_target:
            # This host is the user's desired product, so honor the requested
            # set of targets to configure/build.
            stdlib_targets_to_configure = args.stdlib_deployment_targets
            if "all" in args.build_stdlib_deployment_targets:
                stdlib_targets_to_build = set(stdlib_targets_to_configure)
            else:
                stdlib_targets_to_build = set(
                    args.build_stdlib_deployment_targets).intersection(
                    set(args.stdlib_deployment_targets))
        else:
            # Otherwise, this is a host we are building as part of
            # cross-compiling, so we only need the target itself.
            stdlib_targets_to_configure = [host_target]
            stdlib_targets_to_build = set(stdlib_targets_to_configure)

        # Compute the lists of **CMake** targets for each use case (configure
        # vs. build vs. run) and the SDKs to configure with.
        self.sdks_to_configure = set()
        self.swift_stdlib_build_targets = []
        self.swift_test_run_targets = []
        self.swift_benchmark_build_targets = []
        self.swift_benchmark_run_targets = []
        for deployment_target_name in stdlib_targets_to_configure:
            # Get the target object.
            deployment_target = StdlibDeploymentTarget.get_target_for_name(
                deployment_target_name)
            if deployment_target is None:
                diagnostics.fatal("unknown target: %r" % (
                    deployment_target_name,))

            # Add the SDK to use.
            deployment_platform = deployment_target.platform
            self.sdks_to_configure.add(deployment_platform.sdk_name)

            # If we aren't actually building this target (only configuring
            # it), do nothing else.
            if deployment_target_name not in stdlib_targets_to_build:
                continue

            # Compute which actions are desired.
            build = (
                deployment_platform not in invocation.platforms_to_skip_build)
            test = (
                deployment_platform not in invocation.platforms_to_skip_test)
            test_host_only = None
            dt_supports_benchmark = deployment_target.supports_benchmark
            build_benchmarks = build and dt_supports_benchmark
            build_external_benchmarks = all([build, dt_supports_benchmark,
                                             args.build_external_benchmarks])

            # FIXME: Note, `build-script-impl` computed a property here
            # w.r.t. testing, but it was actually unused.

            # For platforms which normally require a connected device to
            # test, the default behavior is to run tests that only require
            # the host (i.e., they do not attempt to execute).
            if deployment_platform.is_darwin and \
               deployment_platform.is_embedded and \
               not deployment_platform.is_simulator:
                if deployment_platform not in \
                        invocation.platforms_to_skip_test_host:
                    test_host_only = True
                    test = True
                else:
                    test = False

            name = deployment_target.name

            for skip_test_arch in invocation.platforms_archs_to_skip_test:
                if deployment_target.name == skip_test_arch.name:
                    test = False

            if build:
                # Validation and long tests require building the full standard
                # library, whereas the other targets can build a slightly
                # smaller subset which is faster to build.
                if args.build_swift_stdlib_unittest_extra or \
                        args.validation_test or args.long_test:
                    self.swift_stdlib_build_targets.append(
                        "swift-stdlib-" + name)
                else:
                    self.swift_stdlib_build_targets.append(
                        "swift-test-stdlib-" + name)
            if build_benchmarks:
                self.swift_benchmark_build_targets.append(
                    "swift-benchmark-" + name)
                # FIXME: This probably should respect `args.benchmark`, but
                # a typo in build-script-impl meant we always would do this.
                self.swift_benchmark_run_targets.append(
                    "check-swift-benchmark-" + name)

            if build_external_benchmarks:
                # Add support for the external benchmarks.
                self.swift_benchmark_build_targets.append(
                    "swift-benchmark-{}-external".format(name))
                self.swift_benchmark_run_targets.append(
                    "check-swift-benchmark-{}-external".format(name))
            if test:
                if test_host_only:
                    suffix = "-non-executable"
                else:
                    suffix = ""
                subset_suffix = ""
                if args.validation_test and args.long_test:
                    subset_suffix = "-all"
                elif args.validation_test:
                    subset_suffix = "-validation"
                elif args.long_test:
                    subset_suffix = "-only_long"
                else:
                    subset_suffix = ""
                self.swift_test_run_targets.append("check-swift{}{}-{}".format(
                    subset_suffix, suffix, name))
                if args.test_optimized and not test_host_only:
                    self.swift_test_run_targets.append(
                        "check-swift{}-optimize-{}".format(
                            subset_suffix, name))
                if args.test_optimize_for_size and not test_host_only:
                    self.swift_test_run_targets.append(
                        "check-swift{}-optimize_size-{}".format(
                            subset_suffix, name))


class BuildScriptInvocation(object):

    """Represent a single build script invocation."""

    @staticmethod
    def validate_arguments(toolchain, args):
        if toolchain.cc is None or toolchain.cxx is None:
            diagnostics.fatal(
                "can't find clang (please install clang-3.5 or a "
                "later version)")

        if toolchain.cmake is None:
            diagnostics.fatal("can't find CMake (please install CMake)")

        if args.distcc:
            if toolchain.distcc is None:
                diagnostics.fatal(
                    "can't find distcc (please install distcc)")
            if toolchain.distcc_pump is None:
                diagnostics.fatal(
                    "can't find distcc-pump (please install distcc-pump)")

        if args.host_target is None or args.stdlib_deployment_targets is None:
            diagnostics.fatal("unknown operating system")

        if args.symbols_package:
            if not os.path.isabs(args.symbols_package):
                print(
                    '--symbols-package must be an absolute path '
                    '(was \'{}\')'.format(args.symbols_package))
                return 1
            if not args.install_symroot:
                diagnostics.fatal(
                    "--install-symroot is required when specifying "
                    "--symbols-package.")

        if args.android:
            if args.android_ndk is None or \
                    args.android_api_level is None or \
                    args.android_icu_uc is None or \
                    args.android_icu_uc_include is None or \
                    args.android_icu_i18n is None or \
                    args.android_icu_i18n_include is None:
                diagnostics.fatal(
                    "when building for Android, --android-ndk, "
                    "--android-ndk-version, --android-icu-uc, "
                    "--android-icu-uc-include, --android-icu-i18n, "
                    "and --android-icu-i18n-include must be specified")

    @staticmethod
    def apply_default_arguments(toolchain, args):
        # infer if ninja is required
        ninja_required = (
            args.cmake_generator == 'Ninja' or args.build_foundation)
        if ninja_required and toolchain.ninja is None:
            args.build_ninja = True

# ---

    def __init__(self, toolchain, args):
        self.toolchain = toolchain
        self.args = args

        self.workspace = workspace.Workspace(
            source_root=SWIFT_SOURCE_ROOT,
            build_root=os.path.join(SWIFT_BUILD_ROOT, args.build_subdir))

        # Compute derived information from the arguments.
        #
        # FIXME: We should move the platform-derived arguments to be entirely
        # data driven, so that we can eliminate this code duplication and just
        # iterate over all supported platforms.

        self.platforms_to_skip_build = set()
        if not args.build_linux:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.Linux)
        if not args.build_freebsd:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.FreeBSD)
        if not args.build_cygwin:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.Cygwin)
        if not args.build_osx:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.OSX)
        if not args.build_ios_device:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.iOS)
        if not args.build_ios_simulator:
            self.platforms_to_skip_build.add(
                StdlibDeploymentTarget.iOSSimulator)
        if not args.build_tvos_device:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.AppleTV)
        if not args.build_tvos_simulator:
            self.platforms_to_skip_build.add(
                StdlibDeploymentTarget.AppleTVSimulator)
        if not args.build_watchos_device:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.AppleWatch)
        if not args.build_watchos_simulator:
            self.platforms_to_skip_build.add(
                StdlibDeploymentTarget.AppleWatchSimulator)
        if not args.build_android:
            self.platforms_to_skip_build.add(StdlibDeploymentTarget.Android)

        self.platforms_to_skip_test = set()
        self.platforms_archs_to_skip_test = set()
        if not args.test_linux:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.Linux)
        if not args.test_freebsd:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.FreeBSD)
        if not args.test_cygwin:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.Cygwin)
        if not args.test_osx:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.OSX)
        if not args.test_ios_host:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.iOS)
        else:
            exit_rejecting_arguments("error: iOS device tests are not " +
                                     "supported in open-source Swift.")
        if not args.test_ios_simulator:
            self.platforms_to_skip_test.add(
                StdlibDeploymentTarget.iOSSimulator)
        if not args.test_ios_32bit_simulator:
            self.platforms_archs_to_skip_test.add(
                StdlibDeploymentTarget.iOSSimulator.i386)
        if not args.test_tvos_host:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleTV)
        else:
            exit_rejecting_arguments("error: tvOS device tests are not " +
                                     "supported in open-source Swift.")
        if not args.test_tvos_simulator:
            self.platforms_to_skip_test.add(
                StdlibDeploymentTarget.AppleTVSimulator)
        if not args.test_watchos_host:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleWatch)
        else:
            exit_rejecting_arguments("error: watchOS device tests are not " +
                                     "supported in open-source Swift.")
        if not args.test_watchos_simulator:
            self.platforms_to_skip_test.add(
                StdlibDeploymentTarget.AppleWatchSimulator)

        if not args.test_android_host:
            self.platforms_to_skip_test.add(StdlibDeploymentTarget.Android)

        self.platforms_to_skip_test_host = set()
        if not args.test_ios_host:
            self.platforms_to_skip_test_host.add(StdlibDeploymentTarget.iOS)
        if not args.test_tvos_host:
            self.platforms_to_skip_test_host.add(
                StdlibDeploymentTarget.AppleTV)
        if not args.test_watchos_host:
            self.platforms_to_skip_test_host.add(
                StdlibDeploymentTarget.AppleWatch)

    def initialize_runtime_environment(self):
        """Change the program environment for building."""

        # Set an appropriate default umask.
        os.umask(0o022)

        # Unset environment variables that might affect how tools behave.
        for v in [
                'MAKEFLAGS',
                'SDKROOT',
                'MACOSX_DEPLOYMENT_TARGET',
                'IPHONEOS_DEPLOYMENT_TARGET',
                'TVOS_DEPLOYMENT_TARGET',
                'WATCHOS_DEPLOYMENT_TARGET']:
            os.environ.pop(v, None)

    def build_ninja(self):
        if not os.path.exists(self.workspace.source_dir("ninja")):
            diagnostics.fatal(
                "can't find source directory for ninja "
                "(tried %s)" % (self.workspace.source_dir("ninja")))

        ninja_build = products.Ninja(
            args=self.args,
            toolchain=self.toolchain,
            source_dir=self.workspace.source_dir("ninja"),
            build_dir=self.workspace.build_dir("build", "ninja"))
        ninja_build.do_build()
        self.toolchain.ninja = ninja_build.ninja_bin_path

    def convert_to_impl_arguments(self):
        """convert_to_impl_arguments() -> (env, args)

        Convert the invocation to an environment and list of arguments suitable
        for invoking `build-script-impl`.
        """

        # Create local shadows, for convenience.
        args = self.args
        toolchain = self.toolchain

        cmake = CMake(args=args,
                      toolchain=self.toolchain)

        impl_args = [
            "--workspace", self.workspace.source_root,
            "--build-dir", self.workspace.build_root,
            "--install-prefix", args.install_prefix,
            "--host-target", args.host_target,
            "--stdlib-deployment-targets",
            " ".join(args.stdlib_deployment_targets),
            "--host-cc", toolchain.cc,
            "--host-cxx", toolchain.cxx,
            "--darwin-xcrun-toolchain", args.darwin_xcrun_toolchain,
            "--darwin-deployment-version-osx=%s" % (
                args.darwin_deployment_version_osx),
            "--darwin-deployment-version-ios=%s" % (
                args.darwin_deployment_version_ios),
            "--darwin-deployment-version-tvos=%s" % (
                args.darwin_deployment_version_tvos),
            "--darwin-deployment-version-watchos=%s" % (
                args.darwin_deployment_version_watchos),
            "--cmake", toolchain.cmake,
            "--cmark-build-type", args.cmark_build_variant,
            "--llvm-build-type", args.llvm_build_variant,
            "--swift-build-type", args.swift_build_variant,
            "--swift-stdlib-build-type", args.swift_stdlib_build_variant,
            "--lldb-build-type", args.lldb_build_variant,
            "--foundation-build-type", args.foundation_build_variant,
            "--libdispatch-build-type", args.libdispatch_build_variant,
            "--libicu-build-type", args.libicu_build_variant,
            "--xctest-build-type", args.build_variant,
            "--swiftpm-build-type", args.build_variant,
            "--swift-enable-assertions", str(args.swift_assertions).lower(),
            "--swift-stdlib-enable-assertions", str(
                args.swift_stdlib_assertions).lower(),
            "--swift-analyze-code-coverage", str(
                args.swift_analyze_code_coverage).lower(),
            "--cmake-generator", args.cmake_generator,
            "--build-jobs", str(args.build_jobs),
            "--common-cmake-options=%s" % ' '.join(
                pipes.quote(opt) for opt in cmake.common_options()),
            "--build-args=%s" % ' '.join(
                pipes.quote(arg) for arg in cmake.build_args()),
        ]

        # Compute any product specific cmake arguments.
        for product_class in self.compute_product_classes():
            product_name = product_class.product_name()
            product_source_name = product_class.product_source_name()
            source_dir = self.workspace.source_dir(product_source_name)

            if not os.path.exists(source_dir):
                diagnostics.fatal(
                    "can't find source directory for %s "
                    "(tried %s)" % (product_name, source_dir))

            product = product_class(
                args=args,
                toolchain=self.toolchain,
                source_dir=source_dir,
                # FIXME: This is incorrect since it always assumes the host
                # target I think?
                build_dir=self.workspace.build_dir(
                    args.host_target, product_name))
            cmake_opts = product.cmake_options

            # FIXME: We should be using pipes.quote here but we run into issues
            # with build-script-impl/cmake not being happy with all of the
            # extra "'" in the strings. To fix this easily, we really need to
            # just invoke cmake from build-script directly rather than futzing
            # with build-script-impl. This makes even more sense since there
            # really isn't a security issue here.
            impl_args += [
                "--%s-cmake-options=%s" % (product_name, ' '.join(cmake_opts))
            ]

        if args.build_stdlib_deployment_targets:
            impl_args += [
                "--build-stdlib-deployment-targets", " ".join(
                    args.build_stdlib_deployment_targets)]
        if args.cross_compile_hosts:
            impl_args += [
                "--cross-compile-hosts", " ".join(args.cross_compile_hosts)]

        if args.test_paths:
            impl_args += ["--test-paths", " ".join(args.test_paths)]

        if toolchain.ninja:
            impl_args += ["--ninja-bin=%s" % toolchain.ninja]
        if args.distcc:
            impl_args += [
                "--distcc",
                "--distcc-pump=%s" % toolchain.distcc_pump
            ]

        # *NOTE* We use normal cmake to pass through tsan/ubsan options. We do
        # NOT pass them to build-script-impl.
        if args.enable_asan:
            impl_args += ["--enable-asan"]
        # If we have lsan, we need to export our suppression list. The actual
        # passing in of the LSAN flag is done via the normal cmake method. We
        # do not pass the flag to build-script-impl.
        if args.enable_lsan:
            supp_file = os.path.join(SWIFT_SOURCE_ROOT, SWIFT_REPO_NAME,
                                     "utils",
                                     "lsan_leaks_suppression_list.txt")
            os.environ['LSAN_OPTIONS'] = 'suppressions={}'.format(supp_file)
        if args.verbose_build:
            impl_args += ["--verbose-build"]
        if args.install_symroot:
            impl_args += [
                "--install-symroot", os.path.abspath(args.install_symroot)
            ]

        if args.skip_build:
            impl_args += ["--skip-build-cmark",
                          "--skip-build-llvm",
                          "--skip-build-swift"]
        if not args.build_benchmarks:
            impl_args += ["--skip-build-benchmarks"]
        # Currently we do not build external benchmarks by default.
        if args.build_external_benchmarks:
            impl_args += ["--skip-build-external-benchmarks=0"]
        if not args.build_foundation:
            impl_args += ["--skip-build-foundation"]
        if not args.build_xctest:
            impl_args += ["--skip-build-xctest"]
        if not args.build_lldb:
            impl_args += ["--skip-build-lldb"]
        if not args.build_llbuild:
            impl_args += ["--skip-build-llbuild"]
        if not args.build_libdispatch:
            impl_args += ["--skip-build-libdispatch"]
        if not args.build_libicu:
            impl_args += ["--skip-build-libicu"]
        if not args.build_swiftpm:
            impl_args += ["--skip-build-swiftpm"]
        if not args.build_playgroundlogger:
            impl_args += ["--skip-build-playgroundlogger"]
        if not args.build_playgroundsupport:
            impl_args += ["--skip-build-playgroundsupport"]
        if args.build_swift_dynamic_stdlib:
            impl_args += ["--build-swift-dynamic-stdlib"]
        if args.build_swift_static_stdlib:
            impl_args += ["--build-swift-static-stdlib"]
        if args.build_swift_stdlib_unittest_extra:
            impl_args += ["--build-swift-stdlib-unittest-extra"]
        if args.build_swift_dynamic_sdk_overlay:
            impl_args += ["--build-swift-dynamic-sdk-overlay"]
        if args.build_swift_static_sdk_overlay:
            impl_args += ["--build-swift-static-sdk-overlay"]

        if not args.build_linux:
            impl_args += ["--skip-build-linux"]
        if not args.build_freebsd:
            impl_args += ["--skip-build-freebsd"]
        if not args.build_cygwin:
            impl_args += ["--skip-build-cygwin"]
        if not args.build_osx:
            impl_args += ["--skip-build-osx"]
        if not args.build_ios_device:
            impl_args += ["--skip-build-ios-device"]
        if not args.build_ios_simulator:
            impl_args += ["--skip-build-ios-simulator"]
        if not args.build_tvos_device:
            impl_args += ["--skip-build-tvos-device"]
        if not args.build_tvos_simulator:
            impl_args += ["--skip-build-tvos-simulator"]
        if not args.build_watchos_device:
            impl_args += ["--skip-build-watchos-device"]
        if not args.build_watchos_simulator:
            impl_args += ["--skip-build-watchos-simulator"]
        if not args.build_android:
            impl_args += ["--skip-build-android"]

        if not args.test and not args.long_test:
            impl_args += ["--skip-test-swift"]
        if not args.test:
            impl_args += ["--skip-test-cmark",
                          "--skip-test-lldb",
                          "--skip-test-llbuild",
                          "--skip-test-swiftpm",
                          "--skip-test-xctest",
                          "--skip-test-foundation",
                          "--skip-test-libdispatch",
                          "--skip-test-libicu",
                          "--skip-test-playgroundlogger",
                          "--skip-test-playgroundsupport"]
        if not args.test_linux:
            impl_args += ["--skip-test-linux"]
        if not args.test_freebsd:
            impl_args += ["--skip-test-freebsd"]
        if not args.test_cygwin:
            impl_args += ["--skip-test-cygwin"]
        if not args.test_osx:
            impl_args += ["--skip-test-osx"]
        if not args.test_ios_host:
            impl_args += ["--skip-test-ios-host"]
        if not args.test_ios_simulator:
            impl_args += ["--skip-test-ios-simulator"]
        if not args.test_ios_32bit_simulator:
            impl_args += ["--skip-test-ios-32bit-simulator"]
        if not args.test_tvos_host:
            impl_args += ["--skip-test-tvos-host"]
        if not args.test_tvos_simulator:
            impl_args += ["--skip-test-tvos-simulator"]
        if not args.test_watchos_host:
            impl_args += ["--skip-test-watchos-host"]
        if not args.test_watchos_simulator:
            impl_args += ["--skip-test-watchos-simulator"]
        if not args.test_android_host:
            impl_args += ["--skip-test-android-host"]
        if args.build_runtime_with_host_compiler:
            impl_args += ["--build-runtime-with-host-compiler"]
        if args.validation_test:
            impl_args += ["--validation-test"]
        if args.long_test:
            impl_args += ["--long-test"]
        if not args.benchmark:
            impl_args += ["--skip-test-benchmarks"]
        if not args.test_optimized:
            impl_args += ["--skip-test-optimized"]
        if not args.test_optimize_for_size:
            impl_args += ["--skip-test-optimize-for-size"]

        if args.android:
            impl_args += [
                "--android-ndk", args.android_ndk,
                "--android-api-level", args.android_api_level,
                "--android-ndk-gcc-version",
                args.android_ndk_gcc_version,
                "--android-icu-uc", args.android_icu_uc,
                "--android-icu-uc-include", args.android_icu_uc_include,
                "--android-icu-i18n", args.android_icu_i18n,
                "--android-icu-i18n-include", args.android_icu_i18n_include,
            ]
        if args.android_deploy_device_path:
            impl_args += [
                "--android-deploy-device-path",
                args.android_deploy_device_path,
            ]

        if platform.system() == 'Darwin':
            impl_args += [
                "--toolchain-prefix",
                targets.darwin_toolchain_prefix(
                    args.install_prefix),
                "--host-lipo", toolchain.lipo,
            ]

        if toolchain.libtool is not None:
            impl_args += [
                "--host-libtool", toolchain.libtool,
            ]

        # If we have extra_swift_args, combine all of them together and then
        # add them as one command.
        if args.extra_swift_args:
            impl_args += [
                "--extra-swift-args",
                ";".join(args.extra_swift_args)]

        # If we have extra_cmake_options, combine all of them together and then
        # add them as one command.
        if args.extra_cmake_options:
            impl_args += [
                "--extra-cmake-options=%s" % ' '.join(
                    pipes.quote(opt) for opt in args.extra_cmake_options)
            ]

        if args.lto_type is not None:
            impl_args += [
                "--llvm-enable-lto=%s" % args.lto_type,
                "--swift-tools-enable-lto=%s" % args.lto_type
            ]
            if args.llvm_max_parallel_lto_link_jobs is not None:
                impl_args += [
                    "--llvm-num-parallel-lto-link-jobs=%s" %
                    min(args.llvm_max_parallel_lto_link_jobs, args.build_jobs)
                ]
            if args.swift_tools_max_parallel_lto_link_jobs is not None:
                impl_args += [
                    "--swift-tools-num-parallel-lto-link-jobs=%s" %
                    min(args.swift_tools_max_parallel_lto_link_jobs,
                        args.build_jobs)
                ]

        impl_args += args.build_script_impl_args

        if args.dry_run:
            impl_args += ["--dry-run"]

        if args.clang_profile_instr_use:
            impl_args += [
                "--clang-profile-instr-use=%s" %
                os.path.abspath(args.clang_profile_instr_use)
            ]

        if args.lit_args:
            impl_args += ["--llvm-lit-args=%s" % args.lit_args]

        if args.coverage_db:
            impl_args += [
                "--coverage-db=%s" %
                os.path.abspath(args.coverage_db)
            ]

        # Compute the set of host-specific variables, which we pass through to
        # the build script via environment variables.
        host_specific_variables = self.compute_host_specific_variables()
        impl_env = {}
        for (host_target, options) in host_specific_variables.items():
            for (name, value) in options.items():
                # We mangle into an environment variable we can easily evaluate
                # from the `build-script-impl`.
                impl_env["HOST_VARIABLE_{}__{}".format(
                    host_target.replace("-", "_"), name)] = value

        return (impl_env, impl_args)

    def compute_host_specific_variables(self):
        """compute_host_specific_variables(args) -> dict

        Compute the host-specific options, organized as a dictionary keyed by
        host of options.
        """

        args = self.args

        options = {}
        for host_target in [args.host_target] + args.cross_compile_hosts:
            # Compute the host specific configuration.
            config = HostSpecificConfiguration(host_target, self)

            # Convert into `build-script-impl` style variables.
            options[host_target] = {
                "SWIFT_SDKS": " ".join(sorted(
                    config.sdks_to_configure)),
                "SWIFT_STDLIB_TARGETS": " ".join(
                    config.swift_stdlib_build_targets),
                "SWIFT_BENCHMARK_TARGETS": " ".join(
                    config.swift_benchmark_build_targets),
                "SWIFT_RUN_BENCHMARK_TARGETS": " ".join(
                    config.swift_benchmark_run_targets),
                "SWIFT_TEST_TARGETS": " ".join(
                    config.swift_test_run_targets),
            }

        return options

    def compute_product_classes(self):
        """compute_product_classes() -> list

        Compute the list of all Product classes used in this build. This list
        is constructed in dependency order.
        """

        # FIXME: This is a weird division (returning a list of class objects),
        # but it matches the existing structure of the `build-script-impl`.

        product_classes = []
        product_classes.append(products.CMark)
        product_classes.append(products.LLVM)
        if self.args.build_libicu:
            product_classes.append(products.LibICU)
        product_classes.append(products.Swift)
        if self.args.build_lldb:
            product_classes.append(products.LLDB)
        if self.args.build_llbuild:
            product_classes.append(products.LLBuild)
        if self.args.build_libdispatch:
            product_classes.append(products.LibDispatch)
        if self.args.build_foundation:
            product_classes.append(products.Foundation)
        if self.args.build_xctest:
            product_classes.append(products.XCTest)
        if self.args.build_swiftpm:
            product_classes.append(products.SwiftPM)
        return product_classes

    def execute(self):
        """Execute the invocation with the configured arguments."""

        # Convert to a build-script-impl invocation.
        (impl_env, impl_args) = self.convert_to_impl_arguments()

        # If using the legacy implementation, delegate all behavior to
        # `build-script-impl`.
        if self.args.legacy_impl:
            # Execute the underlying build script implementation.
            call_without_sleeping([build_script_impl] + impl_args,
                                  env=impl_env, echo=True)
            return

        # Otherwise, we compute and execute the individual actions ourselves.

        def execute_one_impl_action(host=None, product_class=None, name=None):
            if host is None:
                assert (product_class is None and
                        name == "merged-hosts-lipo"), "invalid action"
                action_name = name
            elif product_class is None:
                assert name == "package", "invalid action"
                action_name = "{}-{}".format(host.name, name)
            else:
                assert name is not None, "invalid action"
                action_name = "{}-{}-{}".format(
                    host.name, product_class.product_name(), name)
            call_without_sleeping(
                [build_script_impl] + impl_args + [
                    "--only-execute", action_name],
                env=impl_env, echo=self.args.verbose_build)

        # Compute the list of hosts to operate on.
        all_host_names = [
            self.args.host_target] + self.args.cross_compile_hosts
        all_hosts = [StdlibDeploymentTarget.get_target_for_name(name)
                     for name in all_host_names]

        # Compute the list of product classes to operate on.
        #
        # FIXME: This should really be per-host, but the current structure
        # matches that of `build-script-impl`.
        product_classes = self.compute_product_classes()

        # Execute each "pass".

        # Build...
        for host_target in all_hosts:
            # FIXME: We should only compute these once.
            config = HostSpecificConfiguration(host_target.name, self)
            print("Building the standard library for: {}".format(
                " ".join(config.swift_stdlib_build_targets)))
            if config.swift_test_run_targets and (
                    self.args.test or self.args.long_test):
                print("Running Swift tests for: {}".format(
                    " ".join(config.swift_test_run_targets)))
            if config.swift_benchmark_run_targets and self.args.benchmark:
                print("Running Swift benchmarks for: {}".format(
                    " ".join(config.swift_benchmark_run_targets)))

            for product_class in product_classes:
                execute_one_impl_action(host_target, product_class, "build")

        # Test...
        for host_target in all_hosts:
            for product_class in product_classes:
                execute_one_impl_action(host_target, product_class, "test")

        # Install...
        for host_target in all_hosts:
            for product_class in product_classes:
                execute_one_impl_action(host_target, product_class, "install")

        # Package...
        for host_target in all_hosts:
            execute_one_impl_action(host_target, name="package")

        # Lipo...
        execute_one_impl_action(name="merged-hosts-lipo")


# Provide a short delay so accidentally invoked clean builds can be canceled.
def clean_delay():
    sys.stdout.write('Starting clean build in  ')
    for i in range(3, 0, -1):
        sys.stdout.write('\b%d' % i)
        sys.stdout.flush()
        time.sleep(1)
    print('\b\b\b\bnow.')


# Main entry point for the preset mode.
def main_preset():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="""Builds Swift using a preset.""")
    parser.add_argument(
        "-n", "--dry-run",
        help="print the commands that would be executed, but do not execute "
             "them",
        action="store_true",
        default=False)
    parser.add_argument(
        "--preset-file",
        help="load presets from the specified file",
        metavar="PATH",
        action="append",
        dest="preset_file_names",
        default=[])
    parser.add_argument(
        "--preset",
        help="use the specified option preset",
        metavar="NAME")
    parser.add_argument(
        "--show-presets",
        help="list all presets and exit",
        action=arguments.action.optional_bool)
    parser.add_argument(
        "--distcc",
        help="use distcc",
        action=arguments.action.optional_bool)
    parser.add_argument(
        "-j", "--jobs",
        help="the number of parallel build jobs to use",
        type=int,
        dest="build_jobs")
    parser.add_argument(
        "preset_substitutions_raw",
        help="'name=value' pairs that are substituted in the preset",
        nargs="*",
        metavar="SUBSTITUTION")
    parser.add_argument(
        "--expand-build-script-invocation",
        help="Print the expanded build-script invocation generated "
             "by the preset, but do not run the preset",
        action=arguments.action.optional_bool)
    args = parser.parse_args()

    if len(args.preset_file_names) == 0:
        args.preset_file_names = [
            os.path.join(HOME, ".swift-build-presets"),
            os.path.join(
                SWIFT_SOURCE_ROOT, SWIFT_REPO_NAME, "utils",
                "build-presets.ini")
        ]

    if args.show_presets:
        for name in sorted(get_all_preset_names(args.preset_file_names),
                           key=str.lower):
            print(name)
        return 0

    if not args.preset:
        diagnostics.fatal("missing --preset option")

    args.preset_substitutions = {}

    for arg in args.preset_substitutions_raw:
        name, value = arg.split("=", 1)
        args.preset_substitutions[name] = value

    preset_args = get_preset_options(
        args.preset_substitutions, args.preset_file_names, args.preset)

    build_script_args = [sys.argv[0]]
    if args.dry_run:
        build_script_args += ["--dry-run"]
    build_script_args += preset_args
    if args.distcc:
        build_script_args += ["--distcc"]
    if args.build_jobs:
        build_script_args += ["--jobs", str(args.build_jobs)]

    diagnostics.note(
        "using preset '" + args.preset + "', which expands to \n\n" +
        shell.quote_command(build_script_args) + "\n")

    if args.expand_build_script_invocation:
        return 0

    call_without_sleeping(build_script_args)
    return 0


# Main entry point for the normal mode.
def main_normal():
    parser = driver_arguments.create_argument_parser()

    args = migration.parse_args(parser, sys.argv[1:])

    if args.build_script_impl_args:
        # If we received any impl args, check if `build-script-impl` would
        # accept them or not before any further processing.
        try:
            migration.check_impl_args(build_script_impl,
                                      args.build_script_impl_args)
        except ValueError as e:
            exit_rejecting_arguments(e, parser)

        if '--check-args-only' in args.build_script_impl_args:
            return 0

    shell.dry_run = args.dry_run

    # Prepare and validate toolchain
    toolchain = host_toolchain(xcrun_toolchain=args.darwin_xcrun_toolchain)
    os.environ['TOOLCHAINS'] = args.darwin_xcrun_toolchain

    if args.host_cc is not None:
        toolchain.cc = args.host_cc
    if args.host_cxx is not None:
        toolchain.cxx = args.host_cxx
    if args.host_lipo is not None:
        toolchain.lipo = args.host_lipo
    if args.host_libtool is not None:
        toolchain.libtool = args.host_libtool
    if args.cmake is not None:
        toolchain.cmake = args.cmake

    # Preprocess the arguments to apply defaults.
    BuildScriptInvocation.apply_default_arguments(toolchain, args)

    # Validate the arguments.
    BuildScriptInvocation.validate_arguments(toolchain, args)

    # Create the build script invocation.
    invocation = BuildScriptInvocation(toolchain, args)

    # Sanitize the runtime environment.
    invocation.initialize_runtime_environment()

    # Show SDKs, if requested.
    if args.show_sdks:
        debug.print_xcodebuild_versions()

    # Clean build directory if requested.
    if args.clean:
        clean_delay()
        shell.rmtree(invocation.workspace.build_root)

    # Create build directory.
    shell.makedirs(invocation.workspace.build_root)

    # Build ninja if required, which will update the toolchain.
    if args.build_ninja:
        invocation.build_ninja()

    # Execute the underlying build script implementation.
    invocation.execute()

    if args.symbols_package:
        print('--- Creating symbols package ---')
        print('-- Package file: {} --'.format(args.symbols_package))

        if platform.system() == 'Darwin':
            prefix = targets.darwin_toolchain_prefix(args.install_prefix)
        else:
            prefix = args.install_prefix

        # As a security measure, `tar` normally strips leading '/' from paths
        # it is archiving. To stay safe, we change working directories, then
        # run `tar` without the leading '/' (we remove it ourselves to keep
        # `tar` from emitting a warning).
        with shell.pushd(args.install_symroot):
            tar.tar(source=prefix.lstrip('/'),
                    destination=args.symbols_package)

    return 0


def main():
    if not SWIFT_SOURCE_ROOT:
        diagnostics.fatal(
            "could not infer source root directory " +
            "(forgot to set $SWIFT_SOURCE_ROOT environment variable?)")

    if not os.path.isdir(SWIFT_SOURCE_ROOT):
        diagnostics.fatal(
            "source root directory \'" + SWIFT_SOURCE_ROOT +
            "\' does not exist " +
            "(forgot to set $SWIFT_SOURCE_ROOT environment variable?)")

    # Determine if we are invoked in the preset mode and dispatch accordingly.
    if any([(opt.startswith("--preset") or opt == "--show-presets")
            for opt in sys.argv[1:]]):
        return main_preset()
    else:
        return main_normal()


if __name__ == "__main__":
    try:
        sys.exit(main())
    except KeyboardInterrupt:
        sys.exit(1)
