summaryrefslogtreecommitdiff
path: root/lit/helper/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'lit/helper/build.py')
-rwxr-xr-xlit/helper/build.py787
1 files changed, 0 insertions, 787 deletions
diff --git a/lit/helper/build.py b/lit/helper/build.py
deleted file mode 100755
index 26f321d709f8..000000000000
--- a/lit/helper/build.py
+++ /dev/null
@@ -1,787 +0,0 @@
-#! /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')
- 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):
- if sys.platform == 'win32':
- name = name + '.exe'
- compiler_dir = os.path.dirname(self.compiler)
- linker_path = os.path.join(compiler_dir, name)
- if not os.path.exists(linker_path):
- raise ValueError('Could not find \'{}\''.format(linker_path))
- 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('/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)