]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - utils/libcxx/test/config.py
Vendor import of libc++ trunk r302418:
[FreeBSD/FreeBSD.git] / utils / libcxx / test / config.py
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 locale
11 import os
12 import platform
13 import pkgutil
14 import pipes
15 import re
16 import shlex
17 import shutil
18 import sys
19
20 from libcxx.compiler import CXXCompiler
21 from libcxx.test.target_info import make_target_info
22 from libcxx.test.executor import *
23 from libcxx.test.tracing import *
24 import libcxx.util
25
26 def loadSiteConfig(lit_config, config, param_name, env_name):
27     # We haven't loaded the site specific configuration (the user is
28     # probably trying to run on a test file directly, and either the site
29     # configuration hasn't been created by the build system, or we are in an
30     # out-of-tree build situation).
31     site_cfg = lit_config.params.get(param_name,
32                                      os.environ.get(env_name))
33     if not site_cfg:
34         lit_config.warning('No site specific configuration file found!'
35                            ' Running the tests in the default configuration.')
36     elif not os.path.isfile(site_cfg):
37         lit_config.fatal(
38             "Specified site configuration file does not exist: '%s'" %
39             site_cfg)
40     else:
41         lit_config.note('using site specific configuration at %s' % site_cfg)
42         ld_fn = lit_config.load_config
43
44         # Null out the load_config function so that lit.site.cfg doesn't
45         # recursively load a config even if it tries.
46         # TODO: This is one hell of a hack. Fix it.
47         def prevent_reload_fn(*args, **kwargs):
48             pass
49         lit_config.load_config = prevent_reload_fn
50         ld_fn(config, site_cfg)
51         lit_config.load_config = ld_fn
52
53 class Configuration(object):
54     # pylint: disable=redefined-outer-name
55     def __init__(self, lit_config, config):
56         self.lit_config = lit_config
57         self.config = config
58         self.is_windows = platform.system() == 'Windows'
59         self.cxx = None
60         self.cxx_is_clang_cl = None
61         self.cxx_stdlib_under_test = None
62         self.project_obj_root = None
63         self.libcxx_src_root = None
64         self.libcxx_obj_root = None
65         self.cxx_library_root = None
66         self.cxx_runtime_root = None
67         self.abi_library_root = None
68         self.link_shared = self.get_lit_bool('enable_shared', default=True)
69         self.debug_build = self.get_lit_bool('debug_build',   default=False)
70         self.exec_env = {}
71         self.use_target = False
72         self.use_system_cxx_lib = False
73         self.use_clang_verify = False
74         self.long_tests = None
75         self.execute_external = False
76
77     def get_lit_conf(self, name, default=None):
78         val = self.lit_config.params.get(name, None)
79         if val is None:
80             val = getattr(self.config, name, None)
81             if val is None:
82                 val = default
83         return val
84
85     def get_lit_bool(self, name, default=None, env_var=None):
86         def check_value(value, var_name):
87             if value is None:
88                 return default
89             if isinstance(value, bool):
90                 return value
91             if not isinstance(value, str):
92                 raise TypeError('expected bool or string')
93             if value.lower() in ('1', 'true'):
94                 return True
95             if value.lower() in ('', '0', 'false'):
96                 return False
97             self.lit_config.fatal(
98                 "parameter '{}' should be true or false".format(var_name))
99
100         conf_val = self.get_lit_conf(name)
101         if env_var is not None and env_var in os.environ and \
102                 os.environ[env_var] is not None:
103             val = os.environ[env_var]
104             if conf_val is not None:
105                 self.lit_config.warning(
106                     'Environment variable %s=%s is overriding explicit '
107                     '--param=%s=%s' % (env_var, val, name, conf_val))
108             return check_value(val, env_var)
109         return check_value(conf_val, name)
110
111     def make_static_lib_name(self, name):
112         """Return the full filename for the specified library name"""
113         if self.is_windows:
114             assert name == 'c++'  # Only allow libc++ to use this function for now.
115             return 'lib' + name + '.lib'
116         else:
117             return 'lib' + name + '.a'
118
119     def configure(self):
120         self.configure_executor()
121         self.configure_use_system_cxx_lib()
122         self.configure_target_info()
123         self.configure_cxx()
124         self.configure_triple()
125         self.configure_deployment()
126         self.configure_availability()
127         self.configure_src_root()
128         self.configure_obj_root()
129         self.configure_cxx_stdlib_under_test()
130         self.configure_cxx_library_root()
131         self.configure_use_clang_verify()
132         self.configure_use_thread_safety()
133         self.configure_execute_external()
134         self.configure_ccache()
135         self.configure_compile_flags()
136         self.configure_filesystem_compile_flags()
137         self.configure_link_flags()
138         self.configure_env()
139         self.configure_color_diagnostics()
140         self.configure_debug_mode()
141         self.configure_warnings()
142         self.configure_sanitizer()
143         self.configure_coverage()
144         self.configure_modules()
145         self.configure_substitutions()
146         self.configure_features()
147
148     def print_config_info(self):
149         # Print the final compile and link flags.
150         self.lit_config.note('Using compiler: %s' % self.cxx.path)
151         self.lit_config.note('Using flags: %s' % self.cxx.flags)
152         if self.cxx.use_modules:
153             self.lit_config.note('Using modules flags: %s' %
154                                  self.cxx.modules_flags)
155         self.lit_config.note('Using compile flags: %s'
156                              % self.cxx.compile_flags)
157         if len(self.cxx.warning_flags):
158             self.lit_config.note('Using warnings: %s' % self.cxx.warning_flags)
159         self.lit_config.note('Using link flags: %s' % self.cxx.link_flags)
160         # Print as list to prevent "set([...])" from being printed.
161         self.lit_config.note('Using available_features: %s' %
162                              list(self.config.available_features))
163         self.lit_config.note('Using environment: %r' % self.exec_env)
164         sys.stderr.flush()  # Force flushing to avoid broken output on Windows
165
166     def get_test_format(self):
167         from libcxx.test.format import LibcxxTestFormat
168         return LibcxxTestFormat(
169             self.cxx,
170             self.use_clang_verify,
171             self.execute_external,
172             self.executor,
173             exec_env=self.exec_env)
174
175     def configure_executor(self):
176         exec_str = self.get_lit_conf('executor', "None")
177         te = eval(exec_str)
178         if te:
179             self.lit_config.note("Using executor: %r" % exec_str)
180             if self.lit_config.useValgrind:
181                 # We have no way of knowing where in the chain the
182                 # ValgrindExecutor is supposed to go. It is likely
183                 # that the user wants it at the end, but we have no
184                 # way of getting at that easily.
185                 selt.lit_config.fatal("Cannot infer how to create a Valgrind "
186                                       " executor.")
187         else:
188             te = LocalExecutor()
189             if self.lit_config.useValgrind:
190                 te = ValgrindExecutor(self.lit_config.valgrindArgs, te)
191         self.executor = te
192
193     def configure_target_info(self):
194         self.target_info = make_target_info(self)
195
196     def configure_cxx(self):
197         # Gather various compiler parameters.
198         cxx = self.get_lit_conf('cxx_under_test')
199         self.cxx_is_clang_cl = cxx is not None and \
200                                os.path.basename(cxx) == 'clang-cl.exe'
201         # If no specific cxx_under_test was given, attempt to infer it as
202         # clang++.
203         if cxx is None or self.cxx_is_clang_cl:
204             search_paths = self.config.environment['PATH']
205             if cxx is not None and os.path.isabs(cxx):
206                 search_paths = os.path.dirname(cxx)
207             clangxx = libcxx.util.which('clang++', search_paths)
208             if clangxx:
209                 cxx = clangxx
210                 self.lit_config.note(
211                     "inferred cxx_under_test as: %r" % cxx)
212             elif self.cxx_is_clang_cl:
213                 self.lit_config.fatal('Failed to find clang++ substitution for'
214                                       ' clang-cl')
215         if not cxx:
216             self.lit_config.fatal('must specify user parameter cxx_under_test '
217                                   '(e.g., --param=cxx_under_test=clang++)')
218         self.cxx = CXXCompiler(cxx) if not self.cxx_is_clang_cl else \
219                    self._configure_clang_cl(cxx)
220         cxx_type = self.cxx.type
221         if cxx_type is not None:
222             assert self.cxx.version is not None
223             maj_v, min_v, _ = self.cxx.version
224             self.config.available_features.add(cxx_type)
225             self.config.available_features.add('%s-%s' % (cxx_type, maj_v))
226             self.config.available_features.add('%s-%s.%s' % (
227                 cxx_type, maj_v, min_v))
228         self.cxx.compile_env = dict(os.environ)
229         # 'CCACHE_CPP2' prevents ccache from stripping comments while
230         # preprocessing. This is required to prevent stripping of '-verify'
231         # comments.
232         self.cxx.compile_env['CCACHE_CPP2'] = '1'
233
234     def _configure_clang_cl(self, clang_path):
235         def _split_env_var(var):
236             return [p.strip() for p in os.environ.get(var, '').split(';') if p.strip()]
237
238         def _prefixed_env_list(var, prefix):
239             from itertools import chain
240             return list(chain.from_iterable((prefix, path) for path in _split_env_var(var)))
241
242         assert self.cxx_is_clang_cl
243         flags = []
244         compile_flags = _prefixed_env_list('INCLUDE', '-isystem')
245         link_flags = _prefixed_env_list('LIB', '-L')
246         for path in _split_env_var('LIB'):
247             self.add_path(self.exec_env, path)
248         return CXXCompiler(clang_path, flags=flags,
249                            compile_flags=compile_flags,
250                            link_flags=link_flags)
251
252
253     def configure_src_root(self):
254         self.libcxx_src_root = self.get_lit_conf(
255             'libcxx_src_root', os.path.dirname(self.config.test_source_root))
256
257     def configure_obj_root(self):
258         self.project_obj_root = self.get_lit_conf('project_obj_root')
259         self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
260         if not self.libcxx_obj_root and self.project_obj_root is not None:
261             possible_root = os.path.join(self.project_obj_root, 'projects', 'libcxx')
262             if os.path.isdir(possible_root):
263                 self.libcxx_obj_root = possible_root
264             else:
265                 self.libcxx_obj_root = self.project_obj_root
266
267     def configure_cxx_library_root(self):
268         self.cxx_library_root = self.get_lit_conf('cxx_library_root',
269                                                   self.libcxx_obj_root)
270         self.cxx_runtime_root = self.get_lit_conf('cxx_runtime_root',
271                                                    self.cxx_library_root)
272
273     def configure_use_system_cxx_lib(self):
274         # This test suite supports testing against either the system library or
275         # the locally built one; the former mode is useful for testing ABI
276         # compatibility between the current headers and a shipping dynamic
277         # library.
278         # Default to testing against the locally built libc++ library.
279         self.use_system_cxx_lib = self.get_lit_conf('use_system_cxx_lib')
280         if self.use_system_cxx_lib == 'true':
281             self.use_system_cxx_lib = True
282         elif self.use_system_cxx_lib == 'false':
283             self.use_system_cxx_lib = False
284         elif self.use_system_cxx_lib:
285             assert os.path.isdir(self.use_system_cxx_lib)
286         self.lit_config.note(
287             "inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
288
289     def configure_availability(self):
290         # See http://llvm.org/docs/AvailabilityMarkup.html
291         self.with_availability = self.get_lit_bool('with_availability', False)
292         self.lit_config.note(
293             "inferred with_availability as: %r" % self.with_availability)
294
295     def configure_cxx_stdlib_under_test(self):
296         self.cxx_stdlib_under_test = self.get_lit_conf(
297             'cxx_stdlib_under_test', 'libc++')
298         if self.cxx_stdlib_under_test not in \
299                 ['libc++', 'libstdc++', 'msvc', 'cxx_default']:
300             self.lit_config.fatal(
301                 'unsupported value for "cxx_stdlib_under_test": %s'
302                 % self.cxx_stdlib_under_test)
303         self.config.available_features.add(self.cxx_stdlib_under_test)
304         if self.cxx_stdlib_under_test == 'libstdc++':
305             self.config.available_features.add('libstdc++')
306             # Manually enable the experimental and filesystem tests for libstdc++
307             # if the options aren't present.
308             # FIXME this is a hack.
309             if self.get_lit_conf('enable_experimental') is None:
310                 self.config.enable_experimental = 'true'
311             if self.get_lit_conf('enable_filesystem') is None:
312                 self.config.enable_filesystem = 'true'
313
314     def configure_use_clang_verify(self):
315         '''If set, run clang with -verify on failing tests.'''
316         if self.with_availability:
317             self.use_clang_verify = False
318             return
319         self.use_clang_verify = self.get_lit_bool('use_clang_verify')
320         if self.use_clang_verify is None:
321             # NOTE: We do not test for the -verify flag directly because
322             #   -verify will always exit with non-zero on an empty file.
323             self.use_clang_verify = self.cxx.isVerifySupported()
324             self.lit_config.note(
325                 "inferred use_clang_verify as: %r" % self.use_clang_verify)
326         if self.use_clang_verify:
327                 self.config.available_features.add('verify-support')
328
329     def configure_use_thread_safety(self):
330         '''If set, run clang with -verify on failing tests.'''
331         has_thread_safety = self.cxx.hasCompileFlag('-Werror=thread-safety')
332         if has_thread_safety:
333             self.cxx.compile_flags += ['-Werror=thread-safety']
334             self.config.available_features.add('thread-safety')
335             self.lit_config.note("enabling thread-safety annotations")
336
337     def configure_execute_external(self):
338         # Choose between lit's internal shell pipeline runner and a real shell.
339         # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
340         # default value. Otherwise we ask the target_info.
341         use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
342         if use_lit_shell_default is not None:
343             use_lit_shell_default = use_lit_shell_default != '0'
344         else:
345             use_lit_shell_default = self.target_info.use_lit_shell_default()
346         # Check for the command line parameter using the default value if it is
347         # not present.
348         use_lit_shell = self.get_lit_bool('use_lit_shell',
349                                           use_lit_shell_default)
350         self.execute_external = not use_lit_shell
351
352     def configure_ccache(self):
353         use_ccache_default = os.environ.get('LIBCXX_USE_CCACHE') is not None
354         use_ccache = self.get_lit_bool('use_ccache', use_ccache_default)
355         if use_ccache:
356             self.cxx.use_ccache = True
357             self.lit_config.note('enabling ccache')
358
359     def add_deployment_feature(self, feature):
360         (arch, name, version) = self.config.deployment
361         self.config.available_features.add('%s=%s-%s' % (feature, arch, name))
362         self.config.available_features.add('%s=%s' % (feature, name))
363         self.config.available_features.add('%s=%s%s' % (feature, name, version))
364
365     def configure_features(self):
366         additional_features = self.get_lit_conf('additional_features')
367         if additional_features:
368             for f in additional_features.split(','):
369                 self.config.available_features.add(f.strip())
370         self.target_info.add_locale_features(self.config.available_features)
371
372         target_platform = self.target_info.platform()
373
374         # Write an "available feature" that combines the triple when
375         # use_system_cxx_lib is enabled. This is so that we can easily write
376         # XFAIL markers for tests that are known to fail with versions of
377         # libc++ as were shipped with a particular triple.
378         if self.use_system_cxx_lib:
379             self.config.available_features.add('with_system_cxx_lib')
380             self.config.available_features.add(
381                 'with_system_cxx_lib=%s' % self.config.target_triple)
382
383             # Add subcomponents individually.
384             target_components = self.config.target_triple.split('-')
385             for component in target_components:
386                 self.config.available_features.add(
387                     'with_system_cxx_lib=%s' % component)
388
389             # Add available features for more generic versions of the target
390             # triple attached to  with_system_cxx_lib.
391             if self.use_deployment:
392                 self.add_deployment_feature('with_system_cxx_lib')
393
394         # Configure the availability markup checks features.
395         if self.with_availability:
396             self.config.available_features.add('availability_markup')
397             self.add_deployment_feature('availability_markup')
398
399         if self.use_system_cxx_lib or self.with_availability:
400             self.config.available_features.add('availability')
401             self.add_deployment_feature('availability')
402
403         if platform.system() == 'Darwin':
404             self.config.available_features.add('apple-darwin')
405
406         # Insert the platform name into the available features as a lower case.
407         self.config.available_features.add(target_platform)
408
409         # Simulator testing can take a really long time for some of these tests
410         # so add a feature check so we can REQUIRES: long_tests in them
411         self.long_tests = self.get_lit_bool('long_tests')
412         if self.long_tests is None:
413             # Default to running long tests.
414             self.long_tests = True
415             self.lit_config.note(
416                 "inferred long_tests as: %r" % self.long_tests)
417
418         if self.long_tests:
419             self.config.available_features.add('long_tests')
420
421         # Run a compile test for the -fsized-deallocation flag. This is needed
422         # in test/std/language.support/support.dynamic/new.delete
423         if self.cxx.hasCompileFlag('-fsized-deallocation'):
424             self.config.available_features.add('fsized-deallocation')
425
426         if self.cxx.hasCompileFlag('-faligned-allocation'):
427             self.config.available_features.add('-faligned-allocation')
428         else:
429             # FIXME remove this once more than just clang-4.0 support
430             # C++17 aligned allocation.
431             self.config.available_features.add('no-aligned-allocation')
432
433         if self.get_lit_bool('has_libatomic', False):
434             self.config.available_features.add('libatomic')
435
436         macros = self.cxx.dumpMacros()
437         if '__cpp_if_constexpr' not in macros:
438             self.config.available_features.add('libcpp-no-if-constexpr')
439
440         if '__cpp_structured_bindings' not in macros:
441             self.config.available_features.add('libcpp-no-structured-bindings')
442
443         if '__cpp_deduction_guides' not in macros:
444             self.config.available_features.add('libcpp-no-deduction-guides')
445
446         if self.is_windows:
447             self.config.available_features.add('windows')
448             if self.cxx_stdlib_under_test == 'libc++':
449                 # LIBCXX-WINDOWS-FIXME is the feature name used to XFAIL the
450                 # initial Windows failures until they can be properly diagnosed
451                 # and fixed. This allows easier detection of new test failures
452                 # and regressions. Note: New failures should not be suppressed
453                 # using this feature. (Also see llvm.org/PR32730)
454                 self.config.available_features.add('LIBCXX-WINDOWS-FIXME')
455
456         # Attempt to detect the glibc version by querying for __GLIBC__
457         # in 'features.h'.
458         macros = self.cxx.dumpMacros(flags=['-include', 'features.h'])
459         if macros is not None and '__GLIBC__' in macros:
460             maj_v, min_v = (macros['__GLIBC__'], macros['__GLIBC_MINOR__'])
461             self.config.available_features.add('glibc')
462             self.config.available_features.add('glibc-%s' % maj_v)
463             self.config.available_features.add('glibc-%s.%s' % (maj_v, min_v))
464
465     def configure_compile_flags(self):
466         no_default_flags = self.get_lit_bool('no_default_flags', False)
467         if not no_default_flags:
468             self.configure_default_compile_flags()
469         # This include is always needed so add so add it regardless of
470         # 'no_default_flags'.
471         support_path = os.path.join(self.libcxx_src_root, 'test/support')
472         self.cxx.compile_flags += ['-I' + support_path]
473         # Configure extra flags
474         compile_flags_str = self.get_lit_conf('compile_flags', '')
475         self.cxx.compile_flags += shlex.split(compile_flags_str)
476         # FIXME: Can we remove this?
477         if self.is_windows:
478             self.cxx.compile_flags += ['-D_CRT_SECURE_NO_WARNINGS']
479
480     def configure_default_compile_flags(self):
481         # Try and get the std version from the command line. Fall back to
482         # default given in lit.site.cfg is not present. If default is not
483         # present then force c++11.
484         std = self.get_lit_conf('std')
485         if not std:
486             # Choose the newest possible language dialect if none is given.
487             possible_stds = ['c++1z', 'c++14', 'c++11', 'c++03']
488             if self.cxx.type == 'gcc':
489                 maj_v, _, _ = self.cxx.version
490                 maj_v = int(maj_v)
491                 if maj_v < 7:
492                     possible_stds.remove('c++1z')
493                 # FIXME: How many C++14 tests actually fail under GCC 5 and 6?
494                 # Should we XFAIL them individually instead?
495                 if maj_v <= 6:
496                     possible_stds.remove('c++14')
497             for s in possible_stds:
498                 if self.cxx.hasCompileFlag('-std=%s' % s):
499                     std = s
500                     self.lit_config.note(
501                         'inferred language dialect as: %s' % std)
502                     break
503             if not std:
504                 self.lit_config.fatal(
505                     'Failed to infer a supported language dialect from one of %r'
506                     % possible_stds)
507         self.cxx.compile_flags += ['-std={0}'.format(std)]
508         self.config.available_features.add(std.replace('gnu++', 'c++'))
509         # Configure include paths
510         self.configure_compile_flags_header_includes()
511         self.target_info.add_cxx_compile_flags(self.cxx.compile_flags)
512         # Configure feature flags.
513         self.configure_compile_flags_exceptions()
514         self.configure_compile_flags_rtti()
515         self.configure_compile_flags_abi_version()
516         enable_32bit = self.get_lit_bool('enable_32bit', False)
517         if enable_32bit:
518             self.cxx.flags += ['-m32']
519         # Use verbose output for better errors
520         self.cxx.flags += ['-v']
521         sysroot = self.get_lit_conf('sysroot')
522         if sysroot:
523             self.cxx.flags += ['--sysroot', sysroot]
524         gcc_toolchain = self.get_lit_conf('gcc_toolchain')
525         if gcc_toolchain:
526             self.cxx.flags += ['-gcc-toolchain', gcc_toolchain]
527         # NOTE: the _DEBUG definition must preceed the triple check because for
528         # the Windows build of libc++, the forced inclusion of a header requires
529         # that _DEBUG is defined.  Incorrect ordering will result in -target
530         # being elided.
531         if self.is_windows and self.debug_build:
532             self.cxx.compile_flags += ['-D_DEBUG']
533         if self.use_target:
534             if not self.cxx.addFlagIfSupported(
535                     ['-target', self.config.target_triple]):
536                 self.lit_config.warning('use_target is true but -target is '\
537                         'not supported by the compiler')
538         if self.use_deployment:
539             arch, name, version = self.config.deployment
540             self.cxx.flags += ['-arch', arch]
541             self.cxx.flags += ['-m' + name + '-version-min=' + version]
542
543         # Disable availability unless explicitely requested
544         if not self.with_availability:
545             self.cxx.flags += ['-D_LIBCPP_DISABLE_AVAILABILITY']
546
547     def configure_compile_flags_header_includes(self):
548         support_path = os.path.join(self.libcxx_src_root, 'test', 'support')
549         if self.cxx_stdlib_under_test != 'libstdc++' and \
550            not self.is_windows:
551             self.cxx.compile_flags += [
552                 '-include', os.path.join(support_path, 'nasty_macros.hpp')]
553         if self.cxx_stdlib_under_test == 'msvc':
554             self.cxx.compile_flags += [
555                 '-include', os.path.join(support_path,
556                                          'msvc_stdlib_force_include.hpp')]
557             pass
558         if self.is_windows and self.debug_build and \
559                 self.cxx_stdlib_under_test != 'msvc':
560             self.cxx.compile_flags += [
561                 '-include', os.path.join(support_path,
562                                          'set_windows_crt_report_mode.h')
563             ]
564         self.configure_config_site_header()
565         cxx_headers = self.get_lit_conf('cxx_headers')
566         if cxx_headers == '' or (cxx_headers is None
567                                  and self.cxx_stdlib_under_test != 'libc++'):
568             self.lit_config.note('using the system cxx headers')
569             return
570         self.cxx.compile_flags += ['-nostdinc++']
571         if cxx_headers is None:
572             cxx_headers = os.path.join(self.libcxx_src_root, 'include')
573         if not os.path.isdir(cxx_headers):
574             self.lit_config.fatal("cxx_headers='%s' is not a directory."
575                                   % cxx_headers)
576         self.cxx.compile_flags += ['-I' + cxx_headers]
577         if self.libcxx_obj_root is not None:
578             cxxabi_headers = os.path.join(self.libcxx_obj_root, 'include',
579                                           'c++build')
580             if os.path.isdir(cxxabi_headers):
581                 self.cxx.compile_flags += ['-I' + cxxabi_headers]
582
583     def configure_config_site_header(self):
584         # Check for a possible __config_site in the build directory. We
585         # use this if it exists.
586         if self.libcxx_obj_root is None:
587             return
588         config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
589         if not os.path.isfile(config_site_header):
590             return
591         contained_macros = self.parse_config_site_and_add_features(
592             config_site_header)
593         self.lit_config.note('Using __config_site header %s with macros: %r'
594             % (config_site_header, contained_macros))
595         # FIXME: This must come after the call to
596         # 'parse_config_site_and_add_features(...)' in order for it to work.
597         self.cxx.compile_flags += ['-include', config_site_header]
598
599     def parse_config_site_and_add_features(self, header):
600         """ parse_config_site_and_add_features - Deduce and add the test
601             features that that are implied by the #define's in the __config_site
602             header. Return a dictionary containing the macros found in the
603             '__config_site' header.
604         """
605         # Parse the macro contents of __config_site by dumping the macros
606         # using 'c++ -dM -E' and filtering the predefines.
607         predefines = self.cxx.dumpMacros()
608         macros = self.cxx.dumpMacros(header)
609         feature_macros_keys = set(macros.keys()) - set(predefines.keys())
610         feature_macros = {}
611         for k in feature_macros_keys:
612             feature_macros[k] = macros[k]
613         # We expect the header guard to be one of the definitions
614         assert '_LIBCPP_CONFIG_SITE' in feature_macros
615         del feature_macros['_LIBCPP_CONFIG_SITE']
616         # The __config_site header should be non-empty. Otherwise it should
617         # have never been emitted by CMake.
618         assert len(feature_macros) > 0
619         # Transform each macro name into the feature name used in the tests.
620         # Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
621         for m in feature_macros:
622             if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS':
623                 continue
624             if m == '_LIBCPP_ABI_VERSION':
625                 self.config.available_features.add('libcpp-abi-version-v%s'
626                     % feature_macros[m])
627                 continue
628             assert m.startswith('_LIBCPP_HAS_') or m == '_LIBCPP_ABI_UNSTABLE'
629             m = m.lower()[1:].replace('_', '-')
630             self.config.available_features.add(m)
631         return feature_macros
632
633
634
635     def configure_compile_flags_exceptions(self):
636         enable_exceptions = self.get_lit_bool('enable_exceptions', True)
637         if not enable_exceptions:
638             self.config.available_features.add('libcpp-no-exceptions')
639             self.cxx.compile_flags += ['-fno-exceptions']
640
641     def configure_compile_flags_rtti(self):
642         enable_rtti = self.get_lit_bool('enable_rtti', True)
643         if not enable_rtti:
644             self.config.available_features.add('libcpp-no-rtti')
645             self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
646
647     def configure_compile_flags_abi_version(self):
648         abi_version = self.get_lit_conf('abi_version', '').strip()
649         abi_unstable = self.get_lit_bool('abi_unstable')
650         # Only add the ABI version when it is non-default.
651         # FIXME(EricWF): Get the ABI version from the "__config_site".
652         if abi_version and abi_version != '1':
653           self.cxx.compile_flags += ['-D_LIBCPP_ABI_VERSION=' + abi_version]
654         if abi_unstable:
655           self.config.available_features.add('libcpp-abi-unstable')
656           self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
657
658     def configure_filesystem_compile_flags(self):
659         enable_fs = self.get_lit_bool('enable_filesystem', default=False)
660         if not enable_fs:
661             return
662         enable_experimental = self.get_lit_bool('enable_experimental', default=False)
663         if not enable_experimental:
664             self.lit_config.fatal(
665                 'filesystem is enabled but libc++experimental.a is not.')
666         self.config.available_features.add('c++filesystem')
667         static_env = os.path.join(self.libcxx_src_root, 'test', 'std',
668                                   'experimental', 'filesystem', 'Inputs', 'static_test_env')
669         static_env = os.path.realpath(static_env)
670         assert os.path.isdir(static_env)
671         self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_STATIC_TEST_ROOT="%s"' % static_env]
672
673         dynamic_env = os.path.join(self.config.test_exec_root,
674                                    'filesystem', 'Output', 'dynamic_env')
675         dynamic_env = os.path.realpath(dynamic_env)
676         if not os.path.isdir(dynamic_env):
677             os.makedirs(dynamic_env)
678         self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT="%s"' % dynamic_env]
679         self.exec_env['LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT'] = ("%s" % dynamic_env)
680
681         dynamic_helper = os.path.join(self.libcxx_src_root, 'test', 'support',
682                                       'filesystem_dynamic_test_helper.py')
683         assert os.path.isfile(dynamic_helper)
684
685         self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="%s %s"'
686                                    % (sys.executable, dynamic_helper)]
687
688
689     def configure_link_flags(self):
690         no_default_flags = self.get_lit_bool('no_default_flags', False)
691         if not no_default_flags:
692             # Configure library path
693             self.configure_link_flags_cxx_library_path()
694             self.configure_link_flags_abi_library_path()
695
696             # Configure libraries
697             if self.cxx_stdlib_under_test == 'libc++':
698                 self.cxx.link_flags += ['-nodefaultlibs']
699                 # FIXME: Handle MSVCRT as part of the ABI library handling.
700                 if self.is_windows:
701                     self.cxx.link_flags += ['-nostdlib']
702                 self.configure_link_flags_cxx_library()
703                 self.configure_link_flags_abi_library()
704                 self.configure_extra_library_flags()
705             elif self.cxx_stdlib_under_test == 'libstdc++':
706                 enable_fs = self.get_lit_bool('enable_filesystem',
707                                               default=False)
708                 if enable_fs:
709                     self.config.available_features.add('c++experimental')
710                     self.cxx.link_flags += ['-lstdc++fs']
711                 self.cxx.link_flags += ['-lm', '-pthread']
712             elif self.cxx_stdlib_under_test == 'msvc':
713                 # FIXME: Correctly setup debug/release flags here.
714                 pass
715             elif self.cxx_stdlib_under_test == 'cxx_default':
716                 self.cxx.link_flags += ['-pthread']
717             else:
718                 self.lit_config.fatal(
719                     'unsupported value for "use_stdlib_type": %s'
720                     %  use_stdlib_type)
721
722         link_flags_str = self.get_lit_conf('link_flags', '')
723         self.cxx.link_flags += shlex.split(link_flags_str)
724
725     def configure_link_flags_cxx_library_path(self):
726         if not self.use_system_cxx_lib:
727             if self.cxx_library_root:
728                 self.cxx.link_flags += ['-L' + self.cxx_library_root]
729                 if self.is_windows and self.link_shared:
730                     self.add_path(self.cxx.compile_env, self.cxx_library_root)
731             if self.cxx_runtime_root:
732                 if not self.is_windows:
733                     self.cxx.link_flags += ['-Wl,-rpath,' +
734                                             self.cxx_runtime_root]
735                 elif self.is_windows and self.link_shared:
736                     self.add_path(self.exec_env, self.cxx_runtime_root)
737         elif os.path.isdir(str(self.use_system_cxx_lib)):
738             self.cxx.link_flags += ['-L' + self.use_system_cxx_lib]
739             if not self.is_windows:
740                 self.cxx.link_flags += ['-Wl,-rpath,' +
741                                         self.use_system_cxx_lib]
742             if self.is_windows and self.link_shared:
743                 self.add_path(self.cxx.compile_env, self.use_system_cxx_lib)
744
745     def configure_link_flags_abi_library_path(self):
746         # Configure ABI library paths.
747         self.abi_library_root = self.get_lit_conf('abi_library_path')
748         if self.abi_library_root:
749             self.cxx.link_flags += ['-L' + self.abi_library_root]
750             if not self.is_windows:
751                 self.cxx.link_flags += ['-Wl,-rpath,' + self.abi_library_root]
752             else:
753                 self.add_path(self.exec_env, self.abi_library_root)
754
755     def configure_link_flags_cxx_library(self):
756         libcxx_experimental = self.get_lit_bool('enable_experimental', default=False)
757         if libcxx_experimental:
758             self.config.available_features.add('c++experimental')
759             self.cxx.link_flags += ['-lc++experimental']
760         if self.link_shared:
761             self.cxx.link_flags += ['-lc++']
762         else:
763             cxx_library_root = self.get_lit_conf('cxx_library_root')
764             if cxx_library_root:
765                 libname = self.make_static_lib_name('c++')
766                 abs_path = os.path.join(cxx_library_root, libname)
767                 assert os.path.exists(abs_path) and \
768                        "static libc++ library does not exist"
769                 self.cxx.link_flags += [abs_path]
770             else:
771                 self.cxx.link_flags += ['-lc++']
772
773     def configure_link_flags_abi_library(self):
774         cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
775         if cxx_abi == 'libstdc++':
776             self.cxx.link_flags += ['-lstdc++']
777         elif cxx_abi == 'libsupc++':
778             self.cxx.link_flags += ['-lsupc++']
779         elif cxx_abi == 'libcxxabi':
780             if self.target_info.allow_cxxabi_link():
781                 libcxxabi_shared = self.get_lit_bool('libcxxabi_shared', default=True)
782                 if libcxxabi_shared:
783                     self.cxx.link_flags += ['-lc++abi']
784                 else:
785                     cxxabi_library_root = self.get_lit_conf('abi_library_path')
786                     if cxxabi_library_root:
787                         libname = self.make_static_lib_name('c++abi')
788                         abs_path = os.path.join(cxxabi_library_root, libname)
789                         self.cxx.link_flags += [abs_path]
790                     else:
791                         self.cxx.link_flags += ['-lc++abi']
792         elif cxx_abi == 'libcxxrt':
793             self.cxx.link_flags += ['-lcxxrt']
794         elif cxx_abi == 'vcruntime':
795             debug_suffix = 'd' if self.debug_build else ''
796             self.cxx.link_flags += ['-l%s%s' % (lib, debug_suffix) for lib in
797                                     ['vcruntime', 'ucrt', 'msvcrt']]
798         elif cxx_abi == 'none' or cxx_abi == 'default':
799             if self.is_windows:
800                 debug_suffix = 'd' if self.debug_build else ''
801                 self.cxx.link_flags += ['-lmsvcrt%s' % debug_suffix]
802         else:
803             self.lit_config.fatal(
804                 'C++ ABI setting %s unsupported for tests' % cxx_abi)
805
806     def configure_extra_library_flags(self):
807         if self.get_lit_bool('cxx_ext_threads', default=False):
808             self.cxx.link_flags += ['-lc++external_threads']
809         self.target_info.add_cxx_link_flags(self.cxx.link_flags)
810
811     def configure_color_diagnostics(self):
812         use_color = self.get_lit_conf('color_diagnostics')
813         if use_color is None:
814             use_color = os.environ.get('LIBCXX_COLOR_DIAGNOSTICS')
815         if use_color is None:
816             return
817         if use_color != '':
818             self.lit_config.fatal('Invalid value for color_diagnostics "%s".'
819                                   % use_color)
820         color_flag = '-fdiagnostics-color=always'
821         # Check if the compiler supports the color diagnostics flag. Issue a
822         # warning if it does not since color diagnostics have been requested.
823         if not self.cxx.hasCompileFlag(color_flag):
824             self.lit_config.warning(
825                 'color diagnostics have been requested but are not supported '
826                 'by the compiler')
827         else:
828             self.cxx.flags += [color_flag]
829
830     def configure_debug_mode(self):
831         debug_level = self.get_lit_conf('debug_level', None)
832         if not debug_level:
833             return
834         if debug_level not in ['0', '1']:
835             self.lit_config.fatal('Invalid value for debug_level "%s".'
836                                   % debug_level)
837         self.cxx.compile_flags += ['-D_LIBCPP_DEBUG=%s' % debug_level]
838
839     def configure_warnings(self):
840         # Turn on warnings by default for Clang based compilers when C++ >= 11
841         default_enable_warnings = self.cxx.type in ['clang', 'apple-clang'] \
842             and len(self.config.available_features.intersection(
843                 ['c++11', 'c++14', 'c++1z'])) != 0
844         enable_warnings = self.get_lit_bool('enable_warnings',
845                                             default_enable_warnings)
846         self.cxx.useWarnings(enable_warnings)
847         self.cxx.warning_flags += [
848             '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER',
849             '-Wall', '-Wextra', '-Werror'
850         ]
851         if self.cxx.hasWarningFlag('-Wuser-defined-warnings'):
852             self.cxx.warning_flags += ['-Wuser-defined-warnings']
853             self.config.available_features.add('diagnose-if-support')
854         self.cxx.addWarningFlagIfSupported('-Wshadow')
855         self.cxx.addWarningFlagIfSupported('-Wno-unused-command-line-argument')
856         self.cxx.addWarningFlagIfSupported('-Wno-attributes')
857         self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move')
858         self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions')
859         self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals')
860         self.cxx.addWarningFlagIfSupported('-Wno-noexcept-type')
861         # These warnings should be enabled in order to support the MSVC
862         # team using the test suite; They enable the warnings below and
863         # expect the test suite to be clean.
864         self.cxx.addWarningFlagIfSupported('-Wsign-compare')
865         self.cxx.addWarningFlagIfSupported('-Wunused-variable')
866         self.cxx.addWarningFlagIfSupported('-Wunused-parameter')
867         self.cxx.addWarningFlagIfSupported('-Wunreachable-code')
868         # FIXME: Enable the two warnings below.
869         self.cxx.addWarningFlagIfSupported('-Wno-conversion')
870         self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
871         std = self.get_lit_conf('std', None)
872         if std in ['c++98', 'c++03']:
873             # The '#define static_assert' provided by libc++ in C++03 mode
874             # causes an unused local typedef whenever it is used.
875             self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
876
877     def configure_sanitizer(self):
878         san = self.get_lit_conf('use_sanitizer', '').strip()
879         if san:
880             self.target_info.add_sanitizer_features(san, self.config.available_features)
881             # Search for llvm-symbolizer along the compiler path first
882             # and then along the PATH env variable.
883             symbolizer_search_paths = os.environ.get('PATH', '')
884             cxx_path = libcxx.util.which(self.cxx.path)
885             if cxx_path is not None:
886                 symbolizer_search_paths = (
887                     os.path.dirname(cxx_path) +
888                     os.pathsep + symbolizer_search_paths)
889             llvm_symbolizer = libcxx.util.which('llvm-symbolizer',
890                                                 symbolizer_search_paths)
891
892             def add_ubsan():
893                 self.cxx.flags += ['-fsanitize=undefined',
894                                    '-fno-sanitize=vptr,function,float-divide-by-zero',
895                                    '-fno-sanitize-recover=all']
896                 self.exec_env['UBSAN_OPTIONS'] = 'print_stacktrace=1'
897                 self.config.available_features.add('ubsan')
898
899             # Setup the sanitizer compile flags
900             self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
901             if san == 'Address' or san == 'Address;Undefined' or san == 'Undefined;Address':
902                 self.cxx.flags += ['-fsanitize=address']
903                 if llvm_symbolizer is not None:
904                     self.exec_env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
905                 # FIXME: Turn ODR violation back on after PR28391 is resolved
906                 # https://bugs.llvm.org/show_bug.cgi?id=28391
907                 self.exec_env['ASAN_OPTIONS'] = 'detect_odr_violation=0'
908                 self.config.available_features.add('asan')
909                 self.config.available_features.add('sanitizer-new-delete')
910                 self.cxx.compile_flags += ['-O1']
911                 if san == 'Address;Undefined' or san == 'Undefined;Address':
912                     add_ubsan()
913             elif san == 'Memory' or san == 'MemoryWithOrigins':
914                 self.cxx.flags += ['-fsanitize=memory']
915                 if san == 'MemoryWithOrigins':
916                     self.cxx.compile_flags += [
917                         '-fsanitize-memory-track-origins']
918                 if llvm_symbolizer is not None:
919                     self.exec_env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
920                 self.config.available_features.add('msan')
921                 self.config.available_features.add('sanitizer-new-delete')
922                 self.cxx.compile_flags += ['-O1']
923             elif san == 'Undefined':
924                 add_ubsan()
925                 self.cxx.compile_flags += ['-O2']
926             elif san == 'Thread':
927                 self.cxx.flags += ['-fsanitize=thread']
928                 self.config.available_features.add('tsan')
929                 self.config.available_features.add('sanitizer-new-delete')
930             else:
931                 self.lit_config.fatal('unsupported value for '
932                                       'use_sanitizer: {0}'.format(san))
933             san_lib = self.get_lit_conf('sanitizer_library')
934             if san_lib:
935                 self.cxx.link_flags += [
936                     san_lib, '-Wl,-rpath,%s' % os.path.dirname(san_lib)]
937
938     def configure_coverage(self):
939         self.generate_coverage = self.get_lit_bool('generate_coverage', False)
940         if self.generate_coverage:
941             self.cxx.flags += ['-g', '--coverage']
942             self.cxx.compile_flags += ['-O0']
943
944     def configure_modules(self):
945         modules_flags = ['-fmodules']
946         if platform.system() != 'Darwin':
947             modules_flags += ['-Xclang', '-fmodules-local-submodule-visibility']
948         supports_modules = self.cxx.hasCompileFlag(modules_flags)
949         enable_modules = self.get_lit_bool('enable_modules',
950                                            default=False,
951                                            env_var='LIBCXX_ENABLE_MODULES')
952         if enable_modules and not supports_modules:
953             self.lit_config.fatal(
954                 '-fmodules is enabled but not supported by the compiler')
955         if not supports_modules:
956             return
957         self.config.available_features.add('modules-support')
958         module_cache = os.path.join(self.config.test_exec_root,
959                                    'modules.cache')
960         module_cache = os.path.realpath(module_cache)
961         if os.path.isdir(module_cache):
962             shutil.rmtree(module_cache)
963         os.makedirs(module_cache)
964         self.cxx.modules_flags = modules_flags + \
965             ['-fmodules-cache-path=' + module_cache]
966         if enable_modules:
967             self.config.available_features.add('-fmodules')
968             self.cxx.useModules()
969
970     def configure_substitutions(self):
971         sub = self.config.substitutions
972         cxx_path = pipes.quote(self.cxx.path)
973         # Configure compiler substitutions
974         sub.append(('%cxx', cxx_path))
975         # Configure flags substitutions
976         flags_str = ' '.join([pipes.quote(f) for f in self.cxx.flags])
977         compile_flags_str = ' '.join([pipes.quote(f) for f in self.cxx.compile_flags])
978         link_flags_str = ' '.join([pipes.quote(f) for f in self.cxx.link_flags])
979         all_flags = '%s %s %s' % (flags_str, compile_flags_str, link_flags_str)
980         sub.append(('%flags', flags_str))
981         sub.append(('%compile_flags', compile_flags_str))
982         sub.append(('%link_flags', link_flags_str))
983         sub.append(('%all_flags', all_flags))
984         if self.cxx.isVerifySupported():
985             verify_str = ' ' + ' '.join(self.cxx.verify_flags) + ' '
986             sub.append(('%verify', verify_str))
987         # Add compile and link shortcuts
988         compile_str = (cxx_path + ' -o %t.o %s -c ' + flags_str
989                        + ' ' + compile_flags_str)
990         link_str = (cxx_path + ' -o %t.exe %t.o ' + flags_str + ' '
991                     + link_flags_str)
992         assert type(link_str) is str
993         build_str = cxx_path + ' -o %t.exe %s ' + all_flags
994         if self.cxx.use_modules:
995             sub.append(('%compile_module', compile_str))
996             sub.append(('%build_module', build_str))
997         elif self.cxx.modules_flags is not None:
998             modules_str = ' '.join(self.cxx.modules_flags) + ' '
999             sub.append(('%compile_module', compile_str + ' ' + modules_str))
1000             sub.append(('%build_module', build_str + ' ' + modules_str))
1001         sub.append(('%compile', compile_str))
1002         sub.append(('%link', link_str))
1003         sub.append(('%build', build_str))
1004         # Configure exec prefix substitutions.
1005         exec_env_str = ''
1006         if not self.is_windows and len(self.exec_env) != 0:
1007             exec_env_str = 'env '
1008             for k, v in self.exec_env.items():
1009                 exec_env_str += ' %s=%s' % (k, v)
1010         # Configure run env substitution.
1011         exec_str = exec_env_str
1012         if self.lit_config.useValgrind:
1013             exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
1014         sub.append(('%exec', exec_str))
1015         # Configure run shortcut
1016         sub.append(('%run', exec_str + ' %t.exe'))
1017         # Configure not program substitutions
1018         not_py = os.path.join(self.libcxx_src_root, 'utils', 'not.py')
1019         not_str = '%s %s ' % (pipes.quote(sys.executable), pipes.quote(not_py))
1020         sub.append(('not ', not_str))
1021
1022     def can_use_deployment(self):
1023         # Check if the host is on an Apple platform using clang.
1024         if not self.target_info.platform() == "darwin":
1025             return False
1026         if not self.target_info.is_host_macosx():
1027             return False
1028         if not self.cxx.type.endswith('clang'):
1029             return False
1030         return True
1031
1032     def configure_triple(self):
1033         # Get or infer the target triple.
1034         target_triple = self.get_lit_conf('target_triple')
1035         self.use_target = self.get_lit_bool('use_target', False)
1036         if self.use_target and target_triple:
1037             self.lit_config.warning('use_target is true but no triple is specified')
1038
1039         # Use deployment if possible.
1040         self.use_deployment = not self.use_target and self.can_use_deployment()
1041         if self.use_deployment:
1042             return
1043
1044         # Save the triple (and warn on Apple platforms).
1045         self.config.target_triple = target_triple
1046         if self.use_target and 'apple' in target_triple:
1047             self.lit_config.warning('consider using arch and platform instead'
1048                                     ' of target_triple on Apple platforms')
1049
1050         # If no target triple was given, try to infer it from the compiler
1051         # under test.
1052         if not self.config.target_triple:
1053             target_triple = self.cxx.getTriple()
1054             # Drop sub-major version components from the triple, because the
1055             # current XFAIL handling expects exact matches for feature checks.
1056             # Example: x86_64-apple-darwin14.0.0 -> x86_64-apple-darwin14
1057             # The 5th group handles triples greater than 3 parts
1058             # (ex x86_64-pc-linux-gnu).
1059             target_triple = re.sub(r'([^-]+)-([^-]+)-([^.]+)([^-]*)(.*)',
1060                                    r'\1-\2-\3\5', target_triple)
1061             # linux-gnu is needed in the triple to properly identify linuxes
1062             # that use GLIBC. Handle redhat and opensuse triples as special
1063             # cases and append the missing `-gnu` portion.
1064             if (target_triple.endswith('redhat-linux') or
1065                 target_triple.endswith('suse-linux')):
1066                 target_triple += '-gnu'
1067             self.config.target_triple = target_triple
1068             self.lit_config.note(
1069                 "inferred target_triple as: %r" % self.config.target_triple)
1070
1071     def configure_deployment(self):
1072         assert not self.use_deployment is None
1073         assert not self.use_target is None
1074         if not self.use_deployment:
1075             # Warn about ignored parameters.
1076             if self.get_lit_conf('arch'):
1077                 self.lit_config.warning('ignoring arch, using target_triple')
1078             if self.get_lit_conf('platform'):
1079                 self.lit_config.warning('ignoring platform, using target_triple')
1080             return
1081
1082         assert not self.use_target
1083         assert self.target_info.is_host_macosx()
1084
1085         # Always specify deployment explicitly on Apple platforms, since
1086         # otherwise a platform is picked up from the SDK.  If the SDK version
1087         # doesn't match the system version, tests that use the system library
1088         # may fail spuriously.
1089         arch = self.get_lit_conf('arch')
1090         if not arch:
1091             arch = self.cxx.getTriple().split('-', 1)[0]
1092             self.lit_config.note("inferred arch as: %r" % arch)
1093
1094         inferred_platform, name, version = self.target_info.get_platform()
1095         if inferred_platform:
1096             self.lit_config.note("inferred platform as: %r" % (name + version))
1097         self.config.deployment = (arch, name, version)
1098
1099         # Set the target triple for use by lit.
1100         self.config.target_triple = arch + '-apple-' + name + version
1101         self.lit_config.note(
1102             "computed target_triple as: %r" % self.config.target_triple)
1103
1104     def configure_env(self):
1105         self.target_info.configure_env(self.exec_env)
1106
1107     def add_path(self, dest_env, new_path):
1108         if 'PATH' not in dest_env:
1109             dest_env['PATH'] = new_path
1110         else:
1111             split_char = ';' if self.is_windows else ':'
1112             dest_env['PATH'] = '%s%s%s' % (new_path, split_char,
1113                                            dest_env['PATH'])