#!/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 json
import os
import pipes
import platform
import sys
import time

from build_swift import defaults
from build_swift import driver_arguments
from build_swift import presets
from build_swift.migration import migrate_swift_sdks

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

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.


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

    def default(self, o):
        return vars(o)


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

        # SWIFT_ENABLE_TENSORFLOW
        if args.enable_tensorflow:
            if toolchain.bazel is None:
                diagnostics.fatal(
                    "can't find bazel, needed to build TensorFlow (please "
                    "install bazel)")

        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 or \
                    args.android_icu_data is None:
                diagnostics.fatal(
                    "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_sourcekitlsp',
            'build_toolchainbenchmarks',
            '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:
            diagnostics.fatal(
                "--legacy-impl is incompatible with building packages needing "
                "a toolchain (%s)" % ", ".join(targets_needing_toolchain))

        # SWIFT_ENABLE_TENSORFLOW
        if args.enable_tensorflow:
            tensorflow_libs = ["libtensorflow.so"]
            tensorflow_dirs = [
                ("tensorflow_host_lib_dir", True),
                ("tensorflow_host_include_dir", False),
                ("tensorflow_target_lib_dir", True),
                ("tensorflow_target_include_dir", False),
            ]
            tensorflow_dirs = [d for d in tensorflow_dirs
                               if getattr(args, d[0]) is not None]
            for dirname, is_lib_dir in tensorflow_dirs:
                tensorflow_dir = getattr(args, dirname)
                if not os.path.isdir(tensorflow_dir):
                    diagnostics.fatal(
                        "--{} does not exist (was '{}')"
                        .format(dirname, tensorflow_dir))
                if is_lib_dir:
                    for lib in tensorflow_libs:
                        if not os.path.exists(
                                os.path.join(tensorflow_dir, lib)):
                            diagnostics.fatal(
                                "--{} does not contain '{}' (was '{}')"
                                .format(dirname, lib, tensorflow_dir))

            if args.build_tensorflow and \
               args.tensorflow_host_lib_dir is not None and \
                args.tensorflow_host_include_dir is not None:
                diagnostics.fatal(
                    "when building with TensorFlow support, cannot specify "
                    " --build-tensorflow (to build TensorFlow from source) at "
                    "the same time as --tensorflow-host-lib-dir and "
                    "--tensorflow-host-include-dir (to use custom TensorFlow "
                    "headers/libraries); please pick one")

            if args.tensorflow_swift_apis is not None:
                if not os.path.isdir(args.tensorflow_swift_apis):
                    diagnostics.fatal(
                        "invalid repository specified for "
                        "--tensorflow-swift-apis (was '{}')"
                        .format(args.tensorflow_swift_apis))

        if args.enable_tensorflow_gpu:
            os.environ['TF_NEED_CUDA'] = '1'
            if '--config=cuda' not in args.tensorflow_bazel_options:
                args.tensorflow_bazel_options += ['--config=cuda']

            # Warn if TensorFlow GPU support environmental variable is not
            # specified.
            def warn_unspecified_tensorflow_env_var(name):
                if name not in os.environ:
                    diagnostics.note(
                        "'{}' environment variable was not specified; "
                        "TensorFlow configure script default will be used"
                        .format(name))
            warn_unspecified_tensorflow_env_var('TF_CUDA_VERSION')
            warn_unspecified_tensorflow_env_var('TF_CUDNN_VERSION')
            warn_unspecified_tensorflow_env_var('CUDA_TOOLKIT_PATH')
            warn_unspecified_tensorflow_env_var('CUDNN_INSTALL_PATH')


    @staticmethod
    def apply_default_arguments(toolchain, args):
        # Infer if ninja is required
        ninja_required = (
            args.cmake_generator == 'Ninja' or args.build_foundation or
            args.build_sourcekitlsp or args.build_indexstoredb)
        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 = \
                StdlibDeploymentTarget.default_stdlib_deployment_targets()
            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)

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

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

        # SWIFT_ENABLE_TENSORFLOW
        if args.enable_tensorflow_gpu:
           args.enable_tensorflow = True

        if args.enable_tensorflow:
            if args.tensorflow_host_lib_dir is None and \
               args.tensorflow_host_include_dir is None:
                args.build_tensorflow = True
            elif args.tensorflow_host_lib_dir is not None and \
                 args.tensorflow_host_include_dir is not None:
                args.build_tensorflow = False

# ---

    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

    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)

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

    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.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,
            "--swiftpm-build-type", args.build_variant,
            "--swiftsyntax-build-type", args.build_variant,
            "--skstresstester-build-type", args.build_variant,
            "--swiftevolve-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()),
        ]

        # Compute any product specific cmake arguments.
        for product_class in 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):
                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

            # SWIFT_ENABLE_TENSORFLOW
            # TensorFlow is not built using CMake and has no CMake options.
            if product_class is products.TensorFlow:
                continue

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

        # *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-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_libcxx:
            impl_args += ["--skip-build-libcxx"]
        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_swiftsyntax:
            impl_args += ["--skip-build-swiftsyntax"]
        if not args.build_skstresstester:
            impl_args += ["--skip-build-skstresstester"]
        if not args.build_swiftevolve:
            impl_args += ["--skip-build-swiftevolve"]
        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 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-swiftpm",
                          "--skip-test-swiftsyntax",
                          "--skip-test-skstresstester",
                          "--skip-test-swiftevolve",
                          "--skip-test-xctest",
                          "--skip-test-foundation",
                          "--skip-test-libdispatch",
                          "--skip-test-libicu",
                          "--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:
            impl_args += ["--skip-test-android"]
        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 args.stress_test:
            impl_args += ["--stress-test"]
        if args.only_executable_test:
            impl_args += ["--only-executable-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 not args.test_optimize_none_with_implicit_dynamic:
            impl_args += ["--skip-test-optimize-none-with-implicit-dynamic"]
        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 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=%s" % ';'.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)
                ]

        # SWIFT_ENABLE_TENSORFLOW
        if not args.build_tensorflow:
            impl_args += ["--skip-build-tensorflow"]

        if args.enable_tensorflow_gpu:
            impl_args += ["--enable-tensorflow-gpu"]

        if args.enable_tensorflow:
            impl_args += [
                "--enable-tensorflow",
                "--host-bazel", toolchain.bazel,
            ]
            print(impl_args)
            # If args.build-tensorflow, include/lib directories will be
            # configured automatically by build-script-impl.
            if not args.build_tensorflow:
                assert args.tensorflow_host_lib_dir, \
                    "Missing --tensorflow-host-lib-dir"
                assert args.tensorflow_host_include_dir, \
                    "Missing --tensorflow-host-include-dir"
                impl_args += [
                    "--tensorflow-host-lib-dir",
                    args.tensorflow_host_lib_dir,
                    "--tensorflow-host-include-dir",
                    args.tensorflow_host_include_dir,
                ]
                if args.tensorflow_target_lib_dir:
                    impl_args += [
                        "--tensorflow-target-lib-dir",
                        args.tensorflow_target_lib_dir,
                    ]
                if args.tensorflow_target_include_dir:
                    impl_args += [
                        "--tensorflow-target-include-dir",
                        args.tensorflow_target_include_dir,
                    ]
        if args.tensorflow_bazel_options:
            impl_args += [
                "--tensorflow-bazel-options=%s" % ' '.join(
                    pipes.quote(opt) for opt in args.tensorflow_bazel_options)
            ]

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

            # 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_libcxx:
            product_classes.append(products.LibCXX)
        if self.args.build_libicu:
            product_classes.append(products.LibICU)
        # SWIFT_ENABLE_TENSORFLOW
        if self.args.build_tensorflow:
            product_classes.append(products.TensorFlow)
        product_classes.append(products.Swift)
        if self.args.build_lldb:
            product_classes.append(products.LLDB)
        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_llbuild:
            product_classes.append(products.LLBuild)
        if self.args.build_swiftpm:
            product_classes.append(products.SwiftPM)
        if self.args.build_swiftsyntax:
            product_classes.append(products.SwiftSyntax)
        if self.args.build_skstresstester:
            product_classes.append(products.SKStressTester)
        if self.args.build_swiftevolve:
            product_classes.append(products.SwiftEvolve)
        if self.args.build_indexstoredb:
            product_classes.append(products.IndexStoreDB)
        if self.args.build_sourcekitlsp:
            product_classes.append(products.SourceKitLSP)
        if self.args.build_toolchainbenchmarks:
            product_classes.append(products.Benchmarks)
        if self.args.tsan_libdispatch_test:
            product_classes.append(products.TSanLibDispatch)
        return 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] + 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`.
        product_classes = self.compute_product_classes()

        impl_product_classes = [cls for cls in product_classes
                                if cls.is_build_script_impl_product()]

        # 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(e.message)
            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)

        # 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()
                product = product_class(
                    args=self.args,
                    toolchain=self.toolchain,
                    source_dir=self.workspace.source_dir(product_source),
                    build_dir=self.workspace.build_dir(
                        host_target, product_name))
                product.build(host_target)
                product.test(host_target)
                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_action(self, action_name):
        shell.call_without_sleeping(
            [build_script_impl] + self.impl_args +
            ["--only-execute", action_name],
            env=self.impl_env, echo=self.args.verbose_build)


# 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(
        "--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=arguments.action.optional_bool)
    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)
    args = parser.parse_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(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(args.preset_file_names)
    except presets.Error as e:
        diagnostics.fatal(e.message)

    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:
        diagnostics.fatal("missing --preset option")

    args.preset_substitutions = {
      'home': os.path.expanduser("~")
    }

    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.Error as e:
        diagnostics.fatal(e.message)

    preset_args = migrate_swift_sdks(preset.format_args())

    if args.distcc and (args.cmake_c_launcher or args.cmake_cxx_launcher):
        diagnostics.fatal(
            '--distcc 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.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"]

    diagnostics.note('using preset "{}", which expands to \n\n{}\n'.format(
        args.preset, printable_command))
    shell.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
    if args.darwin_xcrun_toolchain is None:
        xcrun_toolchain = os.environ.get('TOOLCHAINS',
                                         defaults.DARWIN_XCRUN_TOOLCHAIN)

        diagnostics.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
    # SWIFT_ENABLE_TENSORFLOW
    if args.host_bazel is not None:
        toolchain.bazel = args.host_bazel

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

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