Skip to content

Commit 90bee63

Browse files
author
Ben Craig
committed
[libcxx] Refactoring target_info.py
This patch makes it easier to support running the lit tests for new and unusual platforms. It will break existing users that set LIBCXX_TARGET_INFO to anything other than the default. I think this is fine, because the old LIBCXX_TARGET_INFO wasn't terribly useful. The old way of supporting the different test platforms was to have conditional code scattered throughout config.py. New platforms would need to add conditionals there. Alternatively, the new platform could set no_default_flags to true, and reconstitue almost the entire compile and link line, including things that don't vary across platforms. The new way of supporting new platforms is to create a new target info class, and have make_target_info return an instance of it. For platforms supported in-tree, that will be done by modifying make_target_info. For out-of-tree platforms, users can set LIBCXX_TARGET_INFO at cmake configure time. The target info sub-classes can provide fine-grained information back to config.py. The hooks that will most commonly be provided will be add_cxx_compile_flags and add_cxx_link_flags. These hooks can provide the platform specific flags, while letting config.py handle all the invariant flags. Target info hooks were added for each area that the existing config.py had platform specific behavior. config.py is now mostly free of platform specific conditionals. This patch was tested on Linux x86_64. I both targeted Linux x86_64, and an out-of-tree platform with a custom target_info. In both cases I was able to run libcxx and libcxxabi tests. I do not have access to FreeBSD, Darwin, or Windows machines that are set up for lit testing. llvm-svn: 256588
1 parent a4a3c18 commit 90bee63

File tree

2 files changed

+173
-182
lines changed

2 files changed

+173
-182
lines changed

libcxx/test/libcxx/test/config.py

Lines changed: 10 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import importlib
21
import locale
32
import os
43
import platform
@@ -12,6 +11,7 @@
1211

1312
from libcxx.test.format import LibcxxTestFormat
1413
from libcxx.compiler import CXXCompiler
14+
from libcxx.test.target_info import make_target_info
1515
from libcxx.test.executor import *
1616
from libcxx.test.tracing import *
1717

@@ -42,22 +42,6 @@ def prevent_reload_fn(*args, **kwargs):
4242
ld_fn(config, site_cfg)
4343
lit_config.load_config = ld_fn
4444

45-
def getSysrootFlagsOnDarwin(config, lit_config):
46-
# On Darwin, support relocatable SDKs by providing Clang with a
47-
# default system root path.
48-
if 'darwin' in config.target_triple:
49-
try:
50-
out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
51-
res = 0
52-
except OSError:
53-
res = -1
54-
if res == 0 and out:
55-
sdk_path = out
56-
lit_config.note('using SDKROOT: %r' % sdk_path)
57-
return ["-isysroot", sdk_path]
58-
return []
59-
60-
6145
class Configuration(object):
6246
# pylint: disable=redefined-outer-name
6347
def __init__(self, lit_config, config):
@@ -157,13 +141,7 @@ def configure_executor(self):
157141
self.executor = te
158142

159143
def configure_target_info(self):
160-
default = "libcxx.test.target_info.LocalTI"
161-
info_str = self.get_lit_conf('target_info', default)
162-
mod_path, _, info = info_str.rpartition('.')
163-
mod = importlib.import_module(mod_path)
164-
self.target_info = getattr(mod, info)()
165-
if info_str != default:
166-
self.lit_config.note("inferred target_info as: %r" % info_str)
144+
self.target_info = make_target_info(self)
167145

168146
def configure_cxx(self):
169147
# Gather various compiler parameters.
@@ -234,13 +212,12 @@ def configure_use_clang_verify(self):
234212
def configure_execute_external(self):
235213
# Choose between lit's internal shell pipeline runner and a real shell.
236214
# If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
237-
# default value. Otherwise we default to internal on Windows and
238-
# external elsewhere, as bash on Windows is usually very slow.
215+
# default value. Otherwise we ask the target_info.
239216
use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
240217
if use_lit_shell_default is not None:
241218
use_lit_shell_default = use_lit_shell_default != '0'
242219
else:
243-
use_lit_shell_default = sys.platform == 'win32'
220+
use_lit_shell_default = self.target_info.use_lit_shell_default()
244221
# Check for the command line parameter using the default value if it is
245222
# not present.
246223
use_lit_shell = self.get_lit_bool('use_lit_shell',
@@ -259,63 +236,10 @@ def configure_features(self):
259236
if additional_features:
260237
for f in additional_features.split(','):
261238
self.config.available_features.add(f.strip())
239+
self.target_info.add_locale_features(self.config.available_features)
262240

263-
# Figure out which of the required locales we support
264-
locales = {
265-
'Darwin': {
266-
'en_US.UTF-8': 'en_US.UTF-8',
267-
'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
268-
'fr_FR.UTF-8': 'fr_FR.UTF-8',
269-
'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
270-
'ru_RU.UTF-8': 'ru_RU.UTF-8',
271-
'zh_CN.UTF-8': 'zh_CN.UTF-8',
272-
},
273-
'FreeBSD': {
274-
'en_US.UTF-8': 'en_US.UTF-8',
275-
'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
276-
'fr_FR.UTF-8': 'fr_FR.UTF-8',
277-
'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
278-
'ru_RU.UTF-8': 'ru_RU.UTF-8',
279-
'zh_CN.UTF-8': 'zh_CN.UTF-8',
280-
},
281-
'Linux': {
282-
'en_US.UTF-8': 'en_US.UTF-8',
283-
'cs_CZ.ISO8859-2': 'cs_CZ.ISO-8859-2',
284-
'fr_FR.UTF-8': 'fr_FR.UTF-8',
285-
'fr_CA.ISO8859-1': 'fr_CA.ISO-8859-1',
286-
'ru_RU.UTF-8': 'ru_RU.UTF-8',
287-
'zh_CN.UTF-8': 'zh_CN.UTF-8',
288-
},
289-
'Windows': {
290-
'en_US.UTF-8': 'English_United States.1252',
291-
'cs_CZ.ISO8859-2': 'Czech_Czech Republic.1250',
292-
'fr_FR.UTF-8': 'French_France.1252',
293-
'fr_CA.ISO8859-1': 'French_Canada.1252',
294-
'ru_RU.UTF-8': 'Russian_Russia.1251',
295-
'zh_CN.UTF-8': 'Chinese_China.936',
296-
},
297-
}
298-
299-
target_system = self.target_info.system()
300241
target_platform = self.target_info.platform()
301242

302-
if target_system in locales:
303-
default_locale = locale.setlocale(locale.LC_ALL)
304-
for feature, loc in locales[target_system].items():
305-
try:
306-
locale.setlocale(locale.LC_ALL, loc)
307-
self.config.available_features.add(
308-
'locale.{0}'.format(feature))
309-
except locale.Error:
310-
self.lit_config.warning('The locale {0} is not supported by '
311-
'your platform. Some tests will be '
312-
'unsupported.'.format(loc))
313-
locale.setlocale(locale.LC_ALL, default_locale)
314-
else:
315-
# Warn that the user doesn't get any free XFAILs for locale issues
316-
self.lit_config.warning("No locales entry for target_system: %s" %
317-
target_system)
318-
319243
# Write an "available feature" that combines the triple when
320244
# use_system_cxx_lib is enabled. This is so that we can easily write
321245
# XFAIL markers for tests that are known to fail with versions of
@@ -327,17 +251,6 @@ def configure_features(self):
327251
# Insert the platform name into the available features as a lower case.
328252
self.config.available_features.add(target_platform)
329253

330-
# Some linux distributions have different locale data than others.
331-
# Insert the distributions name and name-version into the available
332-
# features to allow tests to XFAIL on them.
333-
if target_platform == 'linux':
334-
name = self.target_info.platform_name()
335-
ver = self.target_info.platform_ver()
336-
if name:
337-
self.config.available_features.add(name)
338-
if name and ver:
339-
self.config.available_features.add('%s-%s' % (name, ver))
340-
341254
# Simulator testing can take a really long time for some of these tests
342255
# so add a feature check so we can REQUIRES: long_tests in them
343256
self.long_tests = self.get_lit_bool('long_tests')
@@ -362,8 +275,6 @@ def configure_compile_flags(self):
362275
# Configure extra flags
363276
compile_flags_str = self.get_lit_conf('compile_flags', '')
364277
self.cxx.compile_flags += shlex.split(compile_flags_str)
365-
sysroot_flags = getSysrootFlagsOnDarwin(self.config, self.lit_config)
366-
self.cxx.compile_flags.extend(sysroot_flags)
367278

368279
def configure_default_compile_flags(self):
369280
# Try and get the std version from the command line. Fall back to
@@ -388,10 +299,7 @@ def configure_default_compile_flags(self):
388299
# Configure include paths
389300
self.cxx.compile_flags += ['-nostdinc++']
390301
self.configure_compile_flags_header_includes()
391-
if self.target_info.platform() == 'linux':
392-
self.cxx.compile_flags += ['-D__STDC_FORMAT_MACROS',
393-
'-D__STDC_LIMIT_MACROS',
394-
'-D__STDC_CONSTANT_MACROS']
302+
self.target_info.add_cxx_compile_flags(self.cxx.compile_flags)
395303
# Configure feature flags.
396304
self.configure_compile_flags_exceptions()
397305
self.configure_compile_flags_rtti()
@@ -552,9 +460,7 @@ def configure_link_flags_abi_library(self):
552460
elif cxx_abi == 'libsupc++':
553461
self.cxx.link_flags += ['-lsupc++']
554462
elif cxx_abi == 'libcxxabi':
555-
# Don't link libc++abi explicitly on OS X because the symbols
556-
# should be available in libc++ directly.
557-
if self.target_info.platform() != 'darwin':
463+
if self.target_info.allow_cxxabi_link():
558464
self.cxx.link_flags += ['-lc++abi']
559465
elif cxx_abi == 'libcxxrt':
560466
self.cxx.link_flags += ['-lcxxrt']
@@ -565,27 +471,7 @@ def configure_link_flags_abi_library(self):
565471
'C++ ABI setting %s unsupported for tests' % cxx_abi)
566472

567473
def configure_extra_library_flags(self):
568-
enable_threads = ('libcpp-has-no-threads' not in
569-
self.config.available_features)
570-
llvm_unwinder = self.get_lit_bool('llvm_unwinder', False)
571-
target_platform = self.target_info.platform()
572-
if target_platform == 'darwin':
573-
self.cxx.link_flags += ['-lSystem']
574-
elif target_platform == 'linux':
575-
self.cxx.link_flags += ['-lm']
576-
if not llvm_unwinder:
577-
self.cxx.link_flags += ['-lgcc_s', '-lgcc']
578-
if enable_threads:
579-
self.cxx.link_flags += ['-lpthread']
580-
self.cxx.link_flags += ['-lc']
581-
if llvm_unwinder:
582-
self.cxx.link_flags += ['-lunwind', '-ldl']
583-
else:
584-
self.cxx.link_flags += ['-lgcc_s', '-lgcc']
585-
elif target_platform.startswith('freebsd'):
586-
self.cxx.link_flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
587-
else:
588-
self.lit_config.fatal("unrecognized system: %r" % target_platform)
474+
self.target_info.add_cxx_link_flags(self.cxx.link_flags)
589475

590476
def configure_color_diagnostics(self):
591477
use_color = self.get_lit_conf('color_diagnostics')
@@ -639,6 +525,7 @@ def configure_warnings(self):
639525
def configure_sanitizer(self):
640526
san = self.get_lit_conf('use_sanitizer', '').strip()
641527
if san:
528+
self.target_info.add_sanitizer_features(san, self.config.available_features)
642529
# Search for llvm-symbolizer along the compiler path first
643530
# and then along the PATH env variable.
644531
symbolizer_search_paths = os.environ.get('PATH', '')
@@ -651,11 +538,6 @@ def configure_sanitizer(self):
651538
symbolizer_search_paths)
652539
# Setup the sanitizer compile flags
653540
self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
654-
if self.target_info.platform() == 'linux':
655-
# The libraries and their order are taken from the
656-
# linkSanitizerRuntimeDeps function in
657-
# clang/lib/Driver/Tools.cpp
658-
self.cxx.link_flags += ['-lpthread', '-lrt', '-lm', '-ldl']
659541
if san == 'Address':
660542
self.cxx.flags += ['-fsanitize=address']
661543
if llvm_symbolizer is not None:
@@ -677,8 +559,6 @@ def configure_sanitizer(self):
677559
'-fno-sanitize-recover']
678560
self.cxx.compile_flags += ['-O3']
679561
self.config.available_features.add('ubsan')
680-
if self.target_info.platform() == 'darwin':
681-
self.config.available_features.add('sanitizer-new-delete')
682562
elif san == 'Thread':
683563
self.cxx.flags += ['-fsanitize=thread']
684564
self.config.available_features.add('tsan')
@@ -762,18 +642,4 @@ def configure_triple(self):
762642
"inferred target_triple as: %r" % self.config.target_triple)
763643

764644
def configure_env(self):
765-
if self.target_info.platform() == 'darwin':
766-
library_paths = []
767-
# Configure the library path for libc++
768-
libcxx_library = self.get_lit_conf('libcxx_library')
769-
if self.use_system_cxx_lib:
770-
pass
771-
elif libcxx_library:
772-
library_paths += [os.path.dirname(libcxx_library)]
773-
elif self.cxx_library_root:
774-
library_paths += [self.cxx_library_root]
775-
# Configure the abi library path
776-
if self.abi_library_root:
777-
library_paths += [self.abi_library_root]
778-
if library_paths:
779-
self.env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
645+
self.target_info.configure_env(self.env)

0 commit comments

Comments
 (0)