Merge to upstream r304942.
Test: make checkbuild Test: ./run_tests.py Bug: None Change-Id: Ife00da6e2ce8d030886fd9a94d0417e0db784222
This commit is contained in:
@@ -24,6 +24,7 @@ class CXXCompiler(object):
|
||||
modules_flags=None, use_modules=False,
|
||||
use_ccache=False, use_warnings=False, compile_env=None,
|
||||
cxx_type=None, cxx_version=None):
|
||||
self.source_lang = 'c++'
|
||||
self.path = path
|
||||
self.flags = list(flags or [])
|
||||
self.compile_flags = list(compile_flags or [])
|
||||
@@ -108,7 +109,7 @@ class CXXCompiler(object):
|
||||
if out is not None:
|
||||
cmd += ['-o', out]
|
||||
if input_is_cxx:
|
||||
cmd += ['-x', 'c++']
|
||||
cmd += ['-x', self.source_lang]
|
||||
if isinstance(source_files, list):
|
||||
cmd += source_files
|
||||
elif isinstance(source_files, str):
|
||||
|
||||
@@ -67,7 +67,7 @@ class Configuration(object):
|
||||
self.abi_library_root = None
|
||||
self.link_shared = self.get_lit_bool('enable_shared', default=True)
|
||||
self.debug_build = self.get_lit_bool('debug_build', default=False)
|
||||
self.exec_env = {}
|
||||
self.exec_env = dict(os.environ)
|
||||
self.use_target = False
|
||||
self.use_system_cxx_lib = False
|
||||
self.use_clang_verify = False
|
||||
@@ -111,20 +111,23 @@ class Configuration(object):
|
||||
def make_static_lib_name(self, name):
|
||||
"""Return the full filename for the specified library name"""
|
||||
if self.is_windows:
|
||||
return name + '.lib'
|
||||
assert name == 'c++' # Only allow libc++ to use this function for now.
|
||||
return 'lib' + name + '.lib'
|
||||
else:
|
||||
return 'lib' + name + '.a'
|
||||
|
||||
def configure(self):
|
||||
self.configure_executor()
|
||||
self.configure_use_system_cxx_lib()
|
||||
self.configure_target_info()
|
||||
self.configure_cxx()
|
||||
self.configure_triple()
|
||||
self.configure_deployment()
|
||||
self.configure_availability()
|
||||
self.configure_src_root()
|
||||
self.configure_obj_root()
|
||||
self.configure_cxx_stdlib_under_test()
|
||||
self.configure_cxx_library_root()
|
||||
self.configure_use_system_cxx_lib()
|
||||
self.configure_use_clang_verify()
|
||||
self.configure_use_thread_safety()
|
||||
self.configure_execute_external()
|
||||
@@ -139,6 +142,7 @@ class Configuration(object):
|
||||
self.configure_sanitizer()
|
||||
self.configure_coverage()
|
||||
self.configure_modules()
|
||||
self.configure_coroutines()
|
||||
self.configure_substitutions()
|
||||
self.configure_features()
|
||||
|
||||
@@ -157,7 +161,11 @@ class Configuration(object):
|
||||
# Print as list to prevent "set([...])" from being printed.
|
||||
self.lit_config.note('Using available_features: %s' %
|
||||
list(self.config.available_features))
|
||||
self.lit_config.note('Using environment: %r' % self.exec_env)
|
||||
show_env_vars = {}
|
||||
for k,v in self.exec_env.items():
|
||||
if k not in os.environ or os.environ[k] != v:
|
||||
show_env_vars[k] = v
|
||||
self.lit_config.note('Adding environment variables: %r' % show_env_vars)
|
||||
sys.stderr.flush() # Force flushing to avoid broken output on Windows
|
||||
|
||||
def get_test_format(self):
|
||||
@@ -240,7 +248,7 @@ class Configuration(object):
|
||||
flags = []
|
||||
compile_flags = _prefixed_env_list('INCLUDE', '-isystem')
|
||||
link_flags = _prefixed_env_list('LIB', '-L')
|
||||
for path in _list_env_var('LIB'):
|
||||
for path in _split_env_var('LIB'):
|
||||
self.add_path(self.exec_env, path)
|
||||
return CXXCompiler(clang_path, flags=flags,
|
||||
compile_flags=compile_flags,
|
||||
@@ -272,12 +280,22 @@ class Configuration(object):
|
||||
# the locally built one; the former mode is useful for testing ABI
|
||||
# compatibility between the current headers and a shipping dynamic
|
||||
# library.
|
||||
self.use_system_cxx_lib = self.get_lit_bool('use_system_cxx_lib')
|
||||
if self.use_system_cxx_lib is None:
|
||||
# Default to testing against the locally built libc++ library.
|
||||
# Default to testing against the locally built libc++ library.
|
||||
self.use_system_cxx_lib = self.get_lit_conf('use_system_cxx_lib')
|
||||
if self.use_system_cxx_lib == 'true':
|
||||
self.use_system_cxx_lib = True
|
||||
elif self.use_system_cxx_lib == 'false':
|
||||
self.use_system_cxx_lib = False
|
||||
self.lit_config.note(
|
||||
"inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
|
||||
elif self.use_system_cxx_lib:
|
||||
assert os.path.isdir(self.use_system_cxx_lib)
|
||||
self.lit_config.note(
|
||||
"inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
|
||||
|
||||
def configure_availability(self):
|
||||
# See http://llvm.org/docs/AvailabilityMarkup.html
|
||||
self.with_availability = self.get_lit_bool('with_availability', False)
|
||||
self.lit_config.note(
|
||||
"inferred with_availability as: %r" % self.with_availability)
|
||||
|
||||
def configure_cxx_stdlib_under_test(self):
|
||||
self.cxx_stdlib_under_test = self.get_lit_conf(
|
||||
@@ -300,15 +318,18 @@ class Configuration(object):
|
||||
|
||||
def configure_use_clang_verify(self):
|
||||
'''If set, run clang with -verify on failing tests.'''
|
||||
if self.with_availability:
|
||||
self.use_clang_verify = False
|
||||
return
|
||||
self.use_clang_verify = self.get_lit_bool('use_clang_verify')
|
||||
if self.use_clang_verify is None:
|
||||
# NOTE: We do not test for the -verify flag directly because
|
||||
# -verify will always exit with non-zero on an empty file.
|
||||
self.use_clang_verify = self.cxx.isVerifySupported()
|
||||
if self.use_clang_verify:
|
||||
self.config.available_features.add('verify-support')
|
||||
self.lit_config.note(
|
||||
"inferred use_clang_verify as: %r" % self.use_clang_verify)
|
||||
if self.use_clang_verify:
|
||||
self.config.available_features.add('verify-support')
|
||||
|
||||
def configure_use_thread_safety(self):
|
||||
'''If set, run clang with -verify on failing tests.'''
|
||||
@@ -340,6 +361,12 @@ class Configuration(object):
|
||||
self.cxx.use_ccache = True
|
||||
self.lit_config.note('enabling ccache')
|
||||
|
||||
def add_deployment_feature(self, feature):
|
||||
(arch, name, version) = self.config.deployment
|
||||
self.config.available_features.add('%s=%s-%s' % (feature, arch, name))
|
||||
self.config.available_features.add('%s=%s' % (feature, name))
|
||||
self.config.available_features.add('%s=%s%s' % (feature, name, version))
|
||||
|
||||
def configure_features(self):
|
||||
additional_features = self.get_lit_conf('additional_features')
|
||||
if additional_features:
|
||||
@@ -358,6 +385,29 @@ class Configuration(object):
|
||||
self.config.available_features.add(
|
||||
'with_system_cxx_lib=%s' % self.config.target_triple)
|
||||
|
||||
# Add subcomponents individually.
|
||||
target_components = self.config.target_triple.split('-')
|
||||
for component in target_components:
|
||||
self.config.available_features.add(
|
||||
'with_system_cxx_lib=%s' % component)
|
||||
|
||||
# Add available features for more generic versions of the target
|
||||
# triple attached to with_system_cxx_lib.
|
||||
if self.use_deployment:
|
||||
self.add_deployment_feature('with_system_cxx_lib')
|
||||
|
||||
# Configure the availability markup checks features.
|
||||
if self.with_availability:
|
||||
self.config.available_features.add('availability_markup')
|
||||
self.add_deployment_feature('availability_markup')
|
||||
|
||||
if self.use_system_cxx_lib or self.with_availability:
|
||||
self.config.available_features.add('availability')
|
||||
self.add_deployment_feature('availability')
|
||||
|
||||
if platform.system() == 'Darwin':
|
||||
self.config.available_features.add('apple-darwin')
|
||||
|
||||
# Insert the platform name into the available features as a lower case.
|
||||
self.config.available_features.add(target_platform)
|
||||
|
||||
@@ -400,6 +450,13 @@ class Configuration(object):
|
||||
|
||||
if self.is_windows:
|
||||
self.config.available_features.add('windows')
|
||||
if self.cxx_stdlib_under_test == 'libc++':
|
||||
# LIBCXX-WINDOWS-FIXME is the feature name used to XFAIL the
|
||||
# initial Windows failures until they can be properly diagnosed
|
||||
# and fixed. This allows easier detection of new test failures
|
||||
# and regressions. Note: New failures should not be suppressed
|
||||
# using this feature. (Also see llvm.org/PR32730)
|
||||
self.config.available_features.add('LIBCXX-WINDOWS-FIXME')
|
||||
|
||||
# Attempt to detect the glibc version by querying for __GLIBC__
|
||||
# in 'features.h'.
|
||||
@@ -410,6 +467,12 @@ class Configuration(object):
|
||||
self.config.available_features.add('glibc-%s' % maj_v)
|
||||
self.config.available_features.add('glibc-%s.%s' % (maj_v, min_v))
|
||||
|
||||
# Support Objective-C++ only on MacOS and if the compiler supports it.
|
||||
if self.target_info.platform() == "darwin" and \
|
||||
self.target_info.is_host_macosx() and \
|
||||
self.cxx.hasCompileFlag(["-x", "objective-c++", "-fobjc-arc"]):
|
||||
self.config.available_features.add("objective-c++")
|
||||
|
||||
def configure_compile_flags(self):
|
||||
no_default_flags = self.get_lit_bool('no_default_flags', False)
|
||||
if not no_default_flags:
|
||||
@@ -421,9 +484,13 @@ class Configuration(object):
|
||||
# Configure extra flags
|
||||
compile_flags_str = self.get_lit_conf('compile_flags', '')
|
||||
self.cxx.compile_flags += shlex.split(compile_flags_str)
|
||||
# FIXME: Can we remove this?
|
||||
if self.is_windows:
|
||||
# FIXME: Can we remove this?
|
||||
self.cxx.compile_flags += ['-D_CRT_SECURE_NO_WARNINGS']
|
||||
# Required so that tests using min/max don't fail on Windows,
|
||||
# and so that those tests don't have to be changed to tolerate
|
||||
# this insanity.
|
||||
self.cxx.compile_flags += ['-DNOMINMAX']
|
||||
|
||||
def configure_default_compile_flags(self):
|
||||
# Try and get the std version from the command line. Fall back to
|
||||
@@ -483,9 +550,18 @@ class Configuration(object):
|
||||
['-target', self.config.target_triple]):
|
||||
self.lit_config.warning('use_target is true but -target is '\
|
||||
'not supported by the compiler')
|
||||
if self.use_deployment:
|
||||
arch, name, version = self.config.deployment
|
||||
self.cxx.flags += ['-arch', arch]
|
||||
self.cxx.flags += ['-m' + name + '-version-min=' + version]
|
||||
|
||||
# Disable availability unless explicitely requested
|
||||
if not self.with_availability:
|
||||
self.cxx.flags += ['-D_LIBCPP_DISABLE_AVAILABILITY']
|
||||
|
||||
def configure_compile_flags_header_includes(self):
|
||||
support_path = os.path.join(self.libcxx_src_root, 'test', 'support')
|
||||
self.configure_config_site_header()
|
||||
if self.cxx_stdlib_under_test != 'libstdc++' and \
|
||||
not self.is_windows:
|
||||
self.cxx.compile_flags += [
|
||||
@@ -501,7 +577,6 @@ class Configuration(object):
|
||||
'-include', os.path.join(support_path,
|
||||
'set_windows_crt_report_mode.h')
|
||||
]
|
||||
self.configure_config_site_header()
|
||||
cxx_headers = self.get_lit_conf('cxx_headers')
|
||||
if cxx_headers == '' or (cxx_headers is None
|
||||
and self.cxx_stdlib_under_test != 'libc++'):
|
||||
@@ -674,6 +749,13 @@ class Configuration(object):
|
||||
self.cxx_runtime_root]
|
||||
elif self.is_windows and self.link_shared:
|
||||
self.add_path(self.exec_env, self.cxx_runtime_root)
|
||||
elif os.path.isdir(str(self.use_system_cxx_lib)):
|
||||
self.cxx.link_flags += ['-L' + self.use_system_cxx_lib]
|
||||
if not self.is_windows:
|
||||
self.cxx.link_flags += ['-Wl,-rpath,' +
|
||||
self.use_system_cxx_lib]
|
||||
if self.is_windows and self.link_shared:
|
||||
self.add_path(self.cxx.compile_env, self.use_system_cxx_lib)
|
||||
|
||||
def configure_link_flags_abi_library_path(self):
|
||||
# Configure ABI library paths.
|
||||
@@ -790,6 +872,7 @@ class Configuration(object):
|
||||
self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move')
|
||||
self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions')
|
||||
self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals')
|
||||
self.cxx.addWarningFlagIfSupported('-Wno-noexcept-type')
|
||||
# These warnings should be enabled in order to support the MSVC
|
||||
# team using the test suite; They enable the warnings below and
|
||||
# expect the test suite to be clean.
|
||||
@@ -800,6 +883,9 @@ class Configuration(object):
|
||||
# FIXME: Enable the two warnings below.
|
||||
self.cxx.addWarningFlagIfSupported('-Wno-conversion')
|
||||
self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
|
||||
# FIXME: Remove this warning once the min/max handling patch lands
|
||||
# See https://reviews.llvm.org/D33080
|
||||
self.cxx.addWarningFlagIfSupported('-Wno-#warnings')
|
||||
std = self.get_lit_conf('std', None)
|
||||
if std in ['c++98', 'c++03']:
|
||||
# The '#define static_assert' provided by libc++ in C++03 mode
|
||||
@@ -873,6 +959,18 @@ class Configuration(object):
|
||||
self.cxx.flags += ['-g', '--coverage']
|
||||
self.cxx.compile_flags += ['-O0']
|
||||
|
||||
def configure_coroutines(self):
|
||||
if self.cxx.hasCompileFlag('-fcoroutines-ts'):
|
||||
macros = self.cxx.dumpMacros(flags=['-fcoroutines-ts'])
|
||||
if '__cpp_coroutines' not in macros:
|
||||
self.lit_config.warning('-fcoroutines-ts is supported but '
|
||||
'__cpp_coroutines is not defined')
|
||||
# Consider coroutines supported only when the feature test macro
|
||||
# reflects a recent value.
|
||||
val = macros['__cpp_coroutines'].replace('L', '')
|
||||
if int(val) >= 201703:
|
||||
self.config.available_features.add('fcoroutines-ts')
|
||||
|
||||
def configure_modules(self):
|
||||
modules_flags = ['-fmodules']
|
||||
if platform.system() != 'Darwin':
|
||||
@@ -934,29 +1032,41 @@ class Configuration(object):
|
||||
sub.append(('%link', link_str))
|
||||
sub.append(('%build', build_str))
|
||||
# Configure exec prefix substitutions.
|
||||
exec_env_str = ''
|
||||
if not self.is_windows and len(self.exec_env) != 0:
|
||||
exec_env_str = 'env '
|
||||
for k, v in self.exec_env.items():
|
||||
exec_env_str += ' %s=%s' % (k, v)
|
||||
# Configure run env substitution.
|
||||
exec_str = exec_env_str
|
||||
if self.lit_config.useValgrind:
|
||||
exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
|
||||
sub.append(('%exec', exec_str))
|
||||
# Configure run shortcut
|
||||
sub.append(('%run', exec_str + ' %t.exe'))
|
||||
sub.append(('%run', '%t.exe'))
|
||||
# Configure not program substitutions
|
||||
not_py = os.path.join(self.libcxx_src_root, 'utils', 'not.py')
|
||||
not_str = '%s %s ' % (pipes.quote(sys.executable), pipes.quote(not_py))
|
||||
sub.append(('not ', not_str))
|
||||
|
||||
def can_use_deployment(self):
|
||||
# Check if the host is on an Apple platform using clang.
|
||||
if not self.target_info.platform() == "darwin":
|
||||
return False
|
||||
if not self.target_info.is_host_macosx():
|
||||
return False
|
||||
if not self.cxx.type.endswith('clang'):
|
||||
return False
|
||||
return True
|
||||
|
||||
def configure_triple(self):
|
||||
# Get or infer the target triple.
|
||||
self.config.target_triple = self.get_lit_conf('target_triple')
|
||||
target_triple = self.get_lit_conf('target_triple')
|
||||
self.use_target = self.get_lit_bool('use_target', False)
|
||||
if self.use_target and self.config.target_triple:
|
||||
if self.use_target and target_triple:
|
||||
self.lit_config.warning('use_target is true but no triple is specified')
|
||||
|
||||
# Use deployment if possible.
|
||||
self.use_deployment = not self.use_target and self.can_use_deployment()
|
||||
if self.use_deployment:
|
||||
return
|
||||
|
||||
# Save the triple (and warn on Apple platforms).
|
||||
self.config.target_triple = target_triple
|
||||
if self.use_target and 'apple' in target_triple:
|
||||
self.lit_config.warning('consider using arch and platform instead'
|
||||
' of target_triple on Apple platforms')
|
||||
|
||||
# If no target triple was given, try to infer it from the compiler
|
||||
# under test.
|
||||
if not self.config.target_triple:
|
||||
@@ -978,6 +1088,39 @@ class Configuration(object):
|
||||
self.lit_config.note(
|
||||
"inferred target_triple as: %r" % self.config.target_triple)
|
||||
|
||||
def configure_deployment(self):
|
||||
assert not self.use_deployment is None
|
||||
assert not self.use_target is None
|
||||
if not self.use_deployment:
|
||||
# Warn about ignored parameters.
|
||||
if self.get_lit_conf('arch'):
|
||||
self.lit_config.warning('ignoring arch, using target_triple')
|
||||
if self.get_lit_conf('platform'):
|
||||
self.lit_config.warning('ignoring platform, using target_triple')
|
||||
return
|
||||
|
||||
assert not self.use_target
|
||||
assert self.target_info.is_host_macosx()
|
||||
|
||||
# Always specify deployment explicitly on Apple platforms, since
|
||||
# otherwise a platform is picked up from the SDK. If the SDK version
|
||||
# doesn't match the system version, tests that use the system library
|
||||
# may fail spuriously.
|
||||
arch = self.get_lit_conf('arch')
|
||||
if not arch:
|
||||
arch = self.cxx.getTriple().split('-', 1)[0]
|
||||
self.lit_config.note("inferred arch as: %r" % arch)
|
||||
|
||||
inferred_platform, name, version = self.target_info.get_platform()
|
||||
if inferred_platform:
|
||||
self.lit_config.note("inferred platform as: %r" % (name + version))
|
||||
self.config.deployment = (arch, name, version)
|
||||
|
||||
# Set the target triple for use by lit.
|
||||
self.config.target_triple = arch + '-apple-' + name + version
|
||||
self.lit_config.note(
|
||||
"computed target_triple as: %r" % self.config.target_triple)
|
||||
|
||||
def configure_env(self):
|
||||
self.target_info.configure_env(self.exec_env)
|
||||
|
||||
|
||||
@@ -38,36 +38,11 @@ class LocalExecutor(Executor):
|
||||
|
||||
def run(self, exe_path, cmd=None, work_dir='.', file_deps=None, env=None):
|
||||
cmd = cmd or [exe_path]
|
||||
env_cmd = []
|
||||
if env:
|
||||
env_cmd += ['env']
|
||||
env_cmd += ['%s=%s' % (k, v) for k, v in env.items()]
|
||||
if work_dir == '.':
|
||||
work_dir = os.getcwd()
|
||||
if not self.is_windows:
|
||||
out, err, rc = executeCommand(env_cmd + cmd, cwd=work_dir)
|
||||
else:
|
||||
out, err, rc = executeCommand(cmd, cwd=work_dir,
|
||||
env=self._build_windows_env(env))
|
||||
return (env_cmd + cmd, out, err, rc)
|
||||
out, err, rc = executeCommand(cmd, cwd=work_dir, env=env)
|
||||
return (cmd, out, err, rc)
|
||||
|
||||
def _build_windows_env(self, exec_env):
|
||||
# FIXME: Finding Windows DLL's at runtime requires modifying the
|
||||
# PATH environment variables. However we don't want to print out
|
||||
# the entire PATH as part of the diagnostic for every failing test.
|
||||
# Therefore this hack builds a new executable environment that
|
||||
# merges the current environment and the supplied environment while
|
||||
# still only printing the supplied environment in diagnostics.
|
||||
if not self.is_windows or exec_env is None:
|
||||
return None
|
||||
new_env = dict(os.environ)
|
||||
for key, value in exec_env.items():
|
||||
if key == 'PATH':
|
||||
assert value.strip() != '' and "expected non-empty path"
|
||||
new_env['PATH'] = "%s;%s" % (value, os.environ['PATH'])
|
||||
else:
|
||||
new_env[key] = value
|
||||
return new_env
|
||||
|
||||
class PrefixExecutor(Executor):
|
||||
"""Prefix an executor with some other command wrapper.
|
||||
@@ -196,7 +171,7 @@ class SSHExecutor(RemoteExecutor):
|
||||
# Not sure how to do suffix on osx yet
|
||||
dir_arg = '-d' if is_dir else ''
|
||||
cmd = 'mktemp -q {} /tmp/libcxx.XXXXXXXXXX'.format(dir_arg)
|
||||
temp_path, err, exitCode = self._execute_command_remote([cmd])
|
||||
_, temp_path, err, exitCode = self._execute_command_remote([cmd])
|
||||
temp_path = temp_path.strip()
|
||||
if exitCode != 0:
|
||||
raise RuntimeError(err)
|
||||
@@ -219,4 +194,5 @@ class SSHExecutor(RemoteExecutor):
|
||||
remote_cmd = ' '.join(env_cmd + cmd)
|
||||
if remote_work_dir != '.':
|
||||
remote_cmd = 'cd ' + remote_work_dir + ' && ' + remote_cmd
|
||||
return self.local_run(ssh_cmd + [remote_cmd])
|
||||
out, err, rc = self.local_run(ssh_cmd + [remote_cmd])
|
||||
return (remote_cmd, out, err, rc)
|
||||
|
||||
@@ -87,14 +87,22 @@ class LibcxxTestFormat(object):
|
||||
name_root, name_ext = os.path.splitext(name)
|
||||
is_libcxx_test = test.path_in_suite[0] == 'libcxx'
|
||||
is_sh_test = name_root.endswith('.sh')
|
||||
is_pass_test = name.endswith('.pass.cpp')
|
||||
is_fail_test = name.endswith('.fail.cpp')
|
||||
assert is_sh_test or name_ext == '.cpp', 'non-cpp file must be sh test'
|
||||
is_pass_test = name.endswith('.pass.cpp') or name.endswith('.pass.mm')
|
||||
is_fail_test = name.endswith('.fail.cpp') or name.endswith('.fail.mm')
|
||||
is_objcxx_test = name.endswith('.mm')
|
||||
is_objcxx_arc_test = name.endswith('.arc.pass.mm') or \
|
||||
name.endswith('.arc.fail.mm')
|
||||
assert is_sh_test or name_ext == '.cpp' or name_ext == '.mm', \
|
||||
'non-cpp file must be sh test'
|
||||
|
||||
if test.config.unsupported:
|
||||
return (lit.Test.UNSUPPORTED,
|
||||
"A lit.local.cfg marked this unsupported")
|
||||
|
||||
if is_objcxx_test and not \
|
||||
'objective-c++' in test.config.available_features:
|
||||
return (lit.Test.UNSUPPORTED, "Objective-C++ is not supported")
|
||||
|
||||
parsers = self._make_custom_parsers()
|
||||
script = lit.TestRunner.parseIntegratedTestScript(
|
||||
test, additional_parsers=parsers, require_script=is_sh_test)
|
||||
@@ -133,13 +141,21 @@ class LibcxxTestFormat(object):
|
||||
if '#define _LIBCPP_ASSERT' in contents:
|
||||
test_cxx.useModules(False)
|
||||
|
||||
if is_objcxx_test:
|
||||
test_cxx.source_lang = 'objective-c++'
|
||||
if is_objcxx_arc_test:
|
||||
test_cxx.compile_flags += ['-fobjc-arc']
|
||||
else:
|
||||
test_cxx.compile_flags += ['-fno-objc-arc']
|
||||
test_cxx.link_flags += ['-framework', 'Foundation']
|
||||
|
||||
# Dispatch the test based on its suffix.
|
||||
if is_sh_test:
|
||||
if not isinstance(self.executor, LocalExecutor):
|
||||
# We can't run ShTest tests with a executor yet.
|
||||
# For now, bail on trying to run them
|
||||
return lit.Test.UNSUPPORTED, 'ShTest format not yet supported'
|
||||
test.config.enviroment = dict(self.exec_env)
|
||||
test.config.environment = dict(self.exec_env)
|
||||
return lit.TestRunner._runShTest(test, lit_config,
|
||||
self.execute_external, script,
|
||||
tmpBase)
|
||||
|
||||
@@ -12,6 +12,7 @@ import lit.util # pylint: disable=import-error,no-name-in-module
|
||||
import locale
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
|
||||
class DefaultTargetInfo(object):
|
||||
@@ -45,37 +46,88 @@ def test_locale(loc):
|
||||
locale.setlocale(locale.LC_ALL, default_locale)
|
||||
|
||||
|
||||
def add_common_locales(features, lit_config):
|
||||
def add_common_locales(features, lit_config, is_windows=False):
|
||||
# A list of locales needed by the test-suite.
|
||||
# The list uses the canonical name for the locale used in the test-suite
|
||||
# TODO: On Linux ISO8859 *may* needs to hyphenated.
|
||||
locales = [
|
||||
'en_US.UTF-8',
|
||||
'fr_FR.UTF-8',
|
||||
'ru_RU.UTF-8',
|
||||
'zh_CN.UTF-8',
|
||||
'fr_CA.ISO8859-1',
|
||||
'cs_CZ.ISO8859-2'
|
||||
('en_US.UTF-8', 'English_United States.1252'),
|
||||
('fr_FR.UTF-8', 'French_France.1252'),
|
||||
('ru_RU.UTF-8', 'Russian_Russia.1251'),
|
||||
('zh_CN.UTF-8', 'Chinese_China.936'),
|
||||
('fr_CA.ISO8859-1', 'French_Canada.1252'),
|
||||
('cs_CZ.ISO8859-2', 'Czech_Czech Republic.1250')
|
||||
]
|
||||
for loc in locales:
|
||||
if test_locale(loc):
|
||||
features.add('locale.{0}'.format(loc))
|
||||
for loc_id, windows_loc_name in locales:
|
||||
loc_name = windows_loc_name if is_windows else loc_id
|
||||
if test_locale(loc_name):
|
||||
features.add('locale.{0}'.format(loc_id))
|
||||
else:
|
||||
lit_config.warning('The locale {0} is not supported by '
|
||||
'your platform. Some tests will be '
|
||||
'unsupported.'.format(loc))
|
||||
'unsupported.'.format(loc_name))
|
||||
|
||||
|
||||
class DarwinLocalTI(DefaultTargetInfo):
|
||||
def __init__(self, full_config):
|
||||
super(DarwinLocalTI, self).__init__(full_config)
|
||||
|
||||
def is_host_macosx(self):
|
||||
name = lit.util.capture(['sw_vers', '-productName']).strip()
|
||||
return name == "Mac OS X"
|
||||
|
||||
def get_macosx_version(self):
|
||||
assert self.is_host_macosx()
|
||||
version = lit.util.capture(['sw_vers', '-productVersion']).strip()
|
||||
version = re.sub(r'([0-9]+\.[0-9]+)(\..*)?', r'\1', version)
|
||||
return version
|
||||
|
||||
def get_sdk_version(self, name):
|
||||
assert self.is_host_macosx()
|
||||
cmd = ['xcrun', '--sdk', name, '--show-sdk-path']
|
||||
try:
|
||||
out = lit.util.capture(cmd).strip()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if not out:
|
||||
self.full_config.lit_config.fatal(
|
||||
"cannot infer sdk version with: %r" % cmd)
|
||||
|
||||
return re.sub(r'.*/[^0-9]+([0-9.]+)\.sdk', r'\1', out)
|
||||
|
||||
def get_platform(self):
|
||||
platform = self.full_config.get_lit_conf('platform')
|
||||
if platform:
|
||||
platform = re.sub(r'([^0-9]+)([0-9\.]*)', r'\1-\2', platform)
|
||||
name, version = tuple(platform.split('-', 1))
|
||||
else:
|
||||
name = 'macosx'
|
||||
version = None
|
||||
|
||||
if version:
|
||||
return (False, name, version)
|
||||
|
||||
# Infer the version, either from the SDK or the system itself. For
|
||||
# macosx, ignore the SDK version; what matters is what's at
|
||||
# /usr/lib/libc++.dylib.
|
||||
if name == 'macosx':
|
||||
version = self.get_macosx_version()
|
||||
else:
|
||||
version = self.get_sdk_version(name)
|
||||
return (True, name, version)
|
||||
|
||||
def add_locale_features(self, features):
|
||||
add_common_locales(features, self.full_config.lit_config)
|
||||
|
||||
def add_cxx_compile_flags(self, flags):
|
||||
if self.full_config.use_deployment:
|
||||
_, name, _ = self.full_config.config.deployment
|
||||
cmd = ['xcrun', '--sdk', name, '--show-sdk-path']
|
||||
else:
|
||||
cmd = ['xcrun', '--show-sdk-path']
|
||||
try:
|
||||
out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
|
||||
out = lit.util.capture(cmd).strip()
|
||||
res = 0
|
||||
except OSError:
|
||||
res = -1
|
||||
@@ -91,6 +143,8 @@ class DarwinLocalTI(DefaultTargetInfo):
|
||||
library_paths = []
|
||||
# Configure the library path for libc++
|
||||
if self.full_config.use_system_cxx_lib:
|
||||
if (os.path.isdir(str(self.full_config.use_system_cxx_lib))):
|
||||
library_paths += [self.full_config.use_system_cxx_lib]
|
||||
pass
|
||||
elif self.full_config.cxx_runtime_root:
|
||||
library_paths += [self.full_config.cxx_runtime_root]
|
||||
@@ -198,7 +252,8 @@ class WindowsLocalTI(DefaultTargetInfo):
|
||||
super(WindowsLocalTI, self).__init__(full_config)
|
||||
|
||||
def add_locale_features(self, features):
|
||||
add_common_locales(features, self.full_config.lit_config)
|
||||
add_common_locales(features, self.full_config.lit_config,
|
||||
is_windows=True)
|
||||
|
||||
def use_lit_shell_default(self):
|
||||
# Default to the internal shell on Windows, as bash on Windows is
|
||||
|
||||
Reference in New Issue
Block a user