1 #===----------------------------------------------------------------------===//
3 # The LLVM Compiler Infrastructure
5 # This file is dual licensed under the MIT and the University of Illinois Open
6 # Source Licenses. See LICENSE.TXT for details.
8 #===----------------------------------------------------------------------===//
11 import lit.util # pylint: disable=import-error,no-name-in-module
18 class DefaultTargetInfo(object):
19 def __init__(self, full_config):
20 self.full_config = full_config
23 return sys.platform.lower().strip()
25 def add_locale_features(self, features):
26 self.full_config.lit_config.warning(
27 "No locales entry for target_system: %s" % self.platform())
29 def add_cxx_compile_flags(self, flags): pass
30 def add_cxx_link_flags(self, flags): pass
31 def configure_env(self, env): pass
32 def allow_cxxabi_link(self): return True
33 def add_sanitizer_features(self, sanitizer_type, features): pass
34 def use_lit_shell_default(self): return False
38 assert loc is not None
39 default_locale = locale.setlocale(locale.LC_ALL)
41 locale.setlocale(locale.LC_ALL, loc)
46 locale.setlocale(locale.LC_ALL, default_locale)
49 def add_common_locales(features, lit_config):
50 # A list of locales needed by the test-suite.
51 # The list uses the canonical name for the locale used in the test-suite
52 # TODO: On Linux ISO8859 *may* needs to hyphenated.
63 features.add('locale.{0}'.format(loc))
65 lit_config.warning('The locale {0} is not supported by '
66 'your platform. Some tests will be '
67 'unsupported.'.format(loc))
70 class DarwinLocalTI(DefaultTargetInfo):
71 def __init__(self, full_config):
72 super(DarwinLocalTI, self).__init__(full_config)
74 def is_host_macosx(self):
75 name = lit.util.capture(['sw_vers', '-productName']).strip()
76 return name == "Mac OS X"
78 def get_macosx_version(self):
79 assert self.is_host_macosx()
80 version = lit.util.capture(['sw_vers', '-productVersion']).strip()
81 version = re.sub(r'([0-9]+\.[0-9]+)(\..*)?', r'\1', version)
84 def get_sdk_version(self, name):
85 assert self.is_host_macosx()
86 cmd = ['xcrun', '--sdk', name, '--show-sdk-path']
88 out = lit.util.capture(cmd).strip()
93 self.full_config.lit_config.fatal(
94 "cannot infer sdk version with: %r" % cmd)
96 return re.sub(r'.*/[^0-9]+([0-9.]+)\.sdk', r'\1', out)
98 def get_platform(self):
99 platform = self.full_config.get_lit_conf('platform')
101 platform = re.sub(r'([^0-9]+)([0-9\.]*)', r'\1-\2', platform)
102 name, version = tuple(platform.split('-', 1))
108 return (False, name, version)
110 # Infer the version, either from the SDK or the system itself. For
111 # macosx, ignore the SDK version; what matters is what's at
112 # /usr/lib/libc++.dylib.
114 version = self.get_macosx_version()
116 version = self.get_sdk_version(name)
117 return (True, name, version)
119 def add_locale_features(self, features):
120 add_common_locales(features, self.full_config.lit_config)
122 def add_cxx_compile_flags(self, flags):
123 if self.full_config.use_deployment:
124 _, name, _ = self.full_config.config.deployment
125 cmd = ['xcrun', '--sdk', name, '--show-sdk-path']
127 cmd = ['xcrun', '--show-sdk-path']
129 out = lit.util.capture(cmd).strip()
135 self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path)
136 flags += ["-isysroot", sdk_path]
138 def add_cxx_link_flags(self, flags):
139 flags += ['-lSystem']
141 def configure_env(self, env):
143 # Configure the library path for libc++
144 if self.full_config.use_system_cxx_lib:
145 if (os.path.isdir(str(self.full_config.use_system_cxx_lib))):
146 library_paths += [self.full_config.use_system_cxx_lib]
148 elif self.full_config.cxx_runtime_root:
149 library_paths += [self.full_config.cxx_runtime_root]
150 # Configure the abi library path
151 if self.full_config.abi_library_root:
152 library_paths += [self.full_config.abi_library_root]
154 env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
156 def allow_cxxabi_link(self):
158 # libc++ *should* export all of the symbols found in libc++abi on OS X.
159 # For this reason LibcxxConfiguration will not link libc++abi in OS X.
160 # However __cxa_throw_bad_new_array_length doesn't get exported into
161 # libc++ yet so we still need to explicitly link libc++abi when testing
164 if(self.full_config.get_lit_conf('name', '') == 'libc++abi'):
166 # Don't link libc++abi explicitly on OS X because the symbols
167 # should be available in libc++ directly.
170 def add_sanitizer_features(self, sanitizer_type, features):
171 if sanitizer_type == 'Undefined':
172 features.add('sanitizer-new-delete')
175 class FreeBSDLocalTI(DefaultTargetInfo):
176 def __init__(self, full_config):
177 super(FreeBSDLocalTI, self).__init__(full_config)
179 def add_locale_features(self, features):
180 add_common_locales(features, self.full_config.lit_config)
182 def add_cxx_link_flags(self, flags):
183 flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
186 class LinuxLocalTI(DefaultTargetInfo):
187 def __init__(self, full_config):
188 super(LinuxLocalTI, self).__init__(full_config)
193 def platform_name(self):
194 name, _, _ = platform.linux_distribution()
195 name = name.lower().strip()
196 return name # Permitted to be None
198 def platform_ver(self):
199 _, ver, _ = platform.linux_distribution()
200 ver = ver.lower().strip()
201 return ver # Permitted to be None.
203 def add_locale_features(self, features):
204 add_common_locales(features, self.full_config.lit_config)
205 # Some linux distributions have different locale data than others.
206 # Insert the distributions name and name-version into the available
207 # features to allow tests to XFAIL on them.
208 name = self.platform_name()
209 ver = self.platform_ver()
213 features.add('%s-%s' % (name, ver))
215 def add_cxx_compile_flags(self, flags):
216 flags += ['-D__STDC_FORMAT_MACROS',
217 '-D__STDC_LIMIT_MACROS',
218 '-D__STDC_CONSTANT_MACROS']
220 def add_cxx_link_flags(self, flags):
221 enable_threads = ('libcpp-has-no-threads' not in
222 self.full_config.config.available_features)
223 llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
224 shared_libcxx = self.full_config.get_lit_bool('enable_shared', True)
226 if not llvm_unwinder:
227 flags += ['-lgcc_s', '-lgcc']
229 flags += ['-lpthread']
230 if not shared_libcxx:
234 flags += ['-lunwind', '-ldl']
238 use_libatomic = self.full_config.get_lit_bool('use_libatomic', False)
240 flags += ['-latomic']
241 san = self.full_config.get_lit_conf('use_sanitizer', '').strip()
243 # The libraries and their order are taken from the
244 # linkSanitizerRuntimeDeps function in
245 # clang/lib/Driver/Tools.cpp
246 flags += ['-lpthread', '-lrt', '-lm', '-ldl']
249 class WindowsLocalTI(DefaultTargetInfo):
250 def __init__(self, full_config):
251 super(WindowsLocalTI, self).__init__(full_config)
253 def add_locale_features(self, features):
254 add_common_locales(features, self.full_config.lit_config)
256 def use_lit_shell_default(self):
257 # Default to the internal shell on Windows, as bash on Windows is
262 def make_target_info(full_config):
263 default = "libcxx.test.target_info.LocalTI"
264 info_str = full_config.get_lit_conf('target_info', default)
265 if info_str != default:
266 mod_path, _, info = info_str.rpartition('.')
267 mod = importlib.import_module(mod_path)
268 target_info = getattr(mod, info)(full_config)
269 full_config.lit_config.note("inferred target_info as: %r" % info_str)
271 target_system = platform.system()
272 if target_system == 'Darwin': return DarwinLocalTI(full_config)
273 if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config)
274 if target_system == 'Linux': return LinuxLocalTI(full_config)
275 if target_system == 'Windows': return WindowsLocalTI(full_config)
276 return DefaultTargetInfo(full_config)