diff options
Diffstat (limited to 'test/libcxx/test/target_info.py')
-rw-r--r-- | test/libcxx/test/target_info.py | 223 |
1 files changed, 185 insertions, 38 deletions
diff --git a/test/libcxx/test/target_info.py b/test/libcxx/test/target_info.py index a61737786896..667644d2fec6 100644 --- a/test/libcxx/test/target_info.py +++ b/test/libcxx/test/target_info.py @@ -1,55 +1,202 @@ +import importlib +import lit.util # pylint: disable=import-error,no-name-in-module import locale +import os import platform import sys -class TargetInfo(object): +class DefaultTargetInfo(object): + def __init__(self, full_config): + self.full_config = full_config + def platform(self): - raise NotImplementedError + return sys.platform.lower().strip() - def system(self): - raise NotImplementedError + def add_locale_features(self, features): + self.full_config.lit_config.warning( + "No locales entry for target_system: %s" % self.platform()) - def platform_ver(self): - raise NotImplementedError + def add_cxx_compile_flags(self, flags): pass + def add_cxx_link_flags(self, flags): pass + def configure_env(self, env): pass + def allow_cxxabi_link(self): return True + def add_sanitizer_features(self, sanitizer_type, features): pass + def use_lit_shell_default(self): return False - def platform_name(self): - raise NotImplementedError - def supports_locale(self, loc): - raise NotImplementedError +def test_locale(loc): + assert loc is not None + default_locale = locale.setlocale(locale.LC_ALL) + try: + locale.setlocale(locale.LC_ALL, loc) + return True + except locale.Error: + return False + finally: + locale.setlocale(locale.LC_ALL, default_locale) -class LocalTI(TargetInfo): - def platform(self): - platform_name = sys.platform.lower().strip() - # Strip the '2' from linux2. - if platform_name.startswith('linux'): - platform_name = 'linux' - return platform_name +def add_common_locales(features, lit_config): + # 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' + ] + for loc in locales: + if test_locale(loc): + features.add('locale.{0}'.format(loc)) + else: + lit_config.warning('The locale {0} is not supported by ' + 'your platform. Some tests will be ' + 'unsupported.'.format(loc)) + + +class DarwinLocalTI(DefaultTargetInfo): + def __init__(self, full_config): + super(DarwinLocalTI, self).__init__(full_config) + + def add_locale_features(self, features): + add_common_locales(feature, self.full_config.lit_config) + + def add_cxx_compile_flags(self, flags): + try: + out = lit.util.capture(['xcrun', '--show-sdk-path']).strip() + res = 0 + except OSError: + res = -1 + if res == 0 and out: + sdk_path = out + self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path) + flags += ["-isysroot", sdk_path] + + def add_cxx_link_flags(self, flags): + flags += ['-lSystem'] + + def configure_env(self, env): + library_paths = [] + # Configure the library path for libc++ + libcxx_library = self.full_config.get_lit_conf('libcxx_library') + if self.full_config.use_system_cxx_lib: + pass + elif libcxx_library: + library_paths += [os.path.dirname(libcxx_library)] + elif self.full_config.cxx_library_root: + library_paths += [self.full_config.cxx_library_root] + # Configure the abi library path + if self.full_config.abi_library_root: + library_paths += [self.full_config.abi_library_root] + if library_paths: + env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths) + + def allow_cxxabi_link(self): + # Don't link libc++abi explicitly on OS X because the symbols + # should be available in libc++ directly. + return False + + def add_sanitizer_features(self, sanitizer_type, features): + if san == 'Undefined': + features.add('sanitizer-new-delete') + + +class FreeBSDLocalTI(DefaultTargetInfo): + def __init__(self, full_config): + super(FreeBSDLocalTI, self).__init__(full_config) - def system(self): - return platform.system() + def add_locale_features(self, features): + add_common_locales(features, self.full_config.lit_config) + + def add_cxx_link_flags(self, flags): + flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt'] + + +class LinuxLocalTI(DefaultTargetInfo): + def __init__(self, full_config): + super(LinuxLocalTI, self).__init__(full_config) + + def platform(self): + return 'linux' def platform_name(self): - if self.platform() == 'linux': - name, _, _ = platform.linux_distribution() - name = name.lower().strip() - if name: - return name - return None + name, _, _ = platform.linux_distribution() + name = name.lower().strip() + return name # Permitted to be None def platform_ver(self): - if self.platform() == 'linux': - _, ver, _ = platform.linux_distribution() - ver = ver.lower().strip() - if ver: - return ver - return None - - def supports_locale(self, loc): - try: - locale.setlocale(locale.LC_ALL, loc) - return True - except locale.Error: - return False + _, ver, _ = platform.linux_distribution() + ver = ver.lower().strip() + return ver # Permitted to be None. + + def add_locale_features(self, features): + add_common_locales(features, self.full_config.lit_config) + # Some linux distributions have different locale data than others. + # Insert the distributions name and name-version into the available + # features to allow tests to XFAIL on them. + name = self.platform_name() + ver = self.platform_ver() + if name: + features.add(name) + if name and ver: + features.add('%s-%s' % (name, ver)) + + def add_cxx_compile_flags(self, flags): + flags += ['-D__STDC_FORMAT_MACROS', + '-D__STDC_LIMIT_MACROS', + '-D__STDC_CONSTANT_MACROS'] + + def add_cxx_link_flags(self, flags): + enable_threads = ('libcpp-has-no-threads' not in + self.full_config.config.available_features) + llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False) + flags += ['-lm'] + if not llvm_unwinder: + flags += ['-lgcc_s', '-lgcc'] + if enable_threads: + flags += ['-lpthread'] + flags += ['-lc'] + if llvm_unwinder: + flags += ['-lunwind', '-ldl'] + else: + flags += ['-lgcc_s', '-lgcc'] + san = self.full_config.get_lit_conf('use_sanitizer', '').strip() + if san: + # The libraries and their order are taken from the + # linkSanitizerRuntimeDeps function in + # clang/lib/Driver/Tools.cpp + flags += ['-lpthread', '-lrt', '-lm', '-ldl'] + + +class WindowsLocalTI(DefaultTargetInfo): + def __init__(self, full_config): + super(WindowsLocalTI, self).__init__(full_config) + + def add_locale_features(self, features): + add_common_locales(features, self.full_config.lit_config) + + def use_lit_shell_default(self): + # Default to the internal shell on Windows, as bash on Windows is + # usually very slow. + return True + + +def make_target_info(full_config): + default = "libcxx.test.target_info.LocalTI" + info_str = full_config.get_lit_conf('target_info', default) + if info_str != default: + mod_path, _, info = info_str.rpartition('.') + mod = importlib.import_module(mod_path) + target_info = getattr(mod, info)(full_config) + full_config.lit_config.note("inferred target_info as: %r" % info_str) + return target_info + target_system = platform.system() + if target_system == 'Darwin': return DarwinLocalTI(full_config) + if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config) + if target_system == 'Linux': return LinuxLocalTI(full_config) + if target_system == 'Windows': return WindowsLocalTI(full_config) + return DefaultTargetInfo(full_config) |