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