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 #===----------------------------------------------------------------------===//
18 from libcxx.util import executeCommand
20 class DefaultTargetInfo(object):
21 def __init__(self, full_config):
22 self.full_config = full_config
25 return sys.platform.lower().strip()
27 def add_locale_features(self, features):
28 self.full_config.lit_config.warning(
29 "No locales entry for target_system: %s" % self.platform())
31 def add_cxx_compile_flags(self, flags): pass
32 def add_cxx_link_flags(self, flags): pass
33 def configure_env(self, env): pass
34 def allow_cxxabi_link(self): return True
35 def add_sanitizer_features(self, sanitizer_type, features): pass
36 def use_lit_shell_default(self): return False
40 assert loc is not None
41 default_locale = locale.setlocale(locale.LC_ALL)
43 locale.setlocale(locale.LC_ALL, loc)
48 locale.setlocale(locale.LC_ALL, default_locale)
51 def add_common_locales(features, lit_config, is_windows=False):
52 # A list of locales needed by the test-suite.
53 # The list uses the canonical name for the locale used in the test-suite
54 # TODO: On Linux ISO8859 *may* needs to hyphenated.
56 ('en_US.UTF-8', 'English_United States.1252'),
57 ('fr_FR.UTF-8', 'French_France.1252'),
58 ('ru_RU.UTF-8', 'Russian_Russia.1251'),
59 ('zh_CN.UTF-8', 'Chinese_China.936'),
60 ('fr_CA.ISO8859-1', 'French_Canada.1252'),
61 ('cs_CZ.ISO8859-2', 'Czech_Czech Republic.1250')
63 for loc_id, windows_loc_name in locales:
64 loc_name = windows_loc_name if is_windows else loc_id
65 if test_locale(loc_name):
66 features.add('locale.{0}'.format(loc_id))
68 lit_config.warning('The locale {0} is not supported by '
69 'your platform. Some tests will be '
70 'unsupported.'.format(loc_name))
73 class DarwinLocalTI(DefaultTargetInfo):
74 def __init__(self, full_config):
75 super(DarwinLocalTI, self).__init__(full_config)
77 def is_host_macosx(self):
78 name = subprocess.check_output(['sw_vers', '-productName']).strip()
79 return name == "Mac OS X"
81 def get_macosx_version(self):
82 assert self.is_host_macosx()
83 version = subprocess.check_output(
84 ['sw_vers', '-productVersion']).strip()
85 version = re.sub(r'([0-9]+\.[0-9]+)(\..*)?', r'\1', version)
88 def get_sdk_version(self, name):
89 assert self.is_host_macosx()
90 cmd = ['xcrun', '--sdk', name, '--show-sdk-path']
92 out = subprocess.check_output(cmd).strip()
97 self.full_config.lit_config.fatal(
98 "cannot infer sdk version with: %r" % cmd)
100 return re.sub(r'.*/[^0-9]+([0-9.]+)\.sdk', r'\1', out)
102 def get_platform(self):
103 platform = self.full_config.get_lit_conf('platform')
105 platform = re.sub(r'([^0-9]+)([0-9\.]*)', r'\1-\2', platform)
106 name, version = tuple(platform.split('-', 1))
112 return (False, name, version)
114 # Infer the version, either from the SDK or the system itself. For
115 # macosx, ignore the SDK version; what matters is what's at
116 # /usr/lib/libc++.dylib.
118 version = self.get_macosx_version()
120 version = self.get_sdk_version(name)
121 return (True, name, version)
123 def add_locale_features(self, features):
124 add_common_locales(features, self.full_config.lit_config)
126 def add_cxx_compile_flags(self, flags):
127 if self.full_config.use_deployment:
128 _, name, _ = self.full_config.config.deployment
129 cmd = ['xcrun', '--sdk', name, '--show-sdk-path']
131 cmd = ['xcrun', '--show-sdk-path']
132 out, err, exit_code = executeCommand(cmd)
134 self.full_config.lit_config.warning("Could not determine macOS SDK path! stderr was " + err)
135 if exit_code == 0 and out:
136 sdk_path = out.strip()
137 self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path)
138 assert isinstance(sdk_path, str)
139 flags += ["-isysroot", sdk_path]
141 def add_cxx_link_flags(self, flags):
142 flags += ['-lSystem']
144 def configure_env(self, env):
146 # Configure the library path for libc++
147 if self.full_config.cxx_runtime_root:
148 library_paths += [self.full_config.cxx_runtime_root]
149 elif self.full_config.use_system_cxx_lib:
150 if (os.path.isdir(str(self.full_config.use_system_cxx_lib))):
151 library_paths += [self.full_config.use_system_cxx_lib]
153 # Configure the abi library path
154 if self.full_config.abi_library_root:
155 library_paths += [self.full_config.abi_library_root]
157 env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
159 def allow_cxxabi_link(self):
161 # libc++ *should* export all of the symbols found in libc++abi on OS X.
162 # For this reason LibcxxConfiguration will not link libc++abi in OS X.
163 # However __cxa_throw_bad_new_array_length doesn't get exported into
164 # libc++ yet so we still need to explicitly link libc++abi when testing
167 if(self.full_config.get_lit_conf('name', '') == 'libc++abi'):
169 # Don't link libc++abi explicitly on OS X because the symbols
170 # should be available in libc++ directly.
174 class FreeBSDLocalTI(DefaultTargetInfo):
175 def __init__(self, full_config):
176 super(FreeBSDLocalTI, self).__init__(full_config)
178 def add_locale_features(self, features):
179 add_common_locales(features, self.full_config.lit_config)
181 def add_cxx_link_flags(self, flags):
182 flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
185 class NetBSDLocalTI(DefaultTargetInfo):
186 def __init__(self, full_config):
187 super(NetBSDLocalTI, self).__init__(full_config)
189 def add_locale_features(self, features):
190 add_common_locales(features, self.full_config.lit_config)
192 def add_cxx_link_flags(self, flags):
193 flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lc++abi',
197 class LinuxLocalTI(DefaultTargetInfo):
198 def __init__(self, full_config):
199 super(LinuxLocalTI, self).__init__(full_config)
204 def platform_name(self):
205 name, _, _ = platform.linux_distribution()
206 # Some distros have spaces, e.g. 'SUSE Linux Enterprise Server'
207 # lit features can't have spaces
208 name = name.lower().strip().replace(' ', '-')
209 return name # Permitted to be None
211 def platform_ver(self):
212 _, ver, _ = platform.linux_distribution()
213 ver = ver.lower().strip().replace(' ', '-')
214 return ver # Permitted to be None.
216 def add_locale_features(self, features):
217 add_common_locales(features, self.full_config.lit_config)
218 # Some linux distributions have different locale data than others.
219 # Insert the distributions name and name-version into the available
220 # features to allow tests to XFAIL on them.
221 name = self.platform_name()
222 ver = self.platform_ver()
226 features.add('%s-%s' % (name, ver))
228 def add_cxx_compile_flags(self, flags):
229 flags += ['-D__STDC_FORMAT_MACROS',
230 '-D__STDC_LIMIT_MACROS',
231 '-D__STDC_CONSTANT_MACROS']
233 def add_cxx_link_flags(self, flags):
234 enable_threads = ('libcpp-has-no-threads' not in
235 self.full_config.config.available_features)
236 llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
237 shared_libcxx = self.full_config.get_lit_bool('enable_shared', True)
238 # FIXME: Remove the need to link -lrt in all the tests, and instead
239 # limit it only to the filesystem tests. This ensures we don't cause an
240 # implicit dependency on librt except when filesystem is needed.
241 enable_fs = self.full_config.get_lit_bool('enable_filesystem',
244 if not llvm_unwinder:
245 flags += ['-lgcc_s', '-lgcc']
247 flags += ['-lpthread']
248 if not shared_libcxx or enable_fs:
252 flags += ['-lunwind', '-ldl']
255 compiler_rt = self.full_config.get_lit_bool('compiler_rt', False)
258 use_libatomic = self.full_config.get_lit_bool('use_libatomic', False)
260 flags += ['-latomic']
261 san = self.full_config.get_lit_conf('use_sanitizer', '').strip()
263 # The libraries and their order are taken from the
264 # linkSanitizerRuntimeDeps function in
265 # clang/lib/Driver/Tools.cpp
266 flags += ['-lpthread', '-lrt', '-lm', '-ldl']
269 class WindowsLocalTI(DefaultTargetInfo):
270 def __init__(self, full_config):
271 super(WindowsLocalTI, self).__init__(full_config)
273 def add_locale_features(self, features):
274 add_common_locales(features, self.full_config.lit_config,
277 def use_lit_shell_default(self):
278 # Default to the internal shell on Windows, as bash on Windows is
283 def make_target_info(full_config):
284 default = "libcxx.test.target_info.LocalTI"
285 info_str = full_config.get_lit_conf('target_info', default)
286 if info_str != default:
287 mod_path, _, info = info_str.rpartition('.')
288 mod = importlib.import_module(mod_path)
289 target_info = getattr(mod, info)(full_config)
290 full_config.lit_config.note("inferred target_info as: %r" % info_str)
292 target_system = platform.system()
293 if target_system == 'Darwin': return DarwinLocalTI(full_config)
294 if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config)
295 if target_system == 'NetBSD': return NetBSDLocalTI(full_config)
296 if target_system == 'Linux': return LinuxLocalTI(full_config)
297 if target_system == 'Windows': return WindowsLocalTI(full_config)
298 return DefaultTargetInfo(full_config)