Get test-suite configuring on Windows with clang-cl
This patch gets the test suite "working" on Windows, although none of the tests pass. In order to reuse the existing configuration, which uses UNIX style flags not accepted by clang-cl, this patch only works with clang++. When clang-cl is specified the test harness secretly looks for clang++ and then it configures it using the INCLUDE and LIB enviroment variables. This is very much a work in progress. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@291072 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -57,7 +57,9 @@ class Configuration(object):
|
|||||||
def __init__(self, lit_config, config):
|
def __init__(self, lit_config, config):
|
||||||
self.lit_config = lit_config
|
self.lit_config = lit_config
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.is_windows = platform.system() == 'Windows'
|
||||||
self.cxx = None
|
self.cxx = None
|
||||||
|
self.cxx_is_clang_cl = None
|
||||||
self.cxx_stdlib_under_test = None
|
self.cxx_stdlib_under_test = None
|
||||||
self.project_obj_root = None
|
self.project_obj_root = None
|
||||||
self.libcxx_src_root = None
|
self.libcxx_src_root = None
|
||||||
@@ -95,6 +97,13 @@ class Configuration(object):
|
|||||||
self.lit_config.fatal(
|
self.lit_config.fatal(
|
||||||
"parameter '{}' should be true or false".format(name))
|
"parameter '{}' should be true or false".format(name))
|
||||||
|
|
||||||
|
def make_static_lib_name(self, name):
|
||||||
|
"""Return the full filename for the specified library name"""
|
||||||
|
if self.is_windows:
|
||||||
|
return name + '.lib'
|
||||||
|
else:
|
||||||
|
return 'lib' + name + '.a'
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
self.configure_executor()
|
self.configure_executor()
|
||||||
self.configure_target_info()
|
self.configure_target_info()
|
||||||
@@ -171,20 +180,25 @@ class Configuration(object):
|
|||||||
def configure_cxx(self):
|
def configure_cxx(self):
|
||||||
# Gather various compiler parameters.
|
# Gather various compiler parameters.
|
||||||
cxx = self.get_lit_conf('cxx_under_test')
|
cxx = self.get_lit_conf('cxx_under_test')
|
||||||
|
self.cxx_is_clang_cl = cxx is not None and \
|
||||||
|
os.path.basename(cxx) == 'clang-cl.exe'
|
||||||
# If no specific cxx_under_test was given, attempt to infer it as
|
# If no specific cxx_under_test was given, attempt to infer it as
|
||||||
# clang++.
|
# clang++.
|
||||||
if cxx is None:
|
if cxx is None or self.cxx_is_clang_cl:
|
||||||
clangxx = lit.util.which('clang++',
|
clangxx = lit.util.which('clang++',
|
||||||
self.config.environment['PATH'])
|
self.config.environment['PATH'])
|
||||||
if clangxx:
|
if clangxx:
|
||||||
cxx = clangxx
|
cxx = clangxx
|
||||||
self.lit_config.note(
|
self.lit_config.note(
|
||||||
"inferred cxx_under_test as: %r" % cxx)
|
"inferred cxx_under_test as: %r" % cxx)
|
||||||
|
elif self.cxx_is_clang_cl:
|
||||||
|
self.lit_config.fatal('Failed to find clang++ substitution for'
|
||||||
|
' clang-cl')
|
||||||
if not cxx:
|
if not cxx:
|
||||||
self.lit_config.fatal('must specify user parameter cxx_under_test '
|
self.lit_config.fatal('must specify user parameter cxx_under_test '
|
||||||
'(e.g., --param=cxx_under_test=clang++)')
|
'(e.g., --param=cxx_under_test=clang++)')
|
||||||
self.cxx = CXXCompiler(cxx)
|
self.cxx = CXXCompiler(cxx) if not self.cxx_is_clang_cl else \
|
||||||
|
self._configure_clang_cl(cxx)
|
||||||
cxx_type = self.cxx.type
|
cxx_type = self.cxx.type
|
||||||
if cxx_type is not None:
|
if cxx_type is not None:
|
||||||
assert self.cxx.version is not None
|
assert self.cxx.version is not None
|
||||||
@@ -194,6 +208,25 @@ class Configuration(object):
|
|||||||
self.config.available_features.add('%s-%s.%s' % (
|
self.config.available_features.add('%s-%s.%s' % (
|
||||||
cxx_type, maj_v, min_v))
|
cxx_type, maj_v, min_v))
|
||||||
|
|
||||||
|
def _configure_clang_cl(self, clang_path):
|
||||||
|
assert self.cxx_is_clang_cl
|
||||||
|
# FIXME: don't hardcode the target
|
||||||
|
flags = ['-fms-compatibility-version=19.00',
|
||||||
|
'--target=i686-unknown-windows']
|
||||||
|
compile_flags = []
|
||||||
|
link_flags = ['-fuse-ld=lld']
|
||||||
|
if 'INCLUDE' in os.environ:
|
||||||
|
compile_flags += ['-isystem %s' % p.strip()
|
||||||
|
for p in os.environ['INCLUDE'].split(';')
|
||||||
|
if p.strip()]
|
||||||
|
if 'LIB' in os.environ:
|
||||||
|
link_flags += ['-L%s' % p.strip()
|
||||||
|
for p in os.environ['LIB'].split(';') if p.strip()]
|
||||||
|
return CXXCompiler(clang_path, flags=flags,
|
||||||
|
compile_flags=compile_flags,
|
||||||
|
link_flags=link_flags)
|
||||||
|
|
||||||
|
|
||||||
def configure_src_root(self):
|
def configure_src_root(self):
|
||||||
self.libcxx_src_root = self.get_lit_conf(
|
self.libcxx_src_root = self.get_lit_conf(
|
||||||
'libcxx_src_root', os.path.dirname(self.config.test_source_root))
|
'libcxx_src_root', os.path.dirname(self.config.test_source_root))
|
||||||
@@ -400,7 +433,8 @@ class Configuration(object):
|
|||||||
|
|
||||||
def configure_compile_flags_header_includes(self):
|
def configure_compile_flags_header_includes(self):
|
||||||
support_path = os.path.join(self.libcxx_src_root, 'test/support')
|
support_path = os.path.join(self.libcxx_src_root, 'test/support')
|
||||||
if self.cxx_stdlib_under_test != 'libstdc++':
|
if self.cxx_stdlib_under_test != 'libstdc++' and \
|
||||||
|
not self.is_windows:
|
||||||
self.cxx.compile_flags += [
|
self.cxx.compile_flags += [
|
||||||
'-include', os.path.join(support_path, 'nasty_macros.hpp')]
|
'-include', os.path.join(support_path, 'nasty_macros.hpp')]
|
||||||
self.configure_config_site_header()
|
self.configure_config_site_header()
|
||||||
@@ -459,6 +493,8 @@ class Configuration(object):
|
|||||||
# Transform each macro name into the feature name used in the tests.
|
# Transform each macro name into the feature name used in the tests.
|
||||||
# Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
|
# Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
|
||||||
for m in feature_macros:
|
for m in feature_macros:
|
||||||
|
if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS':
|
||||||
|
continue
|
||||||
if m == '_LIBCPP_ABI_VERSION':
|
if m == '_LIBCPP_ABI_VERSION':
|
||||||
self.config.available_features.add('libcpp-abi-version-v%s'
|
self.config.available_features.add('libcpp-abi-version-v%s'
|
||||||
% feature_macros[m])
|
% feature_macros[m])
|
||||||
@@ -558,15 +594,16 @@ class Configuration(object):
|
|||||||
if not self.use_system_cxx_lib:
|
if not self.use_system_cxx_lib:
|
||||||
if self.cxx_library_root:
|
if self.cxx_library_root:
|
||||||
self.cxx.link_flags += ['-L' + self.cxx_library_root]
|
self.cxx.link_flags += ['-L' + self.cxx_library_root]
|
||||||
if self.cxx_runtime_root:
|
if self.cxx_runtime_root and not self.is_windows:
|
||||||
self.cxx.link_flags += ['-Wl,-rpath,' + self.cxx_runtime_root]
|
self.cxx.link_flags += ['-Wl,-rpath,' + self.cxx_runtime_root]
|
||||||
|
|
||||||
def configure_link_flags_abi_library_path(self):
|
def configure_link_flags_abi_library_path(self):
|
||||||
# Configure ABI library paths.
|
# Configure ABI library paths.
|
||||||
self.abi_library_root = self.get_lit_conf('abi_library_path')
|
self.abi_library_root = self.get_lit_conf('abi_library_path')
|
||||||
if self.abi_library_root:
|
if self.abi_library_root:
|
||||||
self.cxx.link_flags += ['-L' + self.abi_library_root,
|
self.cxx.link_flags += ['-L' + self.abi_library_root]
|
||||||
'-Wl,-rpath,' + self.abi_library_root]
|
if not self.is_windows:
|
||||||
|
self.cxx.link_flags += ['-Wl,-rpath,' + self.abi_library_root]
|
||||||
|
|
||||||
def configure_link_flags_cxx_library(self):
|
def configure_link_flags_cxx_library(self):
|
||||||
libcxx_experimental = self.get_lit_bool('enable_experimental', default=False)
|
libcxx_experimental = self.get_lit_bool('enable_experimental', default=False)
|
||||||
@@ -579,7 +616,10 @@ class Configuration(object):
|
|||||||
else:
|
else:
|
||||||
cxx_library_root = self.get_lit_conf('cxx_library_root')
|
cxx_library_root = self.get_lit_conf('cxx_library_root')
|
||||||
if cxx_library_root:
|
if cxx_library_root:
|
||||||
abs_path = os.path.join(cxx_library_root, 'libc++.a')
|
libname = self.make_static_lib_name('c++')
|
||||||
|
abs_path = os.path.join(cxx_library_root, libname)
|
||||||
|
assert os.path.exists(abs_path) and \
|
||||||
|
"static libc++ library does not exist"
|
||||||
self.cxx.link_flags += [abs_path]
|
self.cxx.link_flags += [abs_path]
|
||||||
else:
|
else:
|
||||||
self.cxx.link_flags += ['-lc++']
|
self.cxx.link_flags += ['-lc++']
|
||||||
@@ -598,7 +638,8 @@ class Configuration(object):
|
|||||||
else:
|
else:
|
||||||
cxxabi_library_root = self.get_lit_conf('abi_library_path')
|
cxxabi_library_root = self.get_lit_conf('abi_library_path')
|
||||||
if cxxabi_library_root:
|
if cxxabi_library_root:
|
||||||
abs_path = os.path.join(cxxabi_library_root, 'libc++abi.a')
|
libname = self.make_static_lib_name('c++abi')
|
||||||
|
abs_path = os.path.join(cxxabi_library_root, libname)
|
||||||
self.cxx.link_flags += [abs_path]
|
self.cxx.link_flags += [abs_path]
|
||||||
else:
|
else:
|
||||||
self.cxx.link_flags += ['-lc++abi']
|
self.cxx.link_flags += ['-lc++abi']
|
||||||
|
|||||||
Reference in New Issue
Block a user