aboutsummaryrefslogtreecommitdiff
path: root/test/libcxx/test/config.py
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-09-06 18:46:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-09-06 18:46:46 +0000
commit61b9a7258a7693d7f3674a5a1daf7b036ff1d382 (patch)
treeec41ed70ffca97240e76f9a78bb2dedba28f310c /test/libcxx/test/config.py
parentf857581820d15e410e9945d2fcd5f7163be25a96 (diff)
downloadsrc-61b9a7258a7693d7f3674a5a1daf7b036ff1d382.tar.gz
src-61b9a7258a7693d7f3674a5a1daf7b036ff1d382.zip
Import libc++ 3.7.0 release (r246257).vendor/libc++/libc++-release_370-r246257
Notes
Notes: svn path=/vendor/libc++/dist/; revision=287518 svn path=/vendor/libc++/libc++-release_370-r246257/; revision=287519; tag=vendor/libc++/libc++-release_370-r246257
Diffstat (limited to 'test/libcxx/test/config.py')
-rw-r--r--test/libcxx/test/config.py709
1 files changed, 709 insertions, 0 deletions
diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py
new file mode 100644
index 000000000000..09fbf66dbba0
--- /dev/null
+++ b/test/libcxx/test/config.py
@@ -0,0 +1,709 @@
+import importlib
+import locale
+import os
+import platform
+import pkgutil
+import re
+import shlex
+import sys
+
+import lit.Test # pylint: disable=import-error,no-name-in-module
+import lit.util # pylint: disable=import-error,no-name-in-module
+
+from libcxx.test.format import LibcxxTestFormat
+from libcxx.compiler import CXXCompiler
+from libcxx.test.executor import *
+from libcxx.test.tracing import *
+
+def loadSiteConfig(lit_config, config, param_name, env_name):
+ # We haven't loaded the site specific configuration (the user is
+ # probably trying to run on a test file directly, and either the site
+ # configuration hasn't been created by the build system, or we are in an
+ # out-of-tree build situation).
+ site_cfg = lit_config.params.get(param_name,
+ os.environ.get(env_name))
+ if not site_cfg:
+ lit_config.warning('No site specific configuration file found!'
+ ' Running the tests in the default configuration.')
+ elif not os.path.isfile(site_cfg):
+ lit_config.fatal(
+ "Specified site configuration file does not exist: '%s'" %
+ site_cfg)
+ else:
+ lit_config.note('using site specific configuration at %s' % site_cfg)
+ ld_fn = lit_config.load_config
+
+ # Null out the load_config function so that lit.site.cfg doesn't
+ # recursively load a config even if it tries.
+ # TODO: This is one hell of a hack. Fix it.
+ def prevent_reload_fn(*args, **kwargs):
+ pass
+ lit_config.load_config = prevent_reload_fn
+ ld_fn(config, site_cfg)
+ lit_config.load_config = ld_fn
+
+
+class Configuration(object):
+ # pylint: disable=redefined-outer-name
+ def __init__(self, lit_config, config):
+ self.lit_config = lit_config
+ self.config = config
+ self.cxx = None
+ self.libcxx_src_root = None
+ self.libcxx_obj_root = None
+ self.cxx_library_root = None
+ self.abi_library_root = None
+ self.env = {}
+ self.use_target = False
+ self.use_system_cxx_lib = False
+ self.use_clang_verify = False
+ self.long_tests = None
+ self.execute_external = False
+
+ def get_lit_conf(self, name, default=None):
+ val = self.lit_config.params.get(name, None)
+ if val is None:
+ val = getattr(self.config, name, None)
+ if val is None:
+ val = default
+ return val
+
+ def get_lit_bool(self, name, default=None):
+ conf = self.get_lit_conf(name)
+ if conf is None:
+ return default
+ if conf.lower() in ('1', 'true'):
+ return True
+ if conf.lower() in ('', '0', 'false'):
+ return False
+ self.lit_config.fatal(
+ "parameter '{}' should be true or false".format(name))
+
+ def configure(self):
+ self.configure_executor()
+ self.configure_target_info()
+ self.configure_cxx()
+ self.configure_triple()
+ self.configure_src_root()
+ self.configure_obj_root()
+ self.configure_cxx_library_root()
+ self.configure_use_system_cxx_lib()
+ self.configure_use_clang_verify()
+ self.configure_execute_external()
+ self.configure_ccache()
+ self.configure_compile_flags()
+ self.configure_link_flags()
+ self.configure_env()
+ self.configure_color_diagnostics()
+ self.configure_debug_mode()
+ self.configure_warnings()
+ self.configure_sanitizer()
+ self.configure_coverage()
+ self.configure_substitutions()
+ self.configure_features()
+
+ def print_config_info(self):
+ # Print the final compile and link flags.
+ self.lit_config.note('Using compiler: %s' % self.cxx.path)
+ self.lit_config.note('Using flags: %s' % self.cxx.flags)
+ self.lit_config.note('Using compile flags: %s'
+ % self.cxx.compile_flags)
+ self.lit_config.note('Using link flags: %s' % self.cxx.link_flags)
+ # Print as list to prevent "set([...])" from being printed.
+ self.lit_config.note('Using available_features: %s' %
+ list(self.config.available_features))
+ self.lit_config.note('Using environment: %r' % self.env)
+
+ def get_test_format(self):
+ return LibcxxTestFormat(
+ self.cxx,
+ self.use_clang_verify,
+ self.execute_external,
+ self.executor,
+ exec_env=self.env)
+
+ def configure_executor(self):
+ exec_str = self.get_lit_conf('executor', "None")
+ te = eval(exec_str)
+ if te:
+ self.lit_config.note("Using executor: %r" % exec_str)
+ if self.lit_config.useValgrind:
+ # We have no way of knowing where in the chain the
+ # ValgrindExecutor is supposed to go. It is likely
+ # that the user wants it at the end, but we have no
+ # way of getting at that easily.
+ selt.lit_config.fatal("Cannot infer how to create a Valgrind "
+ " executor.")
+ else:
+ te = LocalExecutor()
+ if self.lit_config.useValgrind:
+ te = ValgrindExecutor(self.lit_config.valgrindArgs, te)
+ self.executor = te
+
+ def configure_target_info(self):
+ default = "libcxx.test.target_info.LocalTI"
+ info_str = self.get_lit_conf('target_info', default)
+ mod_path, _, info = info_str.rpartition('.')
+ mod = importlib.import_module(mod_path)
+ self.target_info = getattr(mod, info)()
+ if info_str != default:
+ self.lit_config.note("inferred target_info as: %r" % info_str)
+
+ def configure_cxx(self):
+ # Gather various compiler parameters.
+ cxx = self.get_lit_conf('cxx_under_test')
+
+ # If no specific cxx_under_test was given, attempt to infer it as
+ # clang++.
+ if cxx is None:
+ clangxx = lit.util.which('clang++',
+ self.config.environment['PATH'])
+ if clangxx:
+ cxx = clangxx
+ self.lit_config.note(
+ "inferred cxx_under_test as: %r" % cxx)
+ if not cxx:
+ self.lit_config.fatal('must specify user parameter cxx_under_test '
+ '(e.g., --param=cxx_under_test=clang++)')
+ self.cxx = CXXCompiler(cxx)
+ cxx_type = self.cxx.type
+ if cxx_type is not None:
+ assert self.cxx.version is not None
+ maj_v, min_v, _ = self.cxx.version
+ self.config.available_features.add(cxx_type)
+ self.config.available_features.add('%s-%s.%s' % (
+ cxx_type, maj_v, min_v))
+
+ def configure_src_root(self):
+ self.libcxx_src_root = self.get_lit_conf(
+ 'libcxx_src_root', os.path.dirname(self.config.test_source_root))
+
+ def configure_obj_root(self):
+ self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
+
+ def configure_cxx_library_root(self):
+ self.cxx_library_root = self.get_lit_conf('cxx_library_root',
+ self.libcxx_obj_root)
+
+ def configure_use_system_cxx_lib(self):
+ # This test suite supports testing against either the system library or
+ # the locally built one; the former mode is useful for testing ABI
+ # compatibility between the current headers and a shipping dynamic
+ # library.
+ self.use_system_cxx_lib = self.get_lit_bool('use_system_cxx_lib')
+ if self.use_system_cxx_lib is None:
+ # Default to testing against the locally built libc++ library.
+ self.use_system_cxx_lib = False
+ self.lit_config.note(
+ "inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
+
+ def configure_use_clang_verify(self):
+ '''If set, run clang with -verify on failing tests.'''
+ self.use_clang_verify = self.get_lit_bool('use_clang_verify')
+ if self.use_clang_verify is None:
+ # NOTE: We do not test for the -verify flag directly because
+ # -verify will always exit with non-zero on an empty file.
+ self.use_clang_verify = self.cxx.hasCompileFlag(
+ ['-Xclang', '-verify-ignore-unexpected'])
+ self.lit_config.note(
+ "inferred use_clang_verify as: %r" % self.use_clang_verify)
+
+ def configure_execute_external(self):
+ # Choose between lit's internal shell pipeline runner and a real shell.
+ # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
+ # default value. Otherwise we default to internal on Windows and
+ # external elsewhere, as bash on Windows is usually very slow.
+ use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
+ if use_lit_shell_default is not None:
+ use_lit_shell_default = use_lit_shell_default != '0'
+ else:
+ use_lit_shell_default = sys.platform == 'win32'
+ # Check for the command line parameter using the default value if it is
+ # not present.
+ use_lit_shell = self.get_lit_bool('use_lit_shell',
+ use_lit_shell_default)
+ self.execute_external = not use_lit_shell
+
+ def configure_ccache(self):
+ use_ccache_default = os.environ.get('LIBCXX_USE_CCACHE') is not None
+ use_ccache = self.get_lit_bool('use_ccache', use_ccache_default)
+ if use_ccache:
+ self.cxx.use_ccache = True
+ self.lit_config.note('enabling ccache')
+
+ def configure_features(self):
+ additional_features = self.get_lit_conf('additional_features')
+ if additional_features:
+ for f in additional_features.split(','):
+ self.config.available_features.add(f.strip())
+
+ # Figure out which of the required locales we support
+ locales = {
+ 'Darwin': {
+ 'en_US.UTF-8': 'en_US.UTF-8',
+ 'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
+ 'fr_FR.UTF-8': 'fr_FR.UTF-8',
+ 'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
+ 'ru_RU.UTF-8': 'ru_RU.UTF-8',
+ 'zh_CN.UTF-8': 'zh_CN.UTF-8',
+ },
+ 'FreeBSD': {
+ 'en_US.UTF-8': 'en_US.UTF-8',
+ 'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
+ 'fr_FR.UTF-8': 'fr_FR.UTF-8',
+ 'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
+ 'ru_RU.UTF-8': 'ru_RU.UTF-8',
+ 'zh_CN.UTF-8': 'zh_CN.UTF-8',
+ },
+ 'Linux': {
+ 'en_US.UTF-8': 'en_US.UTF-8',
+ 'cs_CZ.ISO8859-2': 'cs_CZ.ISO-8859-2',
+ 'fr_FR.UTF-8': 'fr_FR.UTF-8',
+ 'fr_CA.ISO8859-1': 'fr_CA.ISO-8859-1',
+ 'ru_RU.UTF-8': 'ru_RU.UTF-8',
+ 'zh_CN.UTF-8': 'zh_CN.UTF-8',
+ },
+ 'Windows': {
+ 'en_US.UTF-8': 'English_United States.1252',
+ 'cs_CZ.ISO8859-2': 'Czech_Czech Republic.1250',
+ 'fr_FR.UTF-8': 'French_France.1252',
+ 'fr_CA.ISO8859-1': 'French_Canada.1252',
+ 'ru_RU.UTF-8': 'Russian_Russia.1251',
+ 'zh_CN.UTF-8': 'Chinese_China.936',
+ },
+ }
+
+ target_system = self.target_info.system()
+ target_platform = self.target_info.platform()
+
+ if target_system in locales:
+ default_locale = locale.setlocale(locale.LC_ALL)
+ for feature, loc in locales[target_system].items():
+ try:
+ locale.setlocale(locale.LC_ALL, loc)
+ self.config.available_features.add(
+ 'locale.{0}'.format(feature))
+ except locale.Error:
+ self.lit_config.warning('The locale {0} is not supported by '
+ 'your platform. Some tests will be '
+ 'unsupported.'.format(loc))
+ locale.setlocale(locale.LC_ALL, default_locale)
+ else:
+ # Warn that the user doesn't get any free XFAILs for locale issues
+ self.lit_config.warning("No locales entry for target_system: %s" %
+ target_system)
+
+ # Write an "available feature" that combines the triple when
+ # use_system_cxx_lib is enabled. This is so that we can easily write
+ # XFAIL markers for tests that are known to fail with versions of
+ # libc++ as were shipped with a particular triple.
+ if self.use_system_cxx_lib:
+ self.config.available_features.add(
+ 'with_system_cxx_lib=%s' % self.config.target_triple)
+
+ # Insert the platform name into the available features as a lower case.
+ self.config.available_features.add(target_platform)
+
+ # Some linux distributions have different locale data than others.
+ # Insert the distributions name and name-version into the available
+ # features to allow tests to XFAIL on them.
+ if target_platform == 'linux':
+ name = self.target_info.platform_name()
+ ver = self.target_info.platform_ver()
+ if name:
+ self.config.available_features.add(name)
+ if name and ver:
+ self.config.available_features.add('%s-%s' % (name, ver))
+
+ # Simulator testing can take a really long time for some of these tests
+ # so add a feature check so we can REQUIRES: long_tests in them
+ self.long_tests = self.get_lit_bool('long_tests')
+ if self.long_tests is None:
+ # Default to running long tests.
+ self.long_tests = True
+ self.lit_config.note(
+ "inferred long_tests as: %r" % self.long_tests)
+
+ if self.long_tests:
+ self.config.available_features.add('long_tests')
+
+ # Run a compile test for the -fsized-deallocation flag. This is needed
+ # in test/std/language.support/support.dynamic/new.delete
+ if self.cxx.hasCompileFlag('-fsized-deallocation'):
+ self.config.available_features.add('fsized-deallocation')
+
+ def configure_compile_flags(self):
+ no_default_flags = self.get_lit_bool('no_default_flags', False)
+ if not no_default_flags:
+ self.configure_default_compile_flags()
+ # Configure extra flags
+ compile_flags_str = self.get_lit_conf('compile_flags', '')
+ self.cxx.compile_flags += shlex.split(compile_flags_str)
+
+ def configure_default_compile_flags(self):
+ # Try and get the std version from the command line. Fall back to
+ # default given in lit.site.cfg is not present. If default is not
+ # present then force c++11.
+ std = self.get_lit_conf('std', 'c++11')
+ self.cxx.compile_flags += ['-std={0}'.format(std)]
+ self.config.available_features.add(std)
+ # Configure include paths
+ self.cxx.compile_flags += ['-nostdinc++']
+ self.configure_compile_flags_header_includes()
+ if self.target_info.platform() == 'linux':
+ self.cxx.compile_flags += ['-D__STDC_FORMAT_MACROS',
+ '-D__STDC_LIMIT_MACROS',
+ '-D__STDC_CONSTANT_MACROS']
+ # Configure feature flags.
+ self.configure_compile_flags_exceptions()
+ self.configure_compile_flags_rtti()
+ self.configure_compile_flags_no_global_filesystem_namespace()
+ self.configure_compile_flags_no_stdin()
+ self.configure_compile_flags_no_stdout()
+ enable_32bit = self.get_lit_bool('enable_32bit', False)
+ if enable_32bit:
+ self.cxx.flags += ['-m32']
+ # Configure threading features.
+ enable_threads = self.get_lit_bool('enable_threads', True)
+ enable_monotonic_clock = self.get_lit_bool('enable_monotonic_clock',
+ True)
+ if not enable_threads:
+ self.configure_compile_flags_no_threads()
+ if not enable_monotonic_clock:
+ self.configure_compile_flags_no_monotonic_clock()
+ elif not enable_monotonic_clock:
+ self.lit_config.fatal('enable_monotonic_clock cannot be false when'
+ ' enable_threads is true.')
+ self.configure_compile_flags_no_thread_unsafe_c_functions()
+
+ # Use verbose output for better errors
+ self.cxx.flags += ['-v']
+ sysroot = self.get_lit_conf('sysroot')
+ if sysroot:
+ self.cxx.flags += ['--sysroot', sysroot]
+ gcc_toolchain = self.get_lit_conf('gcc_toolchain')
+ if gcc_toolchain:
+ self.cxx.flags += ['-gcc-toolchain', gcc_toolchain]
+ if self.use_target:
+ self.cxx.flags += ['-target', self.config.target_triple]
+
+ def configure_compile_flags_header_includes(self):
+ support_path = os.path.join(self.libcxx_src_root, 'test/support')
+ self.cxx.compile_flags += ['-I' + support_path]
+ self.cxx.compile_flags += ['-include', os.path.join(support_path, 'nasty_macros.hpp')]
+ libcxx_headers = self.get_lit_conf(
+ 'libcxx_headers', os.path.join(self.libcxx_src_root, 'include'))
+ if not os.path.isdir(libcxx_headers):
+ self.lit_config.fatal("libcxx_headers='%s' is not a directory."
+ % libcxx_headers)
+ self.cxx.compile_flags += ['-I' + libcxx_headers]
+
+ def configure_compile_flags_exceptions(self):
+ enable_exceptions = self.get_lit_bool('enable_exceptions', True)
+ if not enable_exceptions:
+ self.config.available_features.add('libcpp-no-exceptions')
+ self.cxx.compile_flags += ['-fno-exceptions']
+
+ def configure_compile_flags_rtti(self):
+ enable_rtti = self.get_lit_bool('enable_rtti', True)
+ if not enable_rtti:
+ self.config.available_features.add('libcpp-no-rtti')
+ self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
+
+ def configure_compile_flags_no_global_filesystem_namespace(self):
+ enable_global_filesystem_namespace = self.get_lit_bool(
+ 'enable_global_filesystem_namespace', True)
+ if not enable_global_filesystem_namespace:
+ self.config.available_features.add(
+ 'libcpp-has-no-global-filesystem-namespace')
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE']
+
+ def configure_compile_flags_no_stdin(self):
+ enable_stdin = self.get_lit_bool('enable_stdin', True)
+ if not enable_stdin:
+ self.config.available_features.add('libcpp-has-no-stdin')
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDIN']
+
+ def configure_compile_flags_no_stdout(self):
+ enable_stdout = self.get_lit_bool('enable_stdout', True)
+ if not enable_stdout:
+ self.config.available_features.add('libcpp-has-no-stdout')
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDOUT']
+
+ def configure_compile_flags_no_threads(self):
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
+ self.config.available_features.add('libcpp-has-no-threads')
+
+ def configure_compile_flags_no_thread_unsafe_c_functions(self):
+ enable_thread_unsafe_c_functions = self.get_lit_bool(
+ 'enable_thread_unsafe_c_functions', True)
+ if not enable_thread_unsafe_c_functions:
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS']
+ self.config.available_features.add(
+ 'libcpp-has-no-thread-unsafe-c-functions')
+
+ def configure_compile_flags_no_monotonic_clock(self):
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
+ self.config.available_features.add('libcpp-has-no-monotonic-clock')
+
+ def configure_link_flags(self):
+ no_default_flags = self.get_lit_bool('no_default_flags', False)
+ if not no_default_flags:
+ self.cxx.link_flags += ['-nodefaultlibs']
+
+ # Configure library path
+ self.configure_link_flags_cxx_library_path()
+ self.configure_link_flags_abi_library_path()
+
+ # Configure libraries
+ self.configure_link_flags_cxx_library()
+ self.configure_link_flags_abi_library()
+ self.configure_extra_library_flags()
+
+ link_flags_str = self.get_lit_conf('link_flags', '')
+ self.cxx.link_flags += shlex.split(link_flags_str)
+
+ def configure_link_flags_cxx_library_path(self):
+ libcxx_library = self.get_lit_conf('libcxx_library')
+ # Configure libc++ library paths.
+ if libcxx_library is not None:
+ # Check that the given value for libcxx_library is valid.
+ if not os.path.isfile(libcxx_library):
+ self.lit_config.fatal(
+ "libcxx_library='%s' is not a valid file." %
+ libcxx_library)
+ if self.use_system_cxx_lib:
+ self.lit_config.fatal(
+ "Conflicting options: 'libcxx_library' cannot be used "
+ "with 'use_system_cxx_lib=true'")
+ self.cxx.link_flags += ['-Wl,-rpath,' +
+ os.path.dirname(libcxx_library)]
+ elif not self.use_system_cxx_lib and self.cxx_library_root:
+ self.cxx.link_flags += ['-L' + self.cxx_library_root,
+ '-Wl,-rpath,' + self.cxx_library_root]
+
+ def configure_link_flags_abi_library_path(self):
+ # Configure ABI library paths.
+ self.abi_library_root = self.get_lit_conf('abi_library_path')
+ if self.abi_library_root:
+ self.cxx.link_flags += ['-L' + self.abi_library_root,
+ '-Wl,-rpath,' + self.abi_library_root]
+
+ def configure_link_flags_cxx_library(self):
+ libcxx_library = self.get_lit_conf('libcxx_library')
+ if libcxx_library:
+ self.cxx.link_flags += [libcxx_library]
+ else:
+ self.cxx.link_flags += ['-lc++']
+
+ def configure_link_flags_abi_library(self):
+ cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
+ if cxx_abi == 'libstdc++':
+ self.cxx.link_flags += ['-lstdc++']
+ elif cxx_abi == 'libsupc++':
+ self.cxx.link_flags += ['-lsupc++']
+ elif cxx_abi == 'libcxxabi':
+ # Don't link libc++abi explicitly on OS X because the symbols
+ # should be available in libc++ directly.
+ if self.target_info.platform() != 'darwin':
+ self.cxx.link_flags += ['-lc++abi']
+ elif cxx_abi == 'libcxxrt':
+ self.cxx.link_flags += ['-lcxxrt']
+ elif cxx_abi == 'none':
+ pass
+ else:
+ self.lit_config.fatal(
+ 'C++ ABI setting %s unsupported for tests' % cxx_abi)
+
+ def configure_extra_library_flags(self):
+ enable_threads = self.get_lit_bool('enable_threads', True)
+ llvm_unwinder = self.get_lit_bool('llvm_unwinder', False)
+ target_platform = self.target_info.platform()
+ if target_platform == 'darwin':
+ self.cxx.link_flags += ['-lSystem']
+ elif target_platform == 'linux':
+ if not llvm_unwinder:
+ self.cxx.link_flags += ['-lgcc_eh']
+ self.cxx.link_flags += ['-lc', '-lm']
+ if enable_threads:
+ self.cxx.link_flags += ['-lpthread']
+ self.cxx.link_flags += ['-lrt']
+ if llvm_unwinder:
+ self.cxx.link_flags += ['-lunwind', '-ldl']
+ else:
+ self.cxx.link_flags += ['-lgcc_s']
+ elif target_platform.startswith('freebsd'):
+ self.cxx.link_flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
+ else:
+ self.lit_config.fatal("unrecognized system: %r" % target_platform)
+
+ def configure_color_diagnostics(self):
+ use_color = self.get_lit_conf('color_diagnostics')
+ if use_color is None:
+ use_color = os.environ.get('LIBCXX_COLOR_DIAGNOSTICS')
+ if use_color is None:
+ return
+ if use_color != '':
+ self.lit_config.fatal('Invalid value for color_diagnostics "%s".'
+ % use_color)
+ color_flag = '-fdiagnostics-color=always'
+ # Check if the compiler supports the color diagnostics flag. Issue a
+ # warning if it does not since color diagnostics have been requested.
+ if not self.cxx.hasCompileFlag(color_flag):
+ self.lit_config.warning(
+ 'color diagnostics have been requested but are not supported '
+ 'by the compiler')
+ else:
+ self.cxx.flags += [color_flag]
+
+ def configure_debug_mode(self):
+ debug_level = self.get_lit_conf('debug_level', None)
+ if not debug_level:
+ return
+ if debug_level not in ['0', '1']:
+ self.lit_config.fatal('Invalid value for debug_level "%s".'
+ % debug_level)
+ self.cxx.compile_flags += ['-D_LIBCPP_DEBUG=%s' % debug_level]
+
+ def configure_warnings(self):
+ enable_warnings = self.get_lit_bool('enable_warnings', False)
+ if enable_warnings:
+ self.cxx.compile_flags += ['-Wsystem-headers', '-Wall', '-Werror']
+ if ('clang' in self.config.available_features or
+ 'apple-clang' in self.config.available_features):
+ self.cxx.compile_flags += ['-Wno-user-defined-literals']
+
+ def configure_sanitizer(self):
+ san = self.get_lit_conf('use_sanitizer', '').strip()
+ if san:
+ # Search for llvm-symbolizer along the compiler path first
+ # and then along the PATH env variable.
+ symbolizer_search_paths = os.environ.get('PATH', '')
+ cxx_path = lit.util.which(self.cxx.path)
+ if cxx_path is not None:
+ symbolizer_search_paths = (
+ os.path.dirname(cxx_path) +
+ os.pathsep + symbolizer_search_paths)
+ llvm_symbolizer = lit.util.which('llvm-symbolizer',
+ symbolizer_search_paths)
+ # Setup the sanitizer compile flags
+ self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
+ if self.target_info.platform() == 'linux':
+ self.cxx.link_flags += ['-ldl']
+ if san == 'Address':
+ self.cxx.flags += ['-fsanitize=address']
+ if llvm_symbolizer is not None:
+ self.env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
+ self.config.available_features.add('asan')
+ self.config.available_features.add('sanitizer-new-delete')
+ elif san == 'Memory' or san == 'MemoryWithOrigins':
+ self.cxx.flags += ['-fsanitize=memory']
+ if san == 'MemoryWithOrigins':
+ self.cxx.compile_flags += [
+ '-fsanitize-memory-track-origins']
+ if llvm_symbolizer is not None:
+ self.env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
+ self.config.available_features.add('msan')
+ self.config.available_features.add('sanitizer-new-delete')
+ elif san == 'Undefined':
+ self.cxx.flags += ['-fsanitize=undefined',
+ '-fno-sanitize=vptr,function',
+ '-fno-sanitize-recover']
+ self.cxx.compile_flags += ['-O3']
+ self.config.available_features.add('ubsan')
+ elif san == 'Thread':
+ self.cxx.flags += ['-fsanitize=thread']
+ self.config.available_features.add('tsan')
+ self.config.available_features.add('sanitizer-new-delete')
+ else:
+ self.lit_config.fatal('unsupported value for '
+ 'use_sanitizer: {0}'.format(san))
+
+ def configure_coverage(self):
+ self.generate_coverage = self.get_lit_bool('generate_coverage', False)
+ if self.generate_coverage:
+ self.cxx.flags += ['-g', '--coverage']
+ self.cxx.compile_flags += ['-O0']
+
+ def configure_substitutions(self):
+ sub = self.config.substitutions
+ # Configure compiler substitions
+ sub.append(('%cxx', self.cxx.path))
+ # Configure flags substitutions
+ flags_str = ' '.join(self.cxx.flags)
+ compile_flags_str = ' '.join(self.cxx.compile_flags)
+ link_flags_str = ' '.join(self.cxx.link_flags)
+ all_flags = '%s %s %s' % (flags_str, compile_flags_str, link_flags_str)
+ sub.append(('%flags', flags_str))
+ sub.append(('%compile_flags', compile_flags_str))
+ sub.append(('%link_flags', link_flags_str))
+ sub.append(('%all_flags', all_flags))
+ # Add compile and link shortcuts
+ compile_str = (self.cxx.path + ' -o %t.o %s -c ' + flags_str
+ + compile_flags_str)
+ link_str = (self.cxx.path + ' -o %t.exe %t.o ' + flags_str
+ + link_flags_str)
+ assert type(link_str) is str
+ build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
+ sub.append(('%compile', compile_str))
+ sub.append(('%link', link_str))
+ sub.append(('%build', build_str))
+ # Configure exec prefix substitutions.
+ exec_env_str = 'env ' if len(self.env) != 0 else ''
+ for k, v in self.env.items():
+ exec_env_str += ' %s=%s' % (k, v)
+ # Configure run env substitution.
+ exec_str = ''
+ if self.lit_config.useValgrind:
+ exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
+ sub.append(('%exec', exec_str))
+ # Configure run shortcut
+ sub.append(('%run', exec_str + ' %t.exe'))
+ # Configure not program substitions
+ not_py = os.path.join(self.libcxx_src_root, 'utils', 'not', 'not.py')
+ not_str = '%s %s' % (sys.executable, not_py)
+ sub.append(('not', not_str))
+
+ def configure_triple(self):
+ # Get or infer the target triple.
+ self.config.target_triple = self.get_lit_conf('target_triple')
+ self.use_target = bool(self.config.target_triple)
+ # If no target triple was given, try to infer it from the compiler
+ # under test.
+ if not self.use_target:
+ target_triple = self.cxx.getTriple()
+ # Drop sub-major version components from the triple, because the
+ # current XFAIL handling expects exact matches for feature checks.
+ # Example: x86_64-apple-darwin14.0.0 -> x86_64-apple-darwin14
+ # The 5th group handles triples greater than 3 parts
+ # (ex x86_64-pc-linux-gnu).
+ target_triple = re.sub(r'([^-]+)-([^-]+)-([^.]+)([^-]*)(.*)',
+ r'\1-\2-\3\5', target_triple)
+ # linux-gnu is needed in the triple to properly identify linuxes
+ # that use GLIBC. Handle redhat and opensuse triples as special
+ # cases and append the missing `-gnu` portion.
+ if (target_triple.endswith('redhat-linux') or
+ target_triple.endswith('suse-linux')):
+ target_triple += '-gnu'
+ self.config.target_triple = target_triple
+ self.lit_config.note(
+ "inferred target_triple as: %r" % self.config.target_triple)
+
+ def configure_env(self):
+ if self.target_info.platform() == 'darwin':
+ library_paths = []
+ # Configure the library path for libc++
+ libcxx_library = self.get_lit_conf('libcxx_library')
+ if self.use_system_cxx_lib:
+ pass
+ elif libcxx_library:
+ library_paths += [os.path.dirname(libcxx_library)]
+ elif self.cxx_library_root:
+ library_paths += [self.cxx_library_root]
+ # Configure the abi library path
+ if self.abi_library_root:
+ library_paths += [self.abi_library_root]
+ if library_paths:
+ self.env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)