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"""
114 assert name == 'c++' # Only allow libc++ to use this function for now.
115 return 'lib' + name + '.lib'
117 return 'lib' + name + '.a'
120 self.configure_executor()
121 self.configure_use_system_cxx_lib()
122 self.configure_target_info()
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()
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()
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
166 def get_test_format(self):
167 from libcxx.test.format import LibcxxTestFormat
168 return LibcxxTestFormat(
170 self.use_clang_verify,
171 self.execute_external,
173 exec_env=self.exec_env)
175 def configure_executor(self):
176 exec_str = self.get_lit_conf('executor', "None")
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 "
189 if self.lit_config.useValgrind:
190 te = ValgrindExecutor(self.lit_config.valgrindArgs, te)
193 def configure_target_info(self):
194 self.target_info = make_target_info(self)
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
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)
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'
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'
232 self.cxx.compile_env['CCACHE_CPP2'] = '1'
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()]
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)))
242 assert self.cxx_is_clang_cl
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)
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))
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
265 self.libcxx_obj_root = self.project_obj_root
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)
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
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)
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)
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'
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
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')
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")
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'
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
348 use_lit_shell = self.get_lit_bool('use_lit_shell',
349 use_lit_shell_default)
350 self.execute_external = not use_lit_shell
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)
356 self.cxx.use_ccache = True
357 self.lit_config.note('enabling ccache')
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))
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)
372 target_platform = self.target_info.platform()
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)
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)
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')
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')
399 if self.use_system_cxx_lib or self.with_availability:
400 self.config.available_features.add('availability')
401 self.add_deployment_feature('availability')
403 if platform.system() == 'Darwin':
404 self.config.available_features.add('apple-darwin')
406 # Insert the platform name into the available features as a lower case.
407 self.config.available_features.add(target_platform)
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)
419 self.config.available_features.add('long_tests')
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')
426 if self.cxx.hasCompileFlag('-faligned-allocation'):
427 self.config.available_features.add('-faligned-allocation')
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')
433 if self.get_lit_bool('has_libatomic', False):
434 self.config.available_features.add('libatomic')
436 macros = self.cxx.dumpMacros()
437 if '__cpp_if_constexpr' not in macros:
438 self.config.available_features.add('libcpp-no-if-constexpr')
440 if '__cpp_structured_bindings' not in macros:
441 self.config.available_features.add('libcpp-no-structured-bindings')
443 if '__cpp_deduction_guides' not in macros:
444 self.config.available_features.add('libcpp-no-deduction-guides')
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')
456 # Attempt to detect the glibc version by querying for __GLIBC__
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))
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?
478 self.cxx.compile_flags += ['-D_CRT_SECURE_NO_WARNINGS']
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')
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
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?
496 possible_stds.remove('c++14')
497 for s in possible_stds:
498 if self.cxx.hasCompileFlag('-std=%s' % s):
500 self.lit_config.note(
501 'inferred language dialect as: %s' % std)
504 self.lit_config.fatal(
505 'Failed to infer a supported language dialect from one of %r'
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)
518 self.cxx.flags += ['-m32']
519 # Use verbose output for better errors
520 self.cxx.flags += ['-v']
521 sysroot = self.get_lit_conf('sysroot')
523 self.cxx.flags += ['--sysroot', sysroot]
524 gcc_toolchain = self.get_lit_conf('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
531 if self.is_windows and self.debug_build:
532 self.cxx.compile_flags += ['-D_DEBUG']
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]
543 # Disable availability unless explicitely requested
544 if not self.with_availability:
545 self.cxx.flags += ['-D_LIBCPP_DISABLE_AVAILABILITY']
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 \
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')]
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')
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')
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."
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',
580 if os.path.isdir(cxxabi_headers):
581 self.cxx.compile_flags += ['-I' + cxxabi_headers]
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:
588 config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
589 if not os.path.isfile(config_site_header):
591 contained_macros = self.parse_config_site_and_add_features(
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]
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.
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())
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':
624 if m == '_LIBCPP_ABI_VERSION':
625 self.config.available_features.add('libcpp-abi-version-v%s'
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
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']
641 def configure_compile_flags_rtti(self):
642 enable_rtti = self.get_lit_bool('enable_rtti', True)
644 self.config.available_features.add('libcpp-no-rtti')
645 self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
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]
655 self.config.available_features.add('libcpp-abi-unstable')
656 self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
658 def configure_filesystem_compile_flags(self):
659 enable_fs = self.get_lit_bool('enable_filesystem', default=False)
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]
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)
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)
685 self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="%s %s"'
686 % (sys.executable, dynamic_helper)]
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()
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.
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',
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.
715 elif self.cxx_stdlib_under_test == 'cxx_default':
716 self.cxx.link_flags += ['-pthread']
718 self.lit_config.fatal(
719 'unsupported value for "use_stdlib_type": %s'
722 link_flags_str = self.get_lit_conf('link_flags', '')
723 self.cxx.link_flags += shlex.split(link_flags_str)
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)
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]
753 self.add_path(self.exec_env, self.abi_library_root)
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']
761 self.cxx.link_flags += ['-lc++']
763 cxx_library_root = self.get_lit_conf('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]
771 self.cxx.link_flags += ['-lc++']
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)
783 self.cxx.link_flags += ['-lc++abi']
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]
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':
800 debug_suffix = 'd' if self.debug_build else ''
801 self.cxx.link_flags += ['-lmsvcrt%s' % debug_suffix]
803 self.lit_config.fatal(
804 'C++ ABI setting %s unsupported for tests' % cxx_abi)
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)
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:
818 self.lit_config.fatal('Invalid value for color_diagnostics "%s".'
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 '
828 self.cxx.flags += [color_flag]
830 def configure_debug_mode(self):
831 debug_level = self.get_lit_conf('debug_level', None)
834 if debug_level not in ['0', '1']:
835 self.lit_config.fatal('Invalid value for debug_level "%s".'
837 self.cxx.compile_flags += ['-D_LIBCPP_DEBUG=%s' % debug_level]
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'
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')
877 def configure_sanitizer(self):
878 san = self.get_lit_conf('use_sanitizer', '').strip()
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)
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')
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':
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':
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')
931 self.lit_config.fatal('unsupported value for '
932 'use_sanitizer: {0}'.format(san))
933 san_lib = self.get_lit_conf('sanitizer_library')
935 self.cxx.link_flags += [
936 san_lib, '-Wl,-rpath,%s' % os.path.dirname(san_lib)]
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']
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',
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:
957 self.config.available_features.add('modules-support')
958 module_cache = os.path.join(self.config.test_exec_root,
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]
967 self.config.available_features.add('-fmodules')
968 self.cxx.useModules()
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 + ' '
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.
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))
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":
1026 if not self.target_info.is_host_macosx():
1028 if not self.cxx.type.endswith('clang'):
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')
1039 # Use deployment if possible.
1040 self.use_deployment = not self.use_target and self.can_use_deployment()
1041 if self.use_deployment:
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')
1050 # If no target triple was given, try to infer it from the compiler
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)
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')
1082 assert not self.use_target
1083 assert self.target_info.is_host_macosx()
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')
1091 arch = self.cxx.getTriple().split('-', 1)[0]
1092 self.lit_config.note("inferred arch as: %r" % arch)
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)
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)
1104 def configure_env(self):
1105 self.target_info.configure_env(self.exec_env)
1107 def add_path(self, dest_env, new_path):
1108 if 'PATH' not in dest_env:
1109 dest_env['PATH'] = new_path
1111 split_char = ';' if self.is_windows else ':'
1112 dest_env['PATH'] = '%s%s%s' % (new_path, split_char,