#! /usr/bin/env python

from __future__ import print_function

import argparse
import os
import signal
import subprocess
import sys

if sys.platform == 'win32':
    # This module was renamed in Python 3.  Make sure to import it using a
    # consistent name regardless of python version.
    try:
        import winreg
    except:
        import _winreg as winreg

if __name__ != "__main__":
    raise RuntimeError("Do not import this script, run it instead")


parser = argparse.ArgumentParser(description='LLDB compilation wrapper')
parser.add_argument('--arch',
                    metavar='arch',
                    dest='arch',
                    required=True,
                    default='host',
                    choices=['32', '64', 'host'],
                    help='Specify the architecture to target.')

parser.add_argument('--compiler',
                    metavar='compiler',
                    dest='compiler',
                    required=True,
                    help='Path to a compiler executable, or one of the values [any, msvc, clang-cl, gcc, clang]')

parser.add_argument('--tools-dir',
                    metavar='directory',
                    dest='tools_dir',
                    required=False,
                    action='append',
                    help='If specified, a path to search in addition to PATH when --compiler is not an exact path')

if sys.platform == 'darwin':
    parser.add_argument('--apple-sdk',
                        metavar='apple_sdk',
                        dest='apple_sdk',
                        default="macosx",
                        help='Specify the name of the Apple SDK (macosx, macosx.internal, iphoneos, iphoneos.internal, or path to SDK) and use the appropriate tools from that SDK\'s toolchain.')

parser.add_argument('--output', '-o',
                    dest='output',
                    metavar='file',
                    required=False,
                    default='',
                    help='Path to output file')

parser.add_argument('--outdir', '-d',
                    dest='outdir',
                    metavar='directory',
                    required=False,
                    help='Directory for output files')

parser.add_argument('--nodefaultlib',
                    dest='nodefaultlib',
                    action='store_true',
                    default=False,
                    help='When specified, the resulting image should not link against system libraries or include system headers.  Useful when writing cross-targeting tests.')

parser.add_argument('--opt',
                    dest='opt',
                    default='none',
                    choices=['none', 'basic', 'lto'],
                    help='Optimization level')

parser.add_argument('--mode',
                    dest='mode',
                    default='compile-and-link',
                    choices=['compile', 'link', 'compile-and-link'],
                    help='Specifies whether to compile, link, or both')

parser.add_argument('--noclean',
                    dest='clean',
                    action='store_false',
                    default=True,
                    help='Dont clean output file before building')

parser.add_argument('--verbose',
                    dest='verbose',
                    action='store_true',
                    default=False,
                    help='Print verbose output')

parser.add_argument('-n', '--dry-run',
                    dest='dry',
                    action='store_true',
                    default=False,
                    help='Print the commands that would run, but dont actually run them')

parser.add_argument('inputs',
                    metavar='file',
                    nargs='+',
                    help='Source file(s) to compile / object file(s) to link')


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


def to_string(b):
    """Return the parameter as type 'str', possibly encoding it.

    In Python2, the 'str' type is the same as 'bytes'. In Python3, the
    'str' type is (essentially) Python2's 'unicode' type, and 'bytes' is
    distinct.

    This function is copied from llvm/utils/lit/lit/util.py
    """
    if isinstance(b, str):
        # In Python2, this branch is taken for types 'str' and 'bytes'.
        # In Python3, this branch is taken only for 'str'.
        return b
    if isinstance(b, bytes):
        # In Python2, this branch is never taken ('bytes' is handled as 'str').
        # In Python3, this is true only for 'bytes'.
        try:
            return b.decode('utf-8')
        except UnicodeDecodeError:
            # If the value is not valid Unicode, return the default
            # repr-line encoding.
            return str(b)

    # By this point, here's what we *don't* have:
    #
    #  - In Python2:
    #    - 'str' or 'bytes' (1st branch above)
    #  - In Python3:
    #    - 'str' (1st branch above)
    #    - 'bytes' (2nd branch above)
    #
    # The last type we might expect is the Python2 'unicode' type. There is no
    # 'unicode' type in Python3 (all the Python3 cases were already handled). In
    # order to get a 'str' object, we need to encode the 'unicode' object.
    try:
        return b.encode('utf-8')
    except AttributeError:
        raise TypeError('not sure how to convert %s to %s' % (type(b), str))

def format_text(lines, indent_0, indent_n):
    result = ' ' * indent_0 + lines[0]
    for next in lines[1:]:
        result = result + '\n{0}{1}'.format(' ' * indent_n, next)
    return result

def print_environment(env):
    if env is None:
        print('    Inherited')
        return
    for e in env:
        value = env[e]
        lines = value.split(os.pathsep)
        formatted_value = format_text(lines, 0, 7 + len(e))
        print('    {0} = {1}'.format(e, formatted_value))

def find_executable(binary_name, search_paths):
    if sys.platform == 'win32':
        binary_name = binary_name + '.exe'

    search_paths = os.pathsep.join(search_paths)
    paths = search_paths + os.pathsep + os.environ.get('PATH', '')
    for path in paths.split(os.pathsep):
        p = os.path.join(path, binary_name)
        if os.path.exists(p) and not os.path.isdir(p):
            return os.path.normpath(p)
    return None

def find_toolchain(compiler, tools_dir):
    if compiler == 'msvc':
        return ('msvc', find_executable('cl', tools_dir))
    if compiler == 'clang-cl':
        return ('clang-cl', find_executable('clang-cl', tools_dir))
    if compiler == 'gcc':
        return ('gcc', find_executable('g++', tools_dir))
    if compiler == 'clang':
        return ('clang', find_executable('clang++', tools_dir))
    if compiler == 'any':
        priorities = []
        if sys.platform == 'win32':
            priorities = ['clang-cl', 'msvc', 'clang', 'gcc']
        else:
            priorities = ['clang', 'gcc', 'clang-cl']
        for toolchain in priorities:
            (type, dir) = find_toolchain(toolchain, tools_dir)
            if type and dir:
                return (type, dir)
        # Could not find any toolchain.
        return (None, None)

    # From here on, assume that |compiler| is a path to a file.
    file = os.path.basename(compiler)
    name, ext = os.path.splitext(file)
    if file.lower() == 'cl.exe':
        return 'msvc'
    if name == 'clang-cl':
        return 'clang-cl'
    if name.startswith('clang'):
        return 'clang'
    if name.startswith('gcc') or name.startswith('g++'):
        return 'gcc'
    if name == 'cc' or name == 'c++':
        return 'generic'
    return 'unknown'

class Builder(object):
    def __init__(self, toolchain_type, args, obj_ext):
        self.toolchain_type = toolchain_type
        self.inputs = args.inputs
        self.arch = args.arch
        self.opt = args.opt
        self.outdir = args.outdir
        self.compiler = args.compiler
        self.clean = args.clean
        self.output = args.output
        self.mode = args.mode
        self.nodefaultlib = args.nodefaultlib
        self.verbose = args.verbose
        self.obj_ext = obj_ext

    def _exe_file_name(self):
        assert self.mode != 'compile'
        return self.output

    def _output_name(self, input, extension, with_executable=False):
        basename = os.path.splitext(os.path.basename(input))[0] + extension
        if with_executable:
            exe_basename = os.path.basename(self._exe_file_name())
            basename = exe_basename + '-' + basename

        output = os.path.join(self.outdir, basename)
        return os.path.normpath(output)

    def _obj_file_names(self):
        if self.mode == 'link':
            return self.inputs

        if self.mode == 'compile-and-link':
            # Object file names should factor in both the input file (source)
            # name and output file (executable) name, to ensure that two tests
            # which share a common source file don't race to write the same
            # object file.
            return [self._output_name(x, self.obj_ext, True) for x in self.inputs]

        if self.mode == 'compile' and self.output:
            return [self.output]

        return [self._output_name(x, self.obj_ext) for x in self.inputs]

    def build_commands(self):
        commands = []
        if self.mode == 'compile' or self.mode == 'compile-and-link':
            for input, output in zip(self.inputs, self._obj_file_names()):
                commands.append(self._get_compilation_command(input, output))
        if self.mode == 'link' or self.mode == 'compile-and-link':
            commands.append(self._get_link_command())
        return commands


class MsvcBuilder(Builder):
    def __init__(self, toolchain_type, args):
        Builder.__init__(self, toolchain_type, args, '.obj')

        self.msvc_arch_str = 'x86' if self.arch == '32' else 'x64'

        if toolchain_type == 'msvc':
            # Make sure we're using the appropriate toolchain for the desired
            # target type.
            compiler_parent_dir = os.path.dirname(self.compiler)
            selected_target_version = os.path.basename(compiler_parent_dir)
            if selected_target_version != self.msvc_arch_str:
                host_dir = os.path.dirname(compiler_parent_dir)
                self.compiler = os.path.join(host_dir, self.msvc_arch_str, 'cl.exe')
                if self.verbose:
                    print('Using alternate compiler "{0}" to match selected target.'.format(self.compiler))

        if self.mode == 'link' or self.mode == 'compile-and-link':
            self.linker = self._find_linker('link') if toolchain_type == 'msvc' else self._find_linker('lld-link', args.tools_dir)
            if not self.linker:
                raise ValueError('Unable to find an appropriate linker.')

        self.compile_env, self.link_env = self._get_visual_studio_environment()

    def _find_linker(self, name, search_paths=[]):
        compiler_dir = os.path.dirname(self.compiler)
        linker_path = find_executable(name, [compiler_dir] + search_paths)
        if linker_path is None:
            raise ValueError('Could not find \'{}\''.format(name))
        return linker_path

    def _get_vc_install_dir(self):
        dir = os.getenv('VCINSTALLDIR', None)
        if dir:
            if self.verbose:
                print('Using %VCINSTALLDIR% {}'.format(dir))
            return dir

        dir = os.getenv('VSINSTALLDIR', None)
        if dir:
            if self.verbose:
                print('Using %VSINSTALLDIR% {}'.format(dir))
            return os.path.join(dir, 'VC')

        dir = os.getenv('VS2019INSTALLDIR', None)
        if dir:
            if self.verbose:
                print('Using %VS2019INSTALLDIR% {}'.format(dir))
            return os.path.join(dir, 'VC')

        dir = os.getenv('VS2017INSTALLDIR', None)
        if dir:
            if self.verbose:
                print('Using %VS2017INSTALLDIR% {}'.format(dir))
            return os.path.join(dir, 'VC')

        dir = os.getenv('VS2015INSTALLDIR', None)
        if dir:
            if self.verbose:
                print('Using %VS2015INSTALLDIR% {}'.format(dir))
            return os.path.join(dir, 'VC')
        return None

    def _get_vctools_version(self):
        ver = os.getenv('VCToolsVersion', None)
        if ver:
            if self.verbose:
                print('Using %VCToolsVersion% {}'.format(ver))
            return ver

        vcinstalldir = self._get_vc_install_dir()
        vcinstalldir = os.path.join(vcinstalldir, 'Tools', 'MSVC')
        subdirs = next(os.walk(vcinstalldir))[1]
        if not subdirs:
            return None

        from distutils.version import StrictVersion
        subdirs.sort(key=lambda x : StrictVersion(x))

        if self.verbose:
            full_path = os.path.join(vcinstalldir, subdirs[-1])
            print('Using VC tools version directory {0} found by directory walk.'.format(full_path))
        return subdirs[-1]

    def _get_vctools_install_dir(self):
        dir = os.getenv('VCToolsInstallDir', None)
        if dir:
            if self.verbose:
                print('Using %VCToolsInstallDir% {}'.format(dir))
            return dir

        vcinstalldir = self._get_vc_install_dir()
        if not vcinstalldir:
            return None
        vctoolsver = self._get_vctools_version()
        if not vctoolsver:
            return None
        result = os.path.join(vcinstalldir, 'Tools', 'MSVC', vctoolsver)
        if not os.path.exists(result):
            return None
        if self.verbose:
            print('Using VC tools install dir {} found by directory walk'.format(result))
        return result

    def _find_windows_sdk_in_registry_view(self, view):
        products_key = None
        roots_key = None
        installed_options_keys = []
        try:
            sam = view | winreg.KEY_READ
            products_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                                          r'Software\Microsoft\Windows Kits\Installed Products',
                                          0,
                                          sam)

            # This is the GUID for the desktop component.  If this is present
            # then the components required for the Desktop SDK are installed.
            # If not it will throw an exception.
            winreg.QueryValueEx(products_key, '{5A3D81EC-D870-9ECF-D997-24BDA6644752}')

            roots_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                                       r'Software\Microsoft\Windows Kits\Installed Roots',
                                       0,
                                       sam)
            root_dir = winreg.QueryValueEx(roots_key, 'KitsRoot10')
            root_dir = to_string(root_dir[0])
            sdk_versions = []
            index = 0
            while True:
                # Installed SDK versions are stored as sub-keys of the
                # 'Installed Roots' key.  Find all of their names, then sort
                # them by version
                try:
                    ver_key = winreg.EnumKey(roots_key, index)
                    sdk_versions.append(ver_key)
                    index = index + 1
                except WindowsError:
                    break
            if not sdk_versions:
                return (None, None)

            # Windows SDK version numbers consist of 4 dotted components, so we
            # have to use LooseVersion, as StrictVersion supports 3 or fewer.
            from distutils.version import LooseVersion
            sdk_versions.sort(key=lambda x : LooseVersion(x), reverse=True)
            option_value_name = 'OptionId.DesktopCPP' + self.msvc_arch_str
            for v in sdk_versions:
                try:
                    version_subkey = v + r'\Installed Options'
                    key = winreg.OpenKey(roots_key, version_subkey)
                    installed_options_keys.append(key)
                    (value, value_type) = winreg.QueryValueEx(key, option_value_name)
                    if value == 1:
                        # The proper architecture is installed.  Return the
                        # associated paths.
                        if self.verbose:
                            print('Found Installed Windows SDK v{0} at {1}'.format(v, root_dir))
                        return (root_dir, v)
                except:
                    continue
        except:
            return (None, None)
        finally:
            del products_key
            del roots_key
            for k in installed_options_keys:
                del k
        return (None, None)

    def _find_windows_sdk_in_registry(self):
        # This could be a clang-cl cross-compile.  If so, there's no registry
        # so just exit.
        if sys.platform != 'win32':
            return (None, None)
        if self.verbose:
            print('Looking for Windows SDK in 64-bit registry.')
        dir, ver = self._find_windows_sdk_in_registry_view(winreg.KEY_WOW64_64KEY)
        if not dir or not ver:
            if self.verbose:
                print('Looking for Windows SDK in 32-bit registry.')
            dir, ver = self._find_windows_sdk_in_registry_view(winreg.KEY_WOW64_32KEY)

        return (dir, ver)

    def _get_winsdk_dir(self):
        # If a Windows SDK is specified in the environment, use that.  Otherwise
        # try to find one in the Windows registry.
        dir = os.getenv('WindowsSdkDir', None)
        if not dir or not os.path.exists(dir):
            return self._find_windows_sdk_in_registry()
        ver = os.getenv('WindowsSDKLibVersion', None)
        if not ver:
            return self._find_windows_sdk_in_registry()

        ver = ver.rstrip('\\')
        if self.verbose:
            print('Using %WindowsSdkDir% {}'.format(dir))
            print('Using %WindowsSDKLibVersion% {}'.format(ver))
        return (dir, ver)

    def _get_msvc_native_toolchain_dir(self):
        assert self.toolchain_type == 'msvc'
        compiler_dir = os.path.dirname(self.compiler)
        target_dir = os.path.dirname(compiler_dir)
        host_name = os.path.basename(target_dir)
        host_name = host_name[4:].lower()
        return os.path.join(target_dir, host_name)

    def _get_visual_studio_environment(self):
        vctools = self._get_vctools_install_dir()
        winsdk, winsdkver = self._get_winsdk_dir()

        if not vctools and self.verbose:
            print('Unable to find VC tools installation directory.')
        if (not winsdk or not winsdkver) and self.verbose:
            print('Unable to find Windows SDK directory.')

        vcincludes = []
        vclibs = []
        sdkincludes = []
        sdklibs = []
        if vctools is not None:
            includes = [['ATLMFC', 'include'], ['include']]
            libs = [['ATLMFC', 'lib'], ['lib']]
            vcincludes = [os.path.join(vctools, *y) for y in includes]
            vclibs = [os.path.join(vctools, *y) for y in libs]
        if winsdk is not None:
            includes = [['include', winsdkver, 'ucrt'],
                        ['include', winsdkver, 'shared'],
                        ['include', winsdkver, 'um'],
                        ['include', winsdkver, 'winrt'],
                        ['include', winsdkver, 'cppwinrt']]
            libs = [['lib', winsdkver, 'ucrt'],
                    ['lib', winsdkver, 'um']]
            sdkincludes = [os.path.join(winsdk, *y) for y in includes]
            sdklibs = [os.path.join(winsdk, *y) for y in libs]

        includes = vcincludes + sdkincludes
        libs = vclibs + sdklibs
        libs = [os.path.join(x, self.msvc_arch_str) for x in libs]
        compileenv = None
        linkenv = None
        defaultenv = {}
        if sys.platform == 'win32':
            defaultenv = { x : os.environ[x] for x in
                          ['SystemDrive', 'SystemRoot', 'TMP', 'TEMP'] }
            # The directory to mspdbcore.dll needs to be in PATH, but this is
            # always in the native toolchain path, not the cross-toolchain
            # path.  So, for example, if we're using HostX64\x86 then we need
            # to add HostX64\x64 to the path, and if we're using HostX86\x64
            # then we need to add HostX86\x86 to the path.
            if self.toolchain_type == 'msvc':
                defaultenv['PATH'] = self._get_msvc_native_toolchain_dir()

        if includes:
            compileenv = {}
            compileenv['INCLUDE'] = os.pathsep.join(includes)
            compileenv.update(defaultenv)
        if libs:
            linkenv = {}
            linkenv['LIB'] = os.pathsep.join(libs)
            linkenv.update(defaultenv)
        return (compileenv, linkenv)

    def _ilk_file_names(self):
        if self.mode == 'link':
            return []

        return [self._output_name(x, '.ilk') for x in self.inputs]

    def _pdb_file_name(self):
        if self.mode == 'compile':
            return None
        return os.path.splitext(self.output)[0] + '.pdb'

    def _get_compilation_command(self, source, obj):
        args = []

        args.append(self.compiler)
        if self.toolchain_type == 'clang-cl':
            args.append('-m' + self.arch)

        if self.opt == 'none':
            args.append('/Od')
        elif self.opt == 'basic':
            args.append('/O2')
        elif self.opt == 'lto':
            if self.toolchain_type == 'msvc':
                args.append('/GL')
                args.append('/Gw')
            else:
                args.append('-flto=thin')
        if self.nodefaultlib:
            args.append('/GS-')
            args.append('/GR-')
        args.append('/Z7')
        if self.toolchain_type == 'clang-cl':
            args.append('-Xclang')
            args.append('-fkeep-static-consts')
            args.append('-fms-compatibility-version=19')
        args.append('/c')

        args.append('/Fo' + obj)
        args.append(source)

        return ('compiling', [source], obj,
                self.compile_env,
                args)

    def _get_link_command(self):
        args = []
        args.append(self.linker)
        args.append('/DEBUG:FULL')
        args.append('/INCREMENTAL:NO')
        if self.nodefaultlib:
            args.append('/nodefaultlib')
            args.append('/entry:main')
        args.append('/PDB:' + self._pdb_file_name())
        args.append('/OUT:' + self._exe_file_name())
        args.extend(self._obj_file_names())

        return ('linking', self._obj_file_names(), self._exe_file_name(),
                self.link_env,
                args)

    def build_commands(self):
        commands = []
        if self.mode == 'compile' or self.mode == 'compile-and-link':
            for input, output in zip(self.inputs, self._obj_file_names()):
                commands.append(self._get_compilation_command(input, output))
        if self.mode == 'link' or self.mode == 'compile-and-link':
            commands.append(self._get_link_command())
        return commands

    def output_files(self):
        outputs = []
        if self.mode == 'compile' or self.mode == 'compile-and-link':
            outputs.extend(self._ilk_file_names())
            outputs.extend(self._obj_file_names())
        if self.mode == 'link' or self.mode == 'compile-and-link':
            outputs.append(self._pdb_file_name())
            outputs.append(self._exe_file_name())

        return [x for x in outputs if x is not None]

class GccBuilder(Builder):
    def __init__(self, toolchain_type, args):
        Builder.__init__(self, toolchain_type, args, '.o')

    def _get_compilation_command(self, source, obj):
        args = []

        args.append(self.compiler)
        args.append('-m' + self.arch)

        args.append('-g')
        if self.opt == 'none':
            args.append('-O0')
        elif self.opt == 'basic':
            args.append('-O2')
        elif self.opt == 'lto':
            args.append('-flto=thin')
        if self.nodefaultlib:
            args.append('-nostdinc')
            args.append('-static')
        args.append('-c')

        args.extend(['-o', obj])
        args.append(source)

        return ('compiling', [source], obj, None, args)

    def _get_link_command(self):
        args = []
        args.append(self.compiler)
        args.append('-m' + self.arch)
        if self.nodefaultlib:
            args.append('-nostdlib')
            args.append('-static')
            main_symbol = 'main'
            if sys.platform == 'darwin':
                main_symbol = '_main'
            args.append('-Wl,-e,' + main_symbol)
        args.extend(['-o', self._exe_file_name()])
        args.extend(self._obj_file_names())

        return ('linking', self._obj_file_names(), self._exe_file_name(), None, args)


    def output_files(self):
        outputs = []
        if self.mode == 'compile' or self.mode == 'compile-and-link':
            outputs.extend(self._obj_file_names())
        if self.mode == 'link' or self.mode == 'compile-and-link':
            outputs.append(self._exe_file_name())

        return outputs

def indent(text, spaces):
    def prefixed_lines():
        prefix = ' ' * spaces
        for line in text.splitlines(True):
            yield prefix + line
    return ''.join(prefixed_lines())

def build(commands):
    global args
    for (status, inputs, output, env, child_args) in commands:
        print('\n\n')
        inputs = [os.path.basename(x) for x in inputs]
        output = os.path.basename(output)
        print(status + ' {0} -> {1}'.format('+'.join(inputs), output))

        if args.verbose:
            print('  Command Line: ' + ' '.join(child_args))
            print('  Env:')
            print_environment(env)
        if args.dry:
            continue

        popen = subprocess.Popen(child_args,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 env=env,
                                 universal_newlines=True)
        stdout, stderr = popen.communicate()
        res = popen.wait()
        if res == -signal.SIGINT:
            raise KeyboardInterrupt
        print('  STDOUT:')
        print(indent(stdout, 4))
        if res != 0:
            print('  STDERR:')
            print(indent(stderr, 4))
            sys.exit(res)

def clean(files):
    global args
    if not files:
        return
    for o in files:
        file = o if args.verbose else os.path.basename(o)
        print('Cleaning {0}'.format(file))
        try:
            if os.path.exists(o):
                if not args.dry:
                    os.remove(o)
                if args.verbose:
                    print('  The file was successfully cleaned.')
            elif args.verbose:
                print('  The file does not exist.')
        except:
            if args.verbose:
                print('  The file could not be removed.')

def fix_arguments(args):
    if not args.inputs:
        raise ValueError('No input files specified')

    if args.output and args.mode == 'compile' and len(args.inputs) > 1:
        raise ValueError('Cannot specify -o with mode=compile and multiple source files.  Use --outdir instead.')

    if not args.dry:
        args.inputs = [os.path.abspath(x) for x in args.inputs]

    # If user didn't specify the outdir, use the directory of the first input.
    if not args.outdir:
        if args.output:
            args.outdir = os.path.dirname(args.output)
        else:
            args.outdir = os.path.dirname(args.inputs[0])
            args.outdir = os.path.abspath(args.outdir)
        args.outdir = os.path.normpath(args.outdir)

    # If user specified a non-absolute path for the output file, append the
    # output directory to it.
    if args.output:
        if not os.path.isabs(args.output):
            args.output = os.path.join(args.outdir, args.output)
        args.output = os.path.normpath(args.output)

fix_arguments(args)

(toolchain_type, toolchain_path) = find_toolchain(args.compiler, args.tools_dir)
if not toolchain_path or not toolchain_type:
    print('Unable to find toolchain {0}'.format(args.compiler))
    sys.exit(1)

if args.verbose:
    print('Script Arguments:')
    print('  Arch: ' + args.arch)
    print('  Compiler: ' + args.compiler)
    print('  Outdir: ' + args.outdir)
    print('  Output: ' + args.output)
    print('  Nodefaultlib: ' + str(args.nodefaultlib))
    print('  Opt: ' + args.opt)
    print('  Mode: ' + args.mode)
    print('  Clean: ' + str(args.clean))
    print('  Verbose: ' + str(args.verbose))
    print('  Dryrun: ' + str(args.dry))
    print('  Inputs: ' + format_text(args.inputs, 0, 10))
    print('Script Environment:')
    print_environment(os.environ)

args.compiler = toolchain_path
if not os.path.exists(args.compiler) and not args.dry:
    raise ValueError('The toolchain {} does not exist.'.format(args.compiler))

if toolchain_type == 'msvc' or toolchain_type=='clang-cl':
    builder = MsvcBuilder(toolchain_type, args)
else:
    builder = GccBuilder(toolchain_type, args)

if args.clean:
    clean(builder.output_files())

cmds = builder.build_commands()

build(cmds)
