#!/usr/bin/env python

# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2020 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


"""
The ultimate tool for building Swift.
"""


from __future__ import absolute_import, print_function, unicode_literals

import json
import os
import pipes
import platform
import sys
import time

from build_swift.build_swift import argparse
from build_swift.build_swift import defaults
from build_swift.build_swift import driver_arguments
from build_swift.build_swift import migration
from build_swift.build_swift import presets
from build_swift.build_swift.constants import BUILD_SCRIPT_IMPL_PATH
from build_swift.build_swift.constants import SWIFT_BUILD_ROOT
from build_swift.build_swift.constants import SWIFT_REPO_NAME
from build_swift.build_swift.constants import SWIFT_SOURCE_ROOT

import six

from swift_build_support.swift_build_support import build_graph
from swift_build_support.swift_build_support import products
from swift_build_support.swift_build_support import shell
from swift_build_support.swift_build_support import targets
from swift_build_support.swift_build_support import workspace
from swift_build_support.swift_build_support.cmake import CMake
from swift_build_support.swift_build_support.host_specific_configuration \
    import HostSpecificConfiguration
from swift_build_support.swift_build_support.targets import StdlibDeploymentTarget
from swift_build_support.swift_build_support.toolchain import host_toolchain


# -----------------------------------------------------------------------------
# Constants

# These versions are community sourced. At any given time only the Xcode
# version used by Swift CI is officially supported. See ci.swift.org
_SUPPORTED_XCODE_BUILDS = [
    ("12.2 beta 3", "12B5035g"),
    ("12.2 Release Candidate", "12B5044c"),
    ("12.2", "12B45b"),
    ("12.3", "12C33"),
]

# -----------------------------------------------------------------------------
# Helpers


def print_note(message, stream=sys.stdout):
    """Writes a diagnostic message to the given stream. By default this
    function outputs to stdout.
    """

    stream.write('[{}] NOTE: {}\n'.format(sys.argv[0], message))
    stream.flush()


def fatal_error(message, stream=sys.stderr):
    """Writes a message to the given stream and exits. By default this
    function outputs to stderr.
    """

    stream.write('[{}] ERROR: {}\n'.format(sys.argv[0], message))
    stream.flush()
    sys.exit(1)


def clean_delay():
    """Provide a short delay so accidentally invoked clean builds can be
    canceled.
    """

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


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 initialize_runtime_environment():
    """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)

    # Set NINJA_STATUS to format ninja output
    os.environ['NINJA_STATUS'] = '[%f/%t][%p][%es] '


class JSONDumper(json.JSONEncoder):
    def __init__(self, *args, **kwargs):
        json.JSONEncoder.__init__(
            self, indent=2, separators=(',', ': '), sort_keys=True,
            *args, **kwargs)

    def default(self, o):
        if hasattr(o, '__dict__'):
            return vars(o)
        return six.text_type(o)


def print_xcodebuild_versions(file=sys.stdout):
    """
    Print the host machine's `xcodebuild` version, as well as version
    information for all available SDKs.
    """
    version = shell.capture(
        ['xcodebuild', '-version'], dry_run=False, echo=False).rstrip()
    # Allow non-zero exit codes.  Under certain obscure circumstances
    # xcodebuild can exit with a non-zero exit code even when the SDK is
    # usable.
    sdks = shell.capture(
        ['xcodebuild', '-version', '-sdk'], dry_run=False, echo=False,
        allow_non_zero_exit=True).rstrip()
    fmt = '{version}\n\n--- SDK versions ---\n{sdks}\n'

    print(fmt.format(version=version, sdks=sdks), file=file)
    file.flush()


def validate_xcode_compatibility():
    if sys.platform != 'darwin':
        return

    if os.getenv("SKIP_XCODE_VERSION_CHECK"):
        print("note: skipping Xcode version check")
        return

    version = shell.capture(
        ['xcodebuild', '-version'], dry_run=False, echo=False).strip()

    valid_build_numbers = tuple(x[1] for x in _SUPPORTED_XCODE_BUILDS)
    if not version.endswith(valid_build_numbers):
        valid_versions_string = "\n".join(
            "{} ({})".format(*x) for x in _SUPPORTED_XCODE_BUILDS)
        raise SystemExit(
            "error: using unsupported Xcode version:\n\n{}\n\n"
            "Install one of:\n{}\n\n"
            "Or set 'SKIP_XCODE_VERSION_CHECK=1' in the environment".format(
                version, valid_versions_string
            )
        )


def tar(source, destination):
    """
    Create a gzip archive of the file at 'source' at the given
    'destination' path.
    """
    # We do not use `tarfile` here because:
    #  - We wish to support LZMA2 compression while also supporting Python 2.7.
    #  - We wish to explicitly set the owner and group of the archive.
    args = ['tar', '-c', '-z', '-f', destination]

    if platform.system() != 'Darwin' and platform.system() != 'Windows':
        args += ['--owner=0', '--group=0']

    # Discard stderr output such as 'tar: Failed to open ...'. We'll detect
    # these cases using the exit code, which should cause 'shell.call' to
    # raise.
    shell.call(args + [source], stderr=shell.DEVNULL)


# -----------------------------------------------------------------------------
# Argument Validation

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

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

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

    if args.sccache:
        if toolchain.sccache is None:
            fatal_error(
                "can't find sccache (please install sccache)")

    if args.host_target is None or args.stdlib_deployment_targets is None:
        fatal_error("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:
            fatal_error(
                "--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 or \
                args.android_icu_data is None:
            fatal_error(
                "when building for Android, --android-ndk, "
                "--android-api-level, --android-icu-uc, "
                "--android-icu-uc-include, --android-icu-i18n, "
                "--android-icu-i18n-include, and --android-icu-data "
                "must be specified")

    targets_needing_toolchain = [
        'build_indexstoredb',
        'build_playgroundsupport',
        'build_sourcekitlsp',
        'build_tensorflow_swift_apis',
        'build_toolchainbenchmarks',
        'build_swift_inspect',
        'tsan_libdispatch_test',
    ]
    has_target_needing_toolchain = \
        bool(sum(getattr(args, x) for x in targets_needing_toolchain))
    if args.legacy_impl and has_target_needing_toolchain:
        fatal_error(
            "--legacy-impl is incompatible with building packages needing "
            "a toolchain (%s)" % ", ".join(targets_needing_toolchain))


def default_stdlib_deployment_targets(args):
    """
    Return targets for the Swift stdlib, based on the build machine.
    If the build machine is not one of the recognized ones, return None.
    """

    host_target = StdlibDeploymentTarget.host_target()
    if host_target is None:
        return None

    # OS X build machines configure all Darwin platforms by default.
    # Put iOS native targets last so that we test them last
    # (it takes a long time).
    if host_target == StdlibDeploymentTarget.OSX.x86_64:
        targets = [host_target]
        if args.build_ios and args.build_ios_simulator:
            targets.extend(StdlibDeploymentTarget.iOSSimulator.targets)
        if args.build_ios and args.build_ios_device:
            targets.extend(StdlibDeploymentTarget.iOS.targets)
        if args.build_tvos and args.build_tvos_simulator:
            targets.extend(StdlibDeploymentTarget.AppleTVSimulator.targets)
        if args.build_tvos and args.build_tvos_device:
            targets.extend(StdlibDeploymentTarget.AppleTV.targets)
        if args.build_watchos and args.build_watchos_simulator:
            targets.extend(StdlibDeploymentTarget
                           .AppleWatchSimulator.targets)
        if args.build_watchos and args.build_watchos_device:
            targets.extend(StdlibDeploymentTarget.AppleWatch.targets)
        return targets
    else:
        # All other machines only configure their host stdlib by default.
        return [host_target]


def apply_default_arguments(toolchain, args):
    # Infer if ninja is required
    ninja_required = (
        args.build_foundation or
        args.build_indexstoredb or
        args.build_sourcekitlsp or
        args.build_tensorflow_swift_apis or
        args.cmake_generator == 'Ninja'
    )
    if ninja_required and toolchain.ninja is None:
        args.build_ninja = True

    # Set the default stdlib-deployment-targets, if none were provided.
    if args.stdlib_deployment_targets is None:
        stdlib_targets = default_stdlib_deployment_targets(args)
        args.stdlib_deployment_targets = [
            target.name for target in stdlib_targets]

    # SwiftPM and XCTest have a dependency on Foundation.
    # On OS X, Foundation is built automatically using xcodebuild.
    # On Linux, we must ensure that it is built manually.
    if ((args.build_swiftpm or args.build_xctest) and
            platform.system() != "Darwin"):
        args.build_foundation = True

    # Foundation has a dependency on libdispatch.
    # On OS X, libdispatch is provided by the OS.
    # On Linux, we must ensure that it is built manually.
    if (args.build_foundation and
            platform.system() != "Darwin"):
        args.build_libdispatch = True

    if args.build_subdir is None:
        args.build_subdir = \
            workspace.compute_build_subdir(args)

    if args.install_destdir is None:
        args.install_destdir = os.path.join(
            SWIFT_BUILD_ROOT, args.build_subdir,
            '{}-{}'.format('toolchain', args.host_target))

    # Add optional stdlib-deployment-targets
    if args.android:
        if args.android_arch == "armv7":
            args.stdlib_deployment_targets.append(
                StdlibDeploymentTarget.Android.armv7.name)
        elif args.android_arch == "aarch64":
            args.stdlib_deployment_targets.append(
                StdlibDeploymentTarget.Android.aarch64.name)
        elif args.android_arch == "x86_64":
            args.stdlib_deployment_targets.append(
                StdlibDeploymentTarget.Android.x86_64.name)

    # Infer platform flags from manually-specified configure targets.
    # This doesn't apply to Darwin platforms, as they are
    # already configured. No building without the platform flag, though.

    android_tgts = [tgt for tgt in args.stdlib_deployment_targets
                    if StdlibDeploymentTarget.Android.contains(tgt)]
    if not args.android and len(android_tgts) > 0:
        # If building natively on an Android host, avoid the NDK
        # cross-compilation configuration.
        if not StdlibDeploymentTarget.Android.contains(StdlibDeploymentTarget
                                                       .host_target().name):
            args.android = True
        args.build_android = False

    # Include the Darwin supported architectures in the CMake options.
    if args.swift_darwin_supported_archs:
        args.extra_cmake_options.append(
            '-DSWIFT_DARWIN_SUPPORTED_ARCHS:STRING={}'.format(
                args.swift_darwin_supported_archs))

        # Remove unsupported Darwin archs from the standard library
        # deployment targets.
        supported_archs = args.swift_darwin_supported_archs.split(';')
        targets = StdlibDeploymentTarget.get_targets_by_name(
            args.stdlib_deployment_targets)

        args.stdlib_deployment_targets = [
            target.name
            for target in targets
            if (target.platform.is_darwin and
                target.arch in supported_archs)
        ]

    # Filter out any macOS stdlib deployment targets that are not supported
    # by the macOS SDK.
    targets = StdlibDeploymentTarget.get_targets_by_name(
        args.stdlib_deployment_targets)
    args.stdlib_deployment_targets = [
        target.name
        for target in targets
        if (not target.platform.is_darwin or
            target.platform.sdk_supports_architecture(
                target.arch, args.darwin_xcrun_toolchain))
    ]

    # Include the Darwin module-only architectures in the CMake options.
    if args.swift_darwin_module_archs:
        args.extra_cmake_options.append(
            '-DSWIFT_DARWIN_MODULE_ARCHS:STRING={}'.format(
                args.swift_darwin_module_archs))


# -----------------------------------------------------------------------------
# Build Script Impl Wrapping

class BuildScriptInvocation(object):
    """Represent a single build script invocation.
    """

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

        self.build_libparser_only = args.build_libparser_only

    @property
    def install_all(self):
        return self.args.install_all or self.args.infer_dependencies

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

        ninja_build = products.Ninja.new_builder(
            args=self.args,
            toolchain=self.toolchain,
            workspace=self.workspace,
            host=StdlibDeploymentTarget.get_target_for_name(
                self.args.host_target))
        ninja_build.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={}".format(
                " ".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,
            "--llbuild-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(),
            "--llbuild-enable-assertions", str(
                args.llbuild_assertions).lower(),
            "--lldb-assertions", str(
                args.lldb_assertions).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()),
            "--dsymutil-jobs", str(args.dsymutil_jobs),
        ]

        # Compute any product specific cmake arguments.
        #
        # NOTE: The sum(list(...)) is b/c compute_product_classes returns a
        # tuple of lists of which the first is the build-script-impl products
        # and the second is the non-build-script-impl-products. It guarantees
        # that when we concatenate these two lists together we get a valid
        # dependency graph.
        for product_class in sum(list(self.compute_product_classes()), []):
            if not product_class.is_build_script_impl_product():
                continue

            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):
                fatal_error(
                    "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.
            if cmake_opts:
                impl_args += [
                    "--{}-cmake-options={}".format(
                        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
            ]
        if args.sccache:
            args.cmake_c_launcher = toolchain.sccache
            args.cmake_cxx_launcher = toolchain.sccache

        # *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 are on linux, disable leak detection when running ASAN. We
            # have a separate bot that checks for leaks.
            if platform.system() == 'Linux':
                os.environ['ASAN_OPTIONS'] = 'detect_leaks=0'
        if args.enable_ubsan:
            impl_args += ["--enable-ubsan"]

        # 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.install_destdir:
            impl_args += [
                "--install-destdir", os.path.abspath(args.install_destdir)
            ]

        if args.skip_build:
            impl_args += ["--skip-build"]
        if not args.build_benchmarks:
            impl_args += ["--skip-build-benchmarks"]

        # Then add subproject install flags that either skip building them /or/
        # if we are going to build them and install_all is set, we also install
        # them.
        conditional_subproject_configs = [
            (args.build_cmark, "cmark"),
            (args.build_llvm, "llvm"),
            (args.build_swift, "swift"),
            (args.build_foundation, "foundation"),
            (args.build_xctest, "xctest"),
            (args.build_lldb, "lldb"),
            (args.build_llbuild, "llbuild"),
            (args.build_libcxx, "libcxx"),
            (args.build_libdispatch, "libdispatch"),
            (args.build_libicu, "libicu")
        ]
        for (should_build, string_name) in conditional_subproject_configs:
            if not should_build and not self.args.infer_dependencies:
                impl_args += ["--skip-build-{}".format(string_name)]
            elif self.install_all:
                impl_args += ["--install-{}".format(string_name)]

        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_android:
            impl_args += ["--skip-build-android"]
        if not args.build_clang_tools_extra:
            impl_args += ["--skip-build-clang-tools-extra"]

        if not args.test and not args.long_test and not args.stress_test:
            impl_args += ["--skip-test-swift"]
        if not args.test:
            impl_args += [
                "--skip-test-cmark",
                "--skip-test-lldb",
                "--skip-test-llbuild",
                "--skip-test-xctest",
                "--skip-test-foundation",
                "--skip-test-libdispatch",
                "--skip-test-libicu",
            ]
        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 args.stress_test:
            impl_args += ["--stress-test"]
        if args.skip_local_build:
            impl_args += ["--skip-local-build"]
        if args.only_executable_test:
            impl_args += ["--only-executable-test"]
        if not args.benchmark:
            impl_args += ["--skip-test-benchmarks"]
        if args.build_libparser_only:
            impl_args += ["--build-libparser-only"]
        if args.android:
            impl_args += [
                "--android-arch", args.android_arch,
                "--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,
                "--android-icu-data", args.android_icu_data,
            ]
        # If building natively on an Android host, only pass the API level.
        if StdlibDeploymentTarget.Android.contains(StdlibDeploymentTarget
                                                   .host_target().name):
            impl_args += ["--android-api-level", args.android_api_level]
        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,
            ]

            # Isolate build from the system; Darwin toolchains build against SDKs.
            # For additional isolation, disable pkg-config. Homebrew's pkg-config
            # prioritizes CommandLineTools paths, resulting in compile errors.
            args.extra_cmake_options += [
                '-DCMAKE_IGNORE_PATH=/usr/lib;/usr/local/lib;/lib',
                '-DPKG_CONFIG_EXECUTABLE=/usr/bin/false',
            ]

        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=%s" % ';'.join(args.extra_swift_args)
            ]

        # Enable macCatalyst
        if args.maccatalyst:
            (args.extra_cmake_options
             .append('-DSWIFT_ENABLE_MACCATALYST:BOOL=TRUE'))
        if args.maccatalyst_ios_tests:
            impl_args += ["--darwin-test-maccatalyst-ios-like=1"]

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

        if args.llvm_install_components:
            impl_args += [
                "--llvm-install-components=%s" % args.llvm_install_components
            ]

        # 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.
            try:
                config = HostSpecificConfiguration(host_target, args)
            except argparse.ArgumentError as e:
                exit_rejecting_arguments(six.text_type(e))

            # 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, list)

        Compute the list first of all build-script-impl products and then all
        non-build-script-impl products. It is assumed that concatenating the two
        lists together will result in a valid dependency graph for the
        compilation.

        """

        # FIXME: This is a weird division (returning a list of class objects),
        # but it matches the existing structure of the `build-script-impl`.
        impl_product_classes = []
        if self.args.build_cmark:
            impl_product_classes.append(products.CMark)

        # If --skip-build-llvm is passed in, LLVM cannot be completely disabled, as
        # Swift still needs a few LLVM targets like tblgen to be built for it to be
        # configured. Instead, handle this in build-script-impl for now.
        impl_product_classes.append(products.LLVM)
        if self.args.build_libcxx:
            impl_product_classes.append(products.LibCXX)
        if self.args.build_libicu:
            impl_product_classes.append(products.LibICU)
        if self.args.build_swift:
            impl_product_classes.append(products.Swift)
        if self.args.build_lldb:
            impl_product_classes.append(products.LLDB)
        if self.args.build_libdispatch:
            impl_product_classes.append(products.LibDispatch)
        if self.args.build_foundation:
            impl_product_classes.append(products.Foundation)
        if self.args.build_xctest:
            impl_product_classes.append(products.XCTest)
        if self.args.build_llbuild:
            impl_product_classes.append(products.LLBuild)
        # Sanity check that all of our impl classes are actually
        # build_script_impl products.
        for prod in impl_product_classes:
            assert(prod.is_build_script_impl_product())

        product_classes = []
        if self.args.build_swiftpm:
            product_classes.append(products.SwiftPM)
        if self.args.build_swift_driver or self.args.install_swift_driver:
            product_classes.append(products.SwiftDriver)
        if self.args.build_swiftsyntax:
            product_classes.append(products.SwiftSyntax)
        if self.args.build_skstresstester:
            product_classes.append(products.SKStressTester)
        if self.args.build_swiftformat:
            product_classes.append(products.SwiftFormat)
        if self.args.build_swiftevolve:
            product_classes.append(products.SwiftEvolve)
        if self.args.build_indexstoredb:
            product_classes.append(products.IndexStoreDB)
        if self.args.build_playgroundsupport:
            product_classes.append(products.PlaygroundSupport)
        if self.args.build_tensorflow_swift_apis:
            product_classes.append(products.TensorFlowSwiftAPIs)
        if self.args.build_sourcekitlsp:
            product_classes.append(products.SourceKitLSP)
        if self.args.build_toolchainbenchmarks:
            product_classes.append(products.Benchmarks)
        if self.args.build_swift_inspect:
            product_classes.append(products.SwiftInspect)
        if self.args.tsan_libdispatch_test:
            product_classes.append(products.TSanLibDispatch)
        # Sanity check that all of our non-impl classes are actually
        # not build_script_impl products.
        for prod in product_classes:
            assert(not prod.is_build_script_impl_product())

        # Now that we have our two lists of product_classes, if we are asked to
        # infer dependencies, infer the dependencies now and then re-split the
        # list.
        if self.args.infer_dependencies:
            combined = impl_product_classes + product_classes
            if self.args.verbose_build:
                print("-- Build Graph Inference --")
                print("Initial Product List:")
                for p in combined:
                    print("    {}".format(p.product_name()))

            # Now that we have produced the schedule, resplit. We require our
            # dependencies to respect our build-script-impl property. This means
            # that no build-script-impl products can have dependencies on
            # non-build-script-impl products. Otherwise, it would be unsafe to
            # re-order build-script-impl products in front of non
            # build-script-impl products.
            impl_product_classes = []
            product_classes = []
            is_darwin = platform.system() == 'Darwin'
            final_schedule = build_graph.produce_scheduled_build(combined)[0]
            for p in final_schedule:
                if is_darwin and p.is_nondarwin_only_build_product():
                    continue

                if p.is_build_script_impl_product():
                    impl_product_classes.append(p)
                else:
                    product_classes.append(p)
            if self.args.verbose_build:
                print("Final Build Order:")
                for p in impl_product_classes:
                    print("    {}".format(p.product_name()))
                for p in product_classes:
                    print("    {}".format(p.product_name()))
        return (impl_product_classes, product_classes)

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

        # Convert to a build-script-impl invocation.
        (self.impl_env, self.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.
            shell.call_without_sleeping([BUILD_SCRIPT_IMPL_PATH] + self.impl_args,
                                        env=self.impl_env, echo=True)
            return

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

        # 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`.
        (impl_product_classes, product_classes) = self.compute_product_classes()

        # Execute each "pass".

        # Build...
        for host_target in all_hosts:
            # FIXME: We should only compute these once.
            try:
                config = HostSpecificConfiguration(host_target.name, self.args)
            except argparse.ArgumentError as e:
                exit_rejecting_arguments(six.text_type(e))
            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 impl_product_classes:
                self._execute_build_action(host_target, product_class)

        # Test...
        for host_target in all_hosts:
            for product_class in impl_product_classes:
                self._execute_test_action(host_target, product_class)

        # Install...
        for host_target in all_hosts:
            for product_class in impl_product_classes:
                self._execute_install_action(host_target, product_class)

        # Core Lipo...
        self._execute_merged_host_lipo_core_action()

        # Non-build-script-impl products...
        # Note: currently only supports building for the host.
        for host_target in [self.args.host_target]:
            for product_class in product_classes:
                if product_class.is_build_script_impl_product():
                    continue
                product_source = product_class.product_source_name()
                product_name = product_class.product_name()
                if product_class.is_swiftpm_unified_build_product():
                    build_dir = self.workspace.swiftpm_unified_build_dir(
                        host_target)
                else:
                    build_dir = self.workspace.build_dir(
                        host_target, product_name)
                product = product_class(
                    args=self.args,
                    toolchain=self.toolchain,
                    source_dir=self.workspace.source_dir(product_source),
                    build_dir=build_dir)
                if product.should_clean(host_target):
                    print("--- Cleaning %s ---" % product_name)
                    product.clean(host_target)
                if product.should_build(host_target):
                    print("--- Building %s ---" % product_name)
                    product.build(host_target)
                if product.should_test(host_target):
                    print("--- Running tests for %s ---" % product_name)
                    product.test(host_target)
                    print("--- Finished tests for %s ---" % product_name)
                if product.should_install(host_target) or \
                   (self.install_all and product.should_build(host_target)):
                    print("--- Installing %s ---" % product_name)
                    product.install(host_target)

        # Extract symbols...
        for host_target in all_hosts:
            self._execute_extract_symbols_action(host_target)

        # Package...
        for host_target in all_hosts:
            self._execute_package_action(host_target)

        # Lipo...
        self._execute_merged_host_lipo_action()

    def _execute_build_action(self, host_target, product_class):
        action_name = "{}-{}-build".format(host_target.name,
                                           product_class.product_name())
        self._execute_action(action_name)

    def _execute_test_action(self, host_target, product_class):
        action_name = "{}-{}-test".format(host_target.name,
                                          product_class.product_name())
        self._execute_action(action_name)

    def _execute_install_action(self, host_target, product_class):
        action_name = "{}-{}-install".format(host_target.name,
                                             product_class.product_name())
        self._execute_action(action_name)

    def _execute_extract_symbols_action(self, host_target):
        action_name = "{}-extractsymbols".format(host_target.name)
        self._execute_action(action_name)

    def _execute_package_action(self, host_target):
        action_name = "{}-package".format(host_target.name)
        self._execute_action(action_name)

    def _execute_merged_host_lipo_action(self):
        self._execute_action("merged-hosts-lipo")

    def _execute_merged_host_lipo_core_action(self):
        self._execute_action("merged-hosts-lipo-core")

    def _execute_action(self, action_name):
        shell.call_without_sleeping(
            [BUILD_SCRIPT_IMPL_PATH] + self.impl_args +
            ["--only-execute", action_name],
            env=self.impl_env, echo=self.args.verbose_build)


# -----------------------------------------------------------------------------
# Main (preset)

def parse_preset_args():
    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=argparse.actions.StoreTrueAction,
        nargs=argparse.Nargs.OPTIONAL)
    parser.add_argument(
        "--distcc",
        help="use distcc",
        action=argparse.actions.StoreTrueAction,
        nargs=argparse.Nargs.OPTIONAL,
        default=os.environ.get('USE_DISTCC') == '1')
    parser.add_argument(
        "--sccache",
        help="use sccache",
        action=argparse.actions.StoreTrueAction,
        nargs=argparse.Nargs.OPTIONAL,
        default=os.environ.get('SWIFT_USE_SCCACHE') == '1')
    parser.add_argument(
        "--cmake-c-launcher",
        help="the absolute path to set CMAKE_C_COMPILER_LAUNCHER",
        metavar="PATH")
    parser.add_argument(
        "--cmake-cxx-launcher",
        help="the absolute path to set CMAKE_CXX_COMPILER_LAUNCHER",
        metavar="PATH")
    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-invocation", "--expand-build-script-invocation",
        help="Print the expanded build-script invocation generated "
             "by the preset, but do not run the preset",
        action=argparse.actions.StoreTrueAction,
        nargs=argparse.Nargs.OPTIONAL)
    parser.add_argument(
        "--swiftsyntax-install-prefix",
        help="specify the directory to where SwiftSyntax should be installed")
    parser.add_argument(
        "--build-dir",
        help="specify the directory where build artifact should be stored")
    parser.add_argument(
        "--dump-config",
        help="instead of building, write JSON to stdout containing "
             "various values used to build in this configuration",
        action="store_true",
        default=False)
    parser.add_argument(
        "--reconfigure",
        help="Reconfigure all projects as we build",
        action="store_true",
        default=False)

    return parser.parse_args()


def main_preset():
    args = parse_preset_args()

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

        user_presets_file = os.path.join(os.getenv("HOME", "/"),
                                         '.swift-build-presets')
        if os.path.isfile(user_presets_file):
            args.preset_file_names.append(user_presets_file)

    preset_parser = presets.PresetParser()

    try:
        preset_parser.read_files(args.preset_file_names)
    except presets.PresetError as e:
        fatal_error(six.text_type(e))

    if args.show_presets:
        for name in sorted(preset_parser.preset_names,
                           key=lambda name: name.lower()):
            print(name)
        return 0

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

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

    try:
        preset = preset_parser.get_preset(
            args.preset,
            vars=args.preset_substitutions)
    except presets.PresetError as e:
        fatal_error(six.text_type(e))

    preset_args = migration.migrate_swift_sdks(preset.args)

    if args.distcc and (args.cmake_c_launcher or args.cmake_cxx_launcher):
        fatal_error(
            '--distcc can not be used with' +
            ' --cmake-c-launcher or --cmake-cxx-launcher')
    if args.sccache and (args.cmake_c_launcher or args.cmake_cxx_launcher):
        fatal_error(
            '--sccache can not be used with' +
            ' --cmake-c-launcher or --cmake-cxx-launcher')

    build_script_args = [sys.argv[0]]
    if args.dry_run:
        build_script_args += ["--dry-run"]
    if args.dump_config:
        build_script_args += ["--dump-config"]

    build_script_args += preset_args
    if args.distcc:
        build_script_args += ["--distcc"]
    if args.sccache:
        build_script_args += ["--sccache"]
    if args.build_jobs:
        build_script_args += ["--jobs", str(args.build_jobs)]
    if args.swiftsyntax_install_prefix:
        build_script_args += ["--install-swiftsyntax",
                              "--install-destdir",
                              args.swiftsyntax_install_prefix]
    if args.build_dir:
        build_script_args += ["--build-dir", args.build_dir]
    if args.cmake_c_launcher:
        build_script_args += ["--cmake-c-launcher", args.cmake_c_launcher]
    if args.cmake_cxx_launcher:
        build_script_args += ["--cmake-cxx-launcher", args.cmake_cxx_launcher]
    printable_command = shell.quote_command(build_script_args)
    if args.expand_invocation:
        print(printable_command)
        return 0

    if args.reconfigure:
        build_script_args += ["--reconfigure"]

    print_note('using preset "{}", which expands to \n\n{}\n'.format(
        args.preset, printable_command))
    shell.call_without_sleeping(build_script_args)
    return 0


# -----------------------------------------------------------------------------
# Main (normal)

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_PATH,
                                      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
    if args.darwin_xcrun_toolchain is None:
        xcrun_toolchain = os.environ.get('TOOLCHAINS',
                                         defaults.DARWIN_XCRUN_TOOLCHAIN)

        print_note('Using toolchain {}'.format(xcrun_toolchain))
        args.darwin_xcrun_toolchain = xcrun_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

    cmake = CMake(args=args, toolchain=toolchain)
    # Check the CMake version is sufficient on Linux and build from source
    # if not.
    cmake_path = cmake.check_cmake_version(SWIFT_SOURCE_ROOT, SWIFT_BUILD_ROOT)
    if cmake_path is not None:
        toolchain.cmake = cmake_path
        args.cmake = cmake_path

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

    # Validate the arguments.
    validate_arguments(toolchain, args)

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

    # Sanitize the runtime environment.
    initialize_runtime_environment()

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

    if args.dump_config:
        print(JSONDumper().encode(invocation))
        return 0

    # 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)
            prefix = os.path.join(args.host_target, prefix.lstrip('/'))
        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(source=prefix.lstrip('/'),
                destination=args.symbols_package)

    return 0


# -----------------------------------------------------------------------------

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

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

    validate_xcode_compatibility()

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