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