[Lldb-commits] [lldb] r374187 - Revert [test] Split LLDB tests into API, Shell & Unit
Adrian Prantl via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 9 10:35:45 PDT 2019
Added: lldb/trunk/lit/helper/__init__.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/helper/__init__.py?rev=374187&view=auto
==============================================================================
(empty)
Added: lldb/trunk/lit/helper/build.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/helper/build.py?rev=374187&view=auto
==============================================================================
--- lldb/trunk/lit/helper/build.py (added)
+++ lldb/trunk/lit/helper/build.py Wed Oct 9 10:35:43 2019
@@ -0,0 +1,799 @@
+#! /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('--libs-dir',
+ metavar='directory',
+ dest='libs_dir',
+ required=False,
+ action='append',
+ help='If specified, a path to linked libraries to be passed via -L')
+
+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', compiler)
+ if name == 'clang-cl':
+ return ('clang-cl', compiler)
+ if name.startswith('clang'):
+ return ('clang', compiler)
+ if name.startswith('gcc') or name.startswith('g++'):
+ return ('gcc', compiler)
+ if name == 'cc' or name == 'c++':
+ return ('generic', compiler)
+ return ('unknown', compiler)
+
+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
+ self.lib_paths = args.libs_dir
+
+ 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)
+ if self.toolchain_type == 'clang-cl':
+ args.append('--')
+ 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)
+ if sys.platform.startswith('netbsd'):
+ for x in self.lib_paths:
+ args += ['-L' + x, '-Wl,-rpath,' + x]
+ 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)
Propchange: lldb/trunk/lit/helper/build.py
------------------------------------------------------------------------------
svn:executable = *
Added: lldb/trunk/lit/helper/toolchain.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/helper/toolchain.py?rev=374187&view=auto
==============================================================================
--- lldb/trunk/lit/helper/toolchain.py (added)
+++ lldb/trunk/lit/helper/toolchain.py Wed Oct 9 10:35:43 2019
@@ -0,0 +1,131 @@
+import os
+import itertools
+import platform
+import subprocess
+import sys
+
+import lit.util
+from lit.llvm import llvm_config
+from lit.llvm.subst import FindTool
+from lit.llvm.subst import ToolSubst
+
+def use_lldb_substitutions(config):
+ # Set up substitutions for primary tools. These tools must come from config.lldb_tools_dir
+ # which is basically the build output directory. We do not want to find these in path or
+ # anywhere else, since they are specifically the programs which are actually being tested.
+
+ dsname = 'debugserver' if platform.system() in ['Darwin'] else 'lldb-server'
+ dsargs = [] if platform.system() in ['Darwin'] else ['gdbserver']
+
+ build_script = os.path.dirname(__file__)
+ build_script = os.path.join(build_script, 'build.py')
+ build_script_args = [build_script,
+ '--compiler=any', # Default to best compiler
+ '--arch=' + str(config.lldb_bitness)]
+ if config.lldb_lit_tools_dir:
+ build_script_args.append('--tools-dir={0}'.format(config.lldb_lit_tools_dir))
+ if config.lldb_tools_dir:
+ build_script_args.append('--tools-dir={0}'.format(config.lldb_tools_dir))
+ if config.llvm_libs_dir:
+ build_script_args.append('--libs-dir={0}'.format(config.llvm_libs_dir))
+
+ lldb_init = os.path.join(config.test_exec_root, 'lit-lldb-init')
+
+ primary_tools = [
+ ToolSubst('%lldb',
+ command=FindTool('lldb'),
+ extra_args=['--no-lldbinit', '-S', lldb_init]),
+ ToolSubst('%lldb-init',
+ command=FindTool('lldb'),
+ extra_args=['-S', lldb_init]),
+ ToolSubst('%debugserver',
+ command=FindTool(dsname),
+ extra_args=dsargs,
+ unresolved='ignore'),
+ ToolSubst('%platformserver',
+ command=FindTool('lldb-server'),
+ extra_args=['platform'],
+ unresolved='ignore'),
+ 'lldb-test',
+ 'lldb-instr',
+ ToolSubst('%build',
+ command="'" + sys.executable + "'",
+ extra_args=build_script_args)
+ ]
+
+ llvm_config.add_tool_substitutions(primary_tools,
+ [config.lldb_tools_dir])
+
+def _use_msvc_substitutions(config):
+ # If running from a Visual Studio Command prompt (e.g. vcvars), this will
+ # detect the include and lib paths, and find cl.exe and link.exe and create
+ # substitutions for each of them that explicitly specify /I and /L paths
+ cl = lit.util.which('cl')
+ link = lit.util.which('link')
+
+ if not cl or not link:
+ return
+
+ cl = '"' + cl + '"'
+ link = '"' + link + '"'
+ includes = os.getenv('INCLUDE', '').split(';')
+ libs = os.getenv('LIB', '').split(';')
+
+ config.available_features.add('msvc')
+ compiler_flags = ['"/I{}"'.format(x) for x in includes if os.path.exists(x)]
+ linker_flags = ['"/LIBPATH:{}"'.format(x) for x in libs if os.path.exists(x)]
+
+ tools = [
+ ToolSubst('%msvc_cl', command=cl, extra_args=compiler_flags),
+ ToolSubst('%msvc_link', command=link, extra_args=linker_flags)]
+ llvm_config.add_tool_substitutions(tools)
+ return
+
+def use_support_substitutions(config):
+ # Set up substitutions for support tools. These tools can be overridden at the CMake
+ # level (by specifying -DLLDB_LIT_TOOLS_DIR), installed, or as a last resort, we can use
+ # the just-built version.
+ flags = []
+ if platform.system() in ['Darwin']:
+ try:
+ out = subprocess.check_output(['xcrun', '--show-sdk-path']).strip()
+ res = 0
+ except OSError:
+ res = -1
+ if res == 0 and out:
+ sdk_path = lit.util.to_string(out)
+ llvm_config.lit_config.note('using SDKROOT: %r' % sdk_path)
+ flags = ['-isysroot', sdk_path]
+ elif platform.system() in ['NetBSD', 'OpenBSD', 'Linux']:
+ flags = ['-pthread']
+
+ if sys.platform.startswith('netbsd'):
+ # needed e.g. to use freshly built libc++
+ flags += ['-L' + config.llvm_libs_dir,
+ '-Wl,-rpath,' + config.llvm_libs_dir]
+
+ # The clang module cache is used for building inferiors.
+ flags += ['-fmodules-cache-path={}'.format(config.clang_module_cache)]
+
+ additional_tool_dirs=[]
+ if config.lldb_lit_tools_dir:
+ additional_tool_dirs.append(config.lldb_lit_tools_dir)
+
+ llvm_config.use_clang(additional_flags=flags,
+ additional_tool_dirs=additional_tool_dirs,
+ required=True)
+
+ if sys.platform == 'win32':
+ _use_msvc_substitutions(config)
+
+ have_lld = llvm_config.use_lld(additional_tool_dirs=additional_tool_dirs,
+ required=False)
+ if have_lld:
+ config.available_features.add('lld')
+
+
+ support_tools = ['yaml2obj', 'obj2yaml', 'llvm-pdbutil',
+ 'llvm-mc', 'llvm-readobj', 'llvm-objdump',
+ 'llvm-objcopy', 'lli']
+ additional_tool_dirs += [config.lldb_tools_dir, config.llvm_tools_dir]
+ llvm_config.add_tool_substitutions(support_tools, additional_tool_dirs)
Added: lldb/trunk/lit/lit-lldb-init.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/lit-lldb-init.in?rev=374187&view=auto
==============================================================================
--- lldb/trunk/lit/lit-lldb-init.in (added)
+++ lldb/trunk/lit/lit-lldb-init.in Wed Oct 9 10:35:43 2019
@@ -0,0 +1,5 @@
+# LLDB init file for the LIT tests.
+settings set symbols.enable-external-lookup false
+settings set plugin.process.gdb-remote.packet-timeout 60
+settings set interpreter.echo-comment-commands false
+settings set symbols.clang-modules-cache-path "@LLDB_TEST_MODULE_CACHE_LLDB@"
Added: lldb/trunk/lit/lit.cfg.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/lit.cfg.py?rev=374187&view=auto
==============================================================================
--- lldb/trunk/lit/lit.cfg.py (added)
+++ lldb/trunk/lit/lit.cfg.py Wed Oct 9 10:35:43 2019
@@ -0,0 +1,107 @@
+# -*- Python -*-
+
+import os
+import platform
+import re
+import shutil
+import site
+import sys
+
+import lit.formats
+from lit.llvm import llvm_config
+from lit.llvm.subst import FindTool
+from lit.llvm.subst import ToolSubst
+from distutils.spawn import find_executable
+
+site.addsitedir(os.path.dirname(__file__))
+from helper import toolchain
+
+# name: The name of this test suite.
+config.name = 'LLDB'
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
+
+# suffixes: A list of file extensions to treat as test files. This is overriden
+# by individual lit.local.cfg files in the test subdirectories.
+config.suffixes = ['.test', '.cpp', '.s']
+
+# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
+# subdirectories contain auxiliary inputs for various tests in their parent
+# directories.
+config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(config.lldb_obj_root, 'lit')
+
+
+llvm_config.use_default_substitutions()
+
+toolchain.use_lldb_substitutions(config)
+
+toolchain.use_support_substitutions(config)
+
+
+if re.match(r'^arm(hf.*-linux)|(.*-linux-gnuabihf)', config.target_triple):
+ config.available_features.add("armhf-linux")
+
+def calculate_arch_features(arch_string):
+ # This will add a feature such as x86, arm, mips, etc for each built
+ # target
+ features = []
+ for arch in arch_string.split():
+ features.append(arch.lower())
+ return features
+
+# Run llvm-config and add automatically add features for whether we have
+# assertions enabled, whether we are in debug mode, and what targets we
+# are built for.
+llvm_config.feature_config(
+ [('--assertion-mode', {'ON': 'asserts'}),
+ ('--build-mode', {'DEBUG': 'debug'}),
+ ('--targets-built', calculate_arch_features)
+ ])
+
+# Clean the module caches in the test build directory. This is necessary in an
+# incremental build whenever clang changes underneath, so doing it once per
+# lit.py invocation is close enough.
+for cachedir in [config.clang_module_cache, config.lldb_module_cache]:
+ if os.path.isdir(cachedir):
+ print("Deleting module cache at %s."%cachedir)
+ shutil.rmtree(cachedir)
+
+# Set a default per-test timeout of 10 minutes. Setting a timeout per test
+# requires that killProcessAndChildren() is supported on the platform and
+# lit complains if the value is set but it is not supported.
+supported, errormsg = lit_config.maxIndividualTestTimeIsSupported
+if supported:
+ lit_config.maxIndividualTestTime = 600
+else:
+ lit_config.warning("Could not set a default per-test timeout. " + errormsg)
+
+
+# If running tests natively, check for CPU features needed for some tests.
+
+if 'native' in config.available_features:
+ cpuid_exe = lit.util.which('lit-cpuid', config.lldb_tools_dir)
+ if cpuid_exe is None:
+ lit_config.warning("lit-cpuid not found, tests requiring CPU extensions will be skipped")
+ else:
+ out, err, exitcode = lit.util.executeCommand([cpuid_exe])
+ if exitcode == 0:
+ for x in out.split():
+ config.available_features.add('native-cpu-%s' % x)
+ else:
+ lit_config.warning("lit-cpuid failed: %s" % err)
+
+if not config.lldb_disable_python:
+ config.available_features.add('python')
+
+if config.lldb_enable_lzma:
+ config.available_features.add('lzma')
+
+if find_executable('xz') != None:
+ config.available_features.add('xz')
Added: lldb/trunk/lit/lit.site.cfg.py.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/lit.site.cfg.py.in?rev=374187&view=auto
==============================================================================
--- lldb/trunk/lit/lit.site.cfg.py.in (added)
+++ lldb/trunk/lit/lit.site.cfg.py.in Wed Oct 9 10:35:43 2019
@@ -0,0 +1,44 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.llvm_shlib_dir = "@SHLIBDIR@"
+config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
+config.lldb_obj_root = "@LLDB_BINARY_DIR@"
+config.lldb_libs_dir = "@LLDB_LIBS_DIR@"
+config.lldb_tools_dir = "@LLDB_TOOLS_DIR@"
+# Since it comes from the command line, it may have backslashes which
+# should not need to be escaped.
+config.lldb_lit_tools_dir = r"@LLDB_LIT_TOOLS_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+config.python_executable = "@PYTHON_EXECUTABLE@"
+config.have_zlib = @LLVM_ENABLE_ZLIB@
+config.lldb_enable_lzma = @LLDB_ENABLE_LZMA@
+config.host_triple = "@LLVM_HOST_TRIPLE@"
+config.lldb_bitness = 64 if @LLDB_IS_64_BITS@ else 32
+config.lldb_disable_python = @LLDB_DISABLE_PYTHON@
+config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@"
+config.lldb_module_cache = "@LLDB_TEST_MODULE_CACHE_LLDB@"
+config.clang_module_cache = "@LLDB_TEST_MODULE_CACHE_CLANG@"
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+ config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
+ config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
+ config.llvm_shlib_dir = config.llvm_shlib_dir % lit_config.params
+ config.lldb_libs_dir = config.lldb_libs_dir % lit_config.params
+ config.lldb_tools_dir = config.lldb_tools_dir % lit_config.params
+ config.lldb_lit_tools_dir = config.lldb_lit_tools_dir % lit_config.params
+
+except KeyError as e:
+ key, = e.args
+ lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LLDB_SOURCE_DIR@/lit/lit.cfg.py")
Modified: lldb/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/CMakeLists.txt?rev=374187&r1=374186&r2=374187&view=diff
==============================================================================
--- lldb/trunk/test/CMakeLists.txt (original)
+++ lldb/trunk/test/CMakeLists.txt Wed Oct 9 10:35:43 2019
@@ -1,117 +1,149 @@
-# Test runner infrastructure for LLDB. This configures the LLDB test trees
-# for use by Lit, and delegates to LLVM's lit test handlers.
-
-add_subdirectory(API)
-
-# LLVM_BUILD_MODE is used in lit.site.cfg
-if (CMAKE_CFG_INTDIR STREQUAL ".")
- set(LLVM_BUILD_MODE ".")
-else ()
- set(LLVM_BUILD_MODE "%(build_mode)s")
+function(add_python_test_target name test_script args comment)
+ set(PYTHON_TEST_COMMAND
+ ${PYTHON_EXECUTABLE}
+ ${test_script}
+ ${args}
+ )
+
+ add_custom_target(${name}
+ COMMAND ${PYTHON_TEST_COMMAND} ${ARG_DEFAULT_ARGS}
+ COMMENT "${comment}"
+ USES_TERMINAL
+ )
+ add_dependencies(${name} lldb-test-deps)
+endfunction()
+
+# The default architecture with which to compile test executables is the default LLVM target
+# architecture, which itself defaults to the host architecture.
+string(TOLOWER "${LLVM_TARGET_ARCH}" LLDB_DEFAULT_TEST_ARCH)
+if( LLDB_DEFAULT_TEST_ARCH STREQUAL "host" )
+ string(REGEX MATCH "^[^-]*" LLDB_DEFAULT_TEST_ARCH ${LLVM_HOST_TRIPLE})
endif ()
-if (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(LLDB_IS_64_BITS 1)
-endif()
+# Allow the user to override the default by setting LLDB_TEST_ARCH
+set(LLDB_TEST_ARCH
+ ${LLDB_DEFAULT_TEST_ARCH}
+ CACHE STRING "Specify the architecture to run LLDB tests as (x86|x64). Determines whether tests are compiled with -m32 or -m64")
+
+# Users can override LLDB_TEST_USER_ARGS to specify arbitrary arguments to pass to the script
+set(LLDB_TEST_USER_ARGS
+ ""
+ CACHE STRING "Specify additional arguments to pass to test runner. For example: '-C gcc -C clang -A i386 -A x86_64'")
+
+# The .noindex suffix is a marker for Spotlight to never index the
+# build directory. LLDB queries Spotlight to locate .dSYM bundles
+# based on the UUID embedded in a binary, and because the UUID is a
+# hash of filename and .text section, there *will* be conflicts inside
+# the build directory.
+set(LLDB_TEST_COMMON_ARGS
+ --arch=${LLDB_TEST_ARCH}
+ -s
+ ${CMAKE_BINARY_DIR}/lldb-test-traces
+ -S nm
+ -u CXXFLAGS
+ -u CFLAGS
+ )
-get_property(LLDB_DOTEST_ARGS GLOBAL PROPERTY LLDB_DOTEST_ARGS_PROPERTY)
-set(dotest_args_replacement ${LLVM_BUILD_MODE})
+list(APPEND LLDB_TEST_COMMON_ARGS
+ --executable ${LLDB_TEST_EXECUTABLE}
+ --dsymutil ${LLDB_TEST_DSYMUTIL}
+ --filecheck ${LLDB_TEST_FILECHECK}
+ -C ${LLDB_TEST_C_COMPILER}
+ )
-set(LLDB_TEST_MODULE_CACHE_LLDB "${LLDB_TEST_BUILD_DIRECTORY}/module-cache-lldb" CACHE PATH "The Clang module cache used by the Clang embedded in LLDB while running tests.")
-set(LLDB_TEST_MODULE_CACHE_CLANG "${LLDB_TEST_BUILD_DIRECTORY}/module-cache-clang" CACHE PATH "The Clang module cache used by the Clang while building tests.")
+if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
+ # All tests are currently flaky on Windows, so rerun them all once when they fail.
+ set(LLDB_TEST_COMMON_ARGS ${LLDB_TEST_COMMON_ARGS} --rerun-all-issues)
+
+ set(LLDB_TEST_DEBUG_TEST_CRASHES
+ 0
+ CACHE BOOL "(Windows only) Enables debugging of tests in the test suite by showing the crash dialog when lldb crashes")
+
+ set(LLDB_TEST_HIDE_CONSOLE_WINDOWS
+ 1
+ CACHE BOOL "(Windows only) Hides the console window for an inferior when it is launched through the test suite")
-if(LLDB_BUILT_STANDALONE)
- # In paths to our build-tree, replace CMAKE_CFG_INTDIR with our configuration name placeholder.
- string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} config_runtime_output_dir ${LLVM_RUNTIME_OUTPUT_INTDIR})
- string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}")
-
- # Remaining ones must be paths to the provided LLVM build-tree.
- if(LLVM_CONFIGURATION_TYPES)
- # LLDB uses single-config; LLVM multi-config; pick one and prefer Release types.
- # Otherwise, if both use multi-config the default is fine.
- if(NOT CMAKE_CONFIGURATION_TYPES)
- if(RelWithDebInfo IN_LIST LLVM_CONFIGURATION_TYPES)
- set(dotest_args_replacement RelWithDebInfo)
- elseif(Release IN_LIST LLVM_CONFIGURATION_TYPES)
- set(dotest_args_replacement Release)
- else()
- list(GET LLVM_CONFIGURATION_TYPES 0 dotest_args_replacement)
- endif()
- endif()
- else()
- # Common case: LLVM used a single-configuration generator like Ninja.
- set(dotest_args_replacement ".")
+ if (LLDB_TEST_DEBUG_TEST_CRASHES)
+ set(LLDB_TEST_COMMON_ARGS ${LLDB_TEST_COMMON_ARGS} --enable-crash-dialog)
endif()
-endif()
-string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}")
-string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_LIBS_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
-string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
-
-add_lldb_test_dependency(
- lit-cpuid
- llc
- lli
- llvm-config
- llvm-dwarfdump
- llvm-nm
- llvm-mc
- llvm-objcopy
- llvm-readobj
- llvm-strip
- )
+ if (NOT LLDB_TEST_HIDE_CONSOLE_WINDOWS)
+ set(LLDB_TEST_COMMON_ARGS ${LLDB_TEST_COMMON_ARGS} --show-inferior-console)
+ endif()
+endif()
-if(TARGET lld)
- add_lldb_test_dependency(lld)
+if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows|Darwin")
+ list(APPEND LLDB_TEST_COMMON_ARGS
+ --env ARCHIVER=${CMAKE_AR} --env OBJCOPY=${CMAKE_OBJCOPY})
endif()
-# the value is not canonicalized within LLVM
-llvm_canonicalize_cmake_booleans(
- LLDB_DISABLE_PYTHON
- LLVM_ENABLE_ZLIB
- LLVM_ENABLE_SHARED_LIBS
- LLDB_IS_64_BITS)
-
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/Shell/lit.site.cfg.py.in
- ${CMAKE_CURRENT_BINARY_DIR}/Shell/lit.site.cfg.py
- MAIN_CONFIG
- ${CMAKE_CURRENT_SOURCE_DIR}/Shell/lit.cfg.py)
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
- ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py
- MAIN_CONFIG
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py)
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/API/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/API/lit.site.cfg)
-
-configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/Shell/lit-lldb-init.in
- ${CMAKE_CURRENT_BINARY_DIR}/Shell/lit-lldb-init)
-
-if(NOT LLDB_BUILT_STANDALONE)
- add_lldb_test_dependency(
- FileCheck
- count
- not
- )
+if (NOT "${LLDB_LIT_TOOLS_DIR}" STREQUAL "")
+ if (NOT EXISTS "${LLDB_LIT_TOOLS_DIR}")
+ message(WARNING "LLDB_LIT_TOOLS_DIR ${LLDB_LIT_TOOLS_DIR} does not exist.")
+ endif()
endif()
-add_lit_testsuite(check-lldb-lit "Running lldb lit test suite"
- ${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS lldb-test-deps
- )
+if(CMAKE_HOST_APPLE)
+ if(LLDB_BUILD_FRAMEWORK)
+ get_target_property(framework_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY)
+ list(APPEND LLDB_TEST_COMMON_ARGS --framework ${framework_build_dir}/LLDB.framework)
+ endif()
-set_target_properties(check-lldb-lit PROPERTIES FOLDER "lldb tests")
+ # Use the same identity for testing
+ get_property(code_sign_identity_used GLOBAL PROPERTY LLDB_DEBUGSERVER_CODESIGN_IDENTITY)
+ if(code_sign_identity_used)
+ list(APPEND LLDB_TEST_COMMON_ARGS --codesign-identity "${code_sign_identity_used}")
+ endif()
-# If we're building with an in-tree clang, then list clang as a dependency
-# to run tests.
-if (TARGET clang)
- add_dependencies(check-lldb-lit clang)
+ if(LLDB_USE_SYSTEM_DEBUGSERVER)
+ lldb_find_system_debugserver(system_debugserver_path)
+ add_custom_target(debugserver
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${system_debugserver_path} ${LLVM_RUNTIME_OUTPUT_INTDIR}
+ COMMENT "Copying the system debugserver to LLDB's binaries directory for testing.")
+ # The custom target for the system debugserver has no install target, so we
+ # need to remove it from the LLVM_DISTRIBUTION_COMPONENTS list.
+ if (LLVM_DISTRIBUTION_COMPONENTS)
+ list(REMOVE_ITEM LLVM_DISTRIBUTION_COMPONENTS debugserver)
+ set(LLVM_DISTRIBUTION_COMPONENTS ${LLVM_DISTRIBUTION_COMPONENTS} PARENT_SCOPE)
+ endif()
+ message(STATUS "LLDB tests use out-of-tree debugserver: ${system_debugserver_path}")
+ list(APPEND LLDB_TEST_COMMON_ARGS --out-of-tree-debugserver)
+ add_lldb_test_dependency(debugserver)
+ elseif(TARGET debugserver)
+ set(debugserver_path ${LLVM_RUNTIME_OUTPUT_INTDIR}/debugserver)
+ message(STATUS "LLDB Tests use just-built debugserver: ${debugserver_path}")
+ list(APPEND LLDB_TEST_COMMON_ARGS --server ${debugserver_path})
+ add_lldb_test_dependency(debugserver)
+ elseif(TARGET lldb-server)
+ set(lldb_server_path ${LLVM_RUNTIME_OUTPUT_INTDIR}/lldb-server)
+ message(STATUS "LLDB Tests use just-built lldb-server: ${lldb_server_path}")
+ list(APPEND LLDB_TEST_COMMON_ARGS --server ${lldb_server_path})
+ add_lldb_test_dependency(lldb-server)
+ else()
+ message(WARNING "LLDB Tests enabled, but no server available")
+ endif()
endif()
-add_lit_testsuites(LLDB
- ${CMAKE_CURRENT_SOURCE_DIR}
- DEPENDS lldb-test-deps
- )
+set(LLDB_DOTEST_ARGS ${LLDB_TEST_COMMON_ARGS};${LLDB_TEST_USER_ARGS})
+set_property(GLOBAL PROPERTY LLDB_DOTEST_ARGS_PROPERTY ${LLDB_DOTEST_ARGS})
+
+add_custom_target(check-lldb)
+add_dependencies(check-lldb lldb-test-deps)
+set_target_properties(check-lldb PROPERTIES FOLDER "lldb misc")
+
+# LLD is required to link test executables on Windows.
+if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+ if (TARGET lld)
+ add_lldb_test_dependency(lld)
+ else ()
+ message(WARNING "lld required to test LLDB on Windows")
+ endif ()
+endif ()
+
+# Run the lit-style tests and the unittests as part of the check-lldb target.
+add_dependencies(check-lldb check-lldb-lit)
+
+# This will add LLDB's test dependencies to the dependencies for check-all and
+# include them in the test-depends target.
+set_property(GLOBAL APPEND PROPERTY LLVM_LIT_DEPENDS ${ARG_DEPENDS})
Added: lldb/trunk/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=374187&view=auto
==============================================================================
--- lldb/trunk/test/dotest.py (added)
+++ lldb/trunk/test/dotest.py Wed Oct 9 10:35:43 2019
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+if __name__ == "__main__":
+ import use_lldb_suite
+
+ import lldbsuite.test
+ lldbsuite.test.run_suite()
Propchange: lldb/trunk/test/dotest.py
------------------------------------------------------------------------------
svn:executable = *
Removed: lldb/trunk/test/lit.cfg.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lit.cfg.py?rev=374186&view=auto
==============================================================================
--- lldb/trunk/test/lit.cfg.py (original)
+++ lldb/trunk/test/lit.cfg.py (removed)
@@ -1,41 +0,0 @@
-# -*- Python -*-
-
-import os
-import platform
-import re
-import shutil
-import site
-import sys
-
-import lit.formats
-from lit.llvm import llvm_config
-from lit.llvm.subst import FindTool
-from lit.llvm.subst import ToolSubst
-from distutils.spawn import find_executable
-
-# This is the top level configuration. Most of these configuration options will
-# be overriden by individual lit configuration files in the test
-# subdirectories.
-
-# name: The name of this test suite.
-config.name = 'lldb'
-
-# testFormat: The test format to use to interpret tests.
-config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
-
-# suffixes: A list of file extensions to treat as test files. This is overriden
-# by individual lit.local.cfg files in the test subdirectories.
-config.suffixes = ['.test', '.cpp', '.s']
-
-# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
-# subdirectories contain auxiliary inputs for various tests in their parent
-# directories.
-config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']
-
-# test_source_root: The root path where tests are located.
-config.test_source_root = os.path.dirname(__file__)
-
-# test_exec_root: The root path where tests should be run.
-config.test_exec_root = os.path.join(config.lldb_obj_root, 'test')
-
-llvm_config.use_default_substitutions()
Added: lldb/trunk/test/testcases
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/testcases?rev=374187&view=auto
==============================================================================
--- lldb/trunk/test/testcases (added)
+++ lldb/trunk/test/testcases Wed Oct 9 10:35:43 2019
@@ -0,0 +1 @@
+link ../packages/Python/lldbsuite/test
\ No newline at end of file
Propchange: lldb/trunk/test/testcases
------------------------------------------------------------------------------
svn:special = *
Added: lldb/trunk/test/use_lldb_suite.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/use_lldb_suite.py?rev=374187&view=auto
==============================================================================
--- lldb/trunk/test/use_lldb_suite.py (added)
+++ lldb/trunk/test/use_lldb_suite.py Wed Oct 9 10:35:43 2019
@@ -0,0 +1,28 @@
+import inspect
+import os
+import sys
+
+
+def find_lldb_root():
+ lldb_root = os.path.dirname(
+ os.path.abspath(inspect.getfile(inspect.currentframe()))
+ )
+ while True:
+ lldb_root = os.path.dirname(lldb_root)
+ if lldb_root is None:
+ return None
+
+ test_path = os.path.join(lldb_root, "use_lldb_suite_root.py")
+ if os.path.isfile(test_path):
+ return lldb_root
+ return None
+
+lldb_root = find_lldb_root()
+if lldb_root is not None:
+ import imp
+ fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root])
+ try:
+ imp.load_module("use_lldb_suite_root", fp, pathname, desc)
+ finally:
+ if fp:
+ fp.close()
More information about the lldb-commits
mailing list