Home | History | Annotate | Download | only in test
      1 #===----------------------------------------------------------------------===//
      2 #
      3 #                     The LLVM Compiler Infrastructure
      4 #
      5 # This file is dual licensed under the MIT and the University of Illinois Open
      6 # Source Licenses. See LICENSE.TXT for details.
      7 #
      8 #===----------------------------------------------------------------------===//
      9 
     10 import importlib
     11 import lit.util  # pylint: disable=import-error,no-name-in-module
     12 import locale
     13 import os
     14 import platform
     15 import sys
     16 
     17 class DefaultTargetInfo(object):
     18     def __init__(self, full_config):
     19         self.full_config = full_config
     20 
     21     def platform(self):
     22         return sys.platform.lower().strip()
     23 
     24     def add_locale_features(self, features):
     25         self.full_config.lit_config.warning(
     26             "No locales entry for target_system: %s" % self.platform())
     27 
     28     def add_cxx_compile_flags(self, flags): pass
     29     def add_cxx_link_flags(self, flags): pass
     30     def configure_env(self, env): pass
     31     def allow_cxxabi_link(self): return True
     32     def add_sanitizer_features(self, sanitizer_type, features): pass
     33     def use_lit_shell_default(self): return False
     34 
     35 
     36 def test_locale(loc):
     37     assert loc is not None
     38     default_locale = locale.setlocale(locale.LC_ALL)
     39     try:
     40         locale.setlocale(locale.LC_ALL, loc)
     41         return True
     42     except locale.Error:
     43         return False
     44     finally:
     45         locale.setlocale(locale.LC_ALL, default_locale)
     46 
     47 
     48 def add_common_locales(features, lit_config):
     49     # A list of locales needed by the test-suite.
     50     # The list uses the canonical name for the locale used in the test-suite
     51     # TODO: On Linux ISO8859 *may* needs to hyphenated.
     52     locales = [
     53         'en_US.UTF-8',
     54         'fr_FR.UTF-8',
     55         'ru_RU.UTF-8',
     56         'zh_CN.UTF-8',
     57         'fr_CA.ISO8859-1',
     58         'cs_CZ.ISO8859-2'
     59     ]
     60     for loc in locales:
     61         if test_locale(loc):
     62             features.add('locale.{0}'.format(loc))
     63         else:
     64             lit_config.warning('The locale {0} is not supported by '
     65                                'your platform. Some tests will be '
     66                                'unsupported.'.format(loc))
     67 
     68 
     69 class DarwinLocalTI(DefaultTargetInfo):
     70     def __init__(self, full_config):
     71         super(DarwinLocalTI, self).__init__(full_config)
     72 
     73     def add_locale_features(self, features):
     74         add_common_locales(features, self.full_config.lit_config)
     75 
     76     def add_cxx_compile_flags(self, flags):
     77         try:
     78             out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
     79             res = 0
     80         except OSError:
     81             res = -1
     82         if res == 0 and out:
     83             sdk_path = out
     84             self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path)
     85             flags += ["-isysroot", sdk_path]
     86 
     87     def add_cxx_link_flags(self, flags):
     88         flags += ['-lSystem']
     89 
     90     def configure_env(self, env):
     91         library_paths = []
     92         # Configure the library path for libc++
     93         if self.full_config.use_system_cxx_lib:
     94             pass
     95         elif self.full_config.cxx_runtime_root:
     96             library_paths += [self.full_config.cxx_runtime_root]
     97         # Configure the abi library path
     98         if self.full_config.abi_library_root:
     99             library_paths += [self.full_config.abi_library_root]
    100         if library_paths:
    101             env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
    102 
    103     def allow_cxxabi_link(self):
    104         # FIXME: PR27405
    105         # libc++ *should* export all of the symbols found in libc++abi on OS X.
    106         # For this reason LibcxxConfiguration will not link libc++abi in OS X.
    107         # However __cxa_throw_bad_new_array_length doesn't get exported into
    108         # libc++ yet so we still need to explicitly link libc++abi when testing
    109         # libc++abi
    110         # See PR22654.
    111         if(self.full_config.get_lit_conf('name', '') == 'libc++abi'):
    112             return True
    113         # Don't link libc++abi explicitly on OS X because the symbols
    114         # should be available in libc++ directly.
    115         return False
    116 
    117     def add_sanitizer_features(self, sanitizer_type, features):
    118         if sanitizer_type == 'Undefined':
    119             features.add('sanitizer-new-delete')
    120 
    121 
    122 class FreeBSDLocalTI(DefaultTargetInfo):
    123     def __init__(self, full_config):
    124         super(FreeBSDLocalTI, self).__init__(full_config)
    125 
    126     def add_locale_features(self, features):
    127         add_common_locales(features, self.full_config.lit_config)
    128 
    129     def add_cxx_link_flags(self, flags):
    130         flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
    131 
    132 
    133 class LinuxLocalTI(DefaultTargetInfo):
    134     def __init__(self, full_config):
    135         super(LinuxLocalTI, self).__init__(full_config)
    136 
    137     def platform(self):
    138         return 'linux'
    139 
    140     def platform_name(self):
    141         name, _, _ = platform.linux_distribution()
    142         name = name.lower().strip()
    143         return name # Permitted to be None
    144 
    145     def platform_ver(self):
    146         _, ver, _ = platform.linux_distribution()
    147         ver = ver.lower().strip()
    148         return ver # Permitted to be None.
    149 
    150     def add_locale_features(self, features):
    151         add_common_locales(features, self.full_config.lit_config)
    152         # Some linux distributions have different locale data than others.
    153         # Insert the distributions name and name-version into the available
    154         # features to allow tests to XFAIL on them.
    155         name = self.platform_name()
    156         ver = self.platform_ver()
    157         if name:
    158             features.add(name)
    159         if name and ver:
    160             features.add('%s-%s' % (name, ver))
    161 
    162     def add_cxx_compile_flags(self, flags):
    163         flags += ['-D__STDC_FORMAT_MACROS',
    164                   '-D__STDC_LIMIT_MACROS',
    165                   '-D__STDC_CONSTANT_MACROS']
    166 
    167     def add_cxx_link_flags(self, flags):
    168         enable_threads = ('libcpp-has-no-threads' not in
    169                           self.full_config.config.available_features)
    170         llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
    171         shared_libcxx = self.full_config.get_lit_bool('enable_shared', True)
    172         flags += ['-lm']
    173         if not llvm_unwinder:
    174             flags += ['-lgcc_s', '-lgcc']
    175         if enable_threads:
    176             flags += ['-lpthread']
    177             if not shared_libcxx:
    178               flags += ['-lrt']
    179         flags += ['-lc']
    180         if llvm_unwinder:
    181             flags += ['-lunwind', '-ldl']
    182         else:
    183             flags += ['-lgcc_s']
    184         flags += ['-lgcc']
    185         use_libatomic = self.full_config.get_lit_bool('use_libatomic', False)
    186         if use_libatomic:
    187             flags += ['-latomic']
    188         san = self.full_config.get_lit_conf('use_sanitizer', '').strip()
    189         if san:
    190             # The libraries and their order are taken from the
    191             # linkSanitizerRuntimeDeps function in
    192             # clang/lib/Driver/Tools.cpp
    193             flags += ['-lpthread', '-lrt', '-lm', '-ldl']
    194 
    195 
    196 class WindowsLocalTI(DefaultTargetInfo):
    197     def __init__(self, full_config):
    198         super(WindowsLocalTI, self).__init__(full_config)
    199 
    200     def add_locale_features(self, features):
    201         add_common_locales(features, self.full_config.lit_config)
    202 
    203     def use_lit_shell_default(self):
    204         # Default to the internal shell on Windows, as bash on Windows is
    205         # usually very slow.
    206         return True
    207 
    208 
    209 def make_target_info(full_config):
    210     default = "libcxx.test.target_info.LocalTI"
    211     info_str = full_config.get_lit_conf('target_info', default)
    212     if info_str != default:
    213         mod_path, _, info = info_str.rpartition('.')
    214         mod = importlib.import_module(mod_path)
    215         target_info = getattr(mod, info)(full_config)
    216         full_config.lit_config.note("inferred target_info as: %r" % info_str)
    217         return target_info
    218     target_system = platform.system()
    219     if target_system == 'Darwin':  return DarwinLocalTI(full_config)
    220     if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config)
    221     if target_system == 'Linux':   return LinuxLocalTI(full_config)
    222     if target_system == 'Windows': return WindowsLocalTI(full_config)
    223     return DefaultTargetInfo(full_config)
    224