mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-04 09:54:09 +00:00
[lit] Add a lit.llvm module that all test suites can use.
To further reduce duplicate code, this patch introduces a module that configs can simply import and get access to a lot of useful functionality such as setting up paths, adding features that are useful across all projects, and other utility-type functions. For now this only updates llvm's suite to use this new library, but subsequent patches will update other projects. Differential Revision: https://reviews.llvm.org/D37778 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313325 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
154124adc3
commit
d5831d289e
@ -1173,6 +1173,10 @@ function(configure_lit_site_cfg input output)
|
||||
set(TARGET_TRIPLE "\"+config.target_triple+\"")
|
||||
endif()
|
||||
|
||||
string(CONCAT LIT_SITE_CFG_IN_FOOTER
|
||||
"import lit.llvm\n"
|
||||
"lit.llvm.initialize(lit_config, config)\n")
|
||||
|
||||
configure_file(${input} ${output} @ONLY)
|
||||
get_filename_component(INPUT_DIR ${input} DIRECTORY)
|
||||
if (EXISTS "${INPUT_DIR}/lit.cfg")
|
||||
|
171
test/lit.cfg
171
test/lit.cfg
@ -10,35 +10,13 @@ import subprocess
|
||||
|
||||
import lit.util
|
||||
import lit.formats
|
||||
from lit.llvm import llvm_config
|
||||
|
||||
# name: The name of this test suite.
|
||||
config.name = 'LLVM'
|
||||
|
||||
# Tweak PATH for Win32 to decide to use bash.exe or not.
|
||||
if sys.platform in ['win32']:
|
||||
# Seek sane tools in directories and set to $PATH.
|
||||
path = getattr(config, 'lit_tools_dir', None)
|
||||
path = lit_config.getToolsPath(path,
|
||||
config.environment['PATH'],
|
||||
['cmp.exe', 'grep.exe', 'sed.exe'])
|
||||
if path is not None:
|
||||
path = os.path.pathsep.join((path,
|
||||
config.environment['PATH']))
|
||||
config.environment['PATH'] = path
|
||||
|
||||
# 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 an override.
|
||||
use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
|
||||
if use_lit_shell:
|
||||
# 0 is external, "" is default, and everything else is internal.
|
||||
execute_external = (use_lit_shell == "0")
|
||||
else:
|
||||
# Otherwise we default to internal on Windows and external elsewhere, as
|
||||
# bash on Windows is usually very slow.
|
||||
execute_external = (not sys.platform in ['win32'])
|
||||
|
||||
# testFormat: The test format to use to interpret tests.
|
||||
config.test_format = lit.formats.ShTest(execute_external)
|
||||
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
|
||||
|
||||
# suffixes: A list of file extensions to treat as test files. This is overriden
|
||||
# by individual lit.local.cfg files in the test subdirectories.
|
||||
@ -56,57 +34,27 @@ config.test_source_root = os.path.dirname(__file__)
|
||||
config.test_exec_root = os.path.join(config.llvm_obj_root, 'test')
|
||||
|
||||
# Tweak the PATH to include the tools dir.
|
||||
path = os.path.pathsep.join((config.llvm_tools_dir, config.environment['PATH']))
|
||||
config.environment['PATH'] = path
|
||||
llvm_config.with_environment('PATH', config.llvm_tools_dir, append_path=True)
|
||||
|
||||
# Propagate 'HOME' through the environment.
|
||||
if 'HOME' in os.environ:
|
||||
config.environment['HOME'] = os.environ['HOME']
|
||||
|
||||
# Propagate 'INCLUDE' through the environment.
|
||||
if 'INCLUDE' in os.environ:
|
||||
config.environment['INCLUDE'] = os.environ['INCLUDE']
|
||||
|
||||
# Propagate 'LIB' through the environment.
|
||||
if 'LIB' in os.environ:
|
||||
config.environment['LIB'] = os.environ['LIB']
|
||||
|
||||
# Propagate the temp directory. Windows requires this because it uses \Windows\
|
||||
# if none of these are present.
|
||||
if 'TMP' in os.environ:
|
||||
config.environment['TMP'] = os.environ['TMP']
|
||||
if 'TEMP' in os.environ:
|
||||
config.environment['TEMP'] = os.environ['TEMP']
|
||||
# Propagate some variables from the host environment.
|
||||
llvm_config.with_system_environment(['HOME', 'INCLUDE', 'LIB', 'TMP', 'TEMP', 'ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH'])
|
||||
|
||||
# Propagate LLVM_SRC_ROOT into the environment.
|
||||
config.environment['LLVM_SRC_ROOT'] = config.llvm_src_root
|
||||
|
||||
# Propagate PYTHON_EXECUTABLE into the environment
|
||||
config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable',
|
||||
'')
|
||||
|
||||
# Propagate path to symbolizer for ASan/MSan.
|
||||
for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
|
||||
if symbolizer in os.environ:
|
||||
config.environment[symbolizer] = os.environ[symbolizer]
|
||||
|
||||
# Set up OCAMLPATH to include newly built OCaml libraries.
|
||||
top_ocaml_lib = os.path.join(config.llvm_lib_dir, 'ocaml')
|
||||
llvm_ocaml_lib = os.path.join(top_ocaml_lib, 'llvm')
|
||||
ocamlpath = os.path.pathsep.join((llvm_ocaml_lib, top_ocaml_lib))
|
||||
if 'OCAMLPATH' in os.environ:
|
||||
ocamlpath = os.path.pathsep.join((ocamlpath, os.environ['OCAMLPATH']))
|
||||
config.environment['OCAMLPATH'] = ocamlpath
|
||||
|
||||
if 'CAML_LD_LIBRARY_PATH' in os.environ:
|
||||
caml_ld_library_path = os.path.pathsep.join((llvm_ocaml_lib,
|
||||
os.environ['CAML_LD_LIBRARY_PATH']))
|
||||
config.environment['CAML_LD_LIBRARY_PATH'] = caml_ld_library_path
|
||||
else:
|
||||
config.environment['CAML_LD_LIBRARY_PATH'] = llvm_ocaml_lib
|
||||
llvm_config.with_system_environment('OCAMLPATH')
|
||||
llvm_config.with_environment('OCAMLPATH', top_ocaml_lib, append_path=True)
|
||||
llvm_config.with_environment('OCAMLPATH', llvm_ocaml_lib, append_path=True)
|
||||
|
||||
llvm_config.with_system_environment('CAML_LD_LIBRARY_PATH')
|
||||
llvm_config.with_environment('CAML_LD_LIBRARY_PATH', llvm_ocaml_lib, append_path=True)
|
||||
|
||||
# Set up OCAMLRUNPARAM to enable backtraces in OCaml tests.
|
||||
config.environment['OCAMLRUNPARAM'] = 'b'
|
||||
llvm_config.with_environment('OCAMLRUNPARAM', 'b')
|
||||
|
||||
# Provide the path to asan runtime lib 'libclang_rt.asan_osx_dynamic.dylib' if
|
||||
# available. This is darwin specific since it's currently only needed on darwin.
|
||||
@ -300,10 +248,6 @@ for arch in config.targets_to_build.split():
|
||||
|
||||
### Features
|
||||
|
||||
# Shell execution
|
||||
if execute_external:
|
||||
config.available_features.add('shell')
|
||||
|
||||
# Others/can-execute.txt
|
||||
if sys.platform not in ['win32']:
|
||||
config.available_features.add('can-execute')
|
||||
@ -323,45 +267,14 @@ if loadable_module:
|
||||
if not config.build_shared_libs:
|
||||
config.available_features.add("static-libs")
|
||||
|
||||
# Sanitizers.
|
||||
if 'Address' in config.llvm_use_sanitizer:
|
||||
config.available_features.add("asan")
|
||||
else:
|
||||
config.available_features.add("not_asan")
|
||||
if 'Memory' in config.llvm_use_sanitizer:
|
||||
config.available_features.add("msan")
|
||||
else:
|
||||
config.available_features.add("not_msan")
|
||||
if 'Undefined' in config.llvm_use_sanitizer:
|
||||
config.available_features.add("ubsan")
|
||||
else:
|
||||
config.available_features.add("not_ubsan")
|
||||
|
||||
# Check if we should run long running tests.
|
||||
if lit_config.params.get("run_long_tests", None) == "true":
|
||||
config.available_features.add("long_tests")
|
||||
|
||||
# Direct object generation
|
||||
if not 'hexagon' in config.target_triple:
|
||||
config.available_features.add("object-emission")
|
||||
|
||||
if config.have_zlib:
|
||||
config.available_features.add("zlib")
|
||||
else:
|
||||
config.available_features.add("nozlib")
|
||||
|
||||
# LLVM can be configured with an empty default triple
|
||||
# Some tests are "generic" and require a valid default triple
|
||||
if config.target_triple:
|
||||
config.available_features.add("default_triple")
|
||||
if re.match(r'^x86_64.*-linux', config.target_triple):
|
||||
config.available_features.add("x86_64-linux")
|
||||
|
||||
# Native compilation: host arch == default triple arch
|
||||
# FIXME: Consider cases that target can be executed
|
||||
# even if host_triple were different from target_triple.
|
||||
if config.host_triple == config.target_triple:
|
||||
config.available_features.add("native")
|
||||
|
||||
import subprocess
|
||||
|
||||
@ -416,19 +329,9 @@ def have_ld64_plugin_support():
|
||||
if have_ld64_plugin_support():
|
||||
config.available_features.add('ld64_plugin')
|
||||
|
||||
# Ask llvm-config about assertion mode.
|
||||
try:
|
||||
llvm_config_cmd = subprocess.Popen(
|
||||
[os.path.join(config.llvm_tools_dir, 'llvm-config'), '--assertion-mode'],
|
||||
stdout = subprocess.PIPE,
|
||||
env=config.environment)
|
||||
except OSError:
|
||||
print("Could not find llvm-config in " + config.llvm_tools_dir)
|
||||
exit(42)
|
||||
|
||||
if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
|
||||
config.available_features.add('asserts')
|
||||
llvm_config_cmd.wait()
|
||||
# Ask llvm-config about asserts and global-isel.
|
||||
llvm_config.feature_config('--assertion-mode', 'asserts')
|
||||
llvm_config.feature_config('--has-global-isel', 'global-isel')
|
||||
|
||||
if 'darwin' == sys.platform:
|
||||
try:
|
||||
@ -441,56 +344,12 @@ if 'darwin' == sys.platform:
|
||||
config.available_features.add('fma3')
|
||||
sysctl_cmd.wait()
|
||||
|
||||
if platform.system() in ['Windows']:
|
||||
if re.match(r'.*-win32$', config.target_triple):
|
||||
config.available_features.add('target-windows')
|
||||
# For tests that require Windows to run.
|
||||
config.available_features.add('system-windows')
|
||||
|
||||
# .debug_frame is not emitted for targeting Windows x64.
|
||||
if not re.match(r'^x86_64.*-(mingw32|windows-gnu|win32)', config.target_triple):
|
||||
config.available_features.add('debug_frame')
|
||||
|
||||
# Check if we should use gmalloc.
|
||||
use_gmalloc_str = lit_config.params.get('use_gmalloc', None)
|
||||
if use_gmalloc_str is not None:
|
||||
if use_gmalloc_str.lower() in ('1', 'true'):
|
||||
use_gmalloc = True
|
||||
elif use_gmalloc_str.lower() in ('', '0', 'false'):
|
||||
use_gmalloc = False
|
||||
else:
|
||||
lit_config.fatal('user parameter use_gmalloc should be 0 or 1')
|
||||
else:
|
||||
# Default to not using gmalloc
|
||||
use_gmalloc = False
|
||||
|
||||
# Allow use of an explicit path for gmalloc library.
|
||||
# Will default to '/usr/lib/libgmalloc.dylib' if not set.
|
||||
gmalloc_path_str = lit_config.params.get('gmalloc_path',
|
||||
'/usr/lib/libgmalloc.dylib')
|
||||
|
||||
if use_gmalloc:
|
||||
config.environment.update({'DYLD_INSERT_LIBRARIES' : gmalloc_path_str})
|
||||
|
||||
# Ask llvm-config about global-isel.
|
||||
try:
|
||||
llvm_config_cmd = subprocess.Popen(
|
||||
[os.path.join(config.llvm_tools_dir, 'llvm-config'), '--has-global-isel'],
|
||||
stdout = subprocess.PIPE,
|
||||
env=config.environment)
|
||||
except OSError:
|
||||
print("Could not find llvm-config in " + config.llvm_tools_dir)
|
||||
exit(42)
|
||||
|
||||
if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
|
||||
config.available_features.add('global-isel')
|
||||
llvm_config_cmd.wait()
|
||||
|
||||
if config.have_libxar:
|
||||
config.available_features.add('xar')
|
||||
|
||||
if config.enable_abi_breaking_checks == "1":
|
||||
config.available_features.add('abi-breaking-checks')
|
||||
|
||||
if config.llvm_libxml2_enabled == "1":
|
||||
config.available_features.add('libxml2')
|
||||
|
@ -52,5 +52,7 @@ except KeyError:
|
||||
key, = e.args
|
||||
lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
|
||||
|
||||
@LIT_SITE_CFG_IN_FOOTER@
|
||||
|
||||
# Let the main config do the real work.
|
||||
lit_config.load_config(config, "@LLVM_SOURCE_DIR@/test/lit.cfg")
|
||||
|
9
utils/lit/lit/llvm/__init__.py
Normal file
9
utils/lit/lit/llvm/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
from lit.llvm import config
|
||||
|
||||
llvm_config = None
|
||||
|
||||
def initialize(lit_config, test_config):
|
||||
global llvm_config
|
||||
llvm_config = config.LLVMConfig(lit_config, test_config)
|
||||
|
125
utils/lit/lit/llvm/config.py
Normal file
125
utils/lit/lit/llvm/config.py
Normal file
@ -0,0 +1,125 @@
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import lit.util
|
||||
|
||||
# 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 an override.
|
||||
litshenv = os.environ.get("LIT_USE_INTERNAL_SHELL")
|
||||
litsh = lit.util.pythonize_bool(litshenv) if litshenv else (sys.platform == 'win32')
|
||||
|
||||
def binary_feature(on, feature, off_prefix):
|
||||
return feature if on else off_prefix + feature
|
||||
|
||||
class LLVMConfig(object):
|
||||
|
||||
def __init__(self, lit_config, config):
|
||||
self.lit_config = lit_config
|
||||
self.config = config
|
||||
|
||||
features = config.available_features
|
||||
|
||||
# Tweak PATH for Win32 to decide to use bash.exe or not.
|
||||
if sys.platform == 'win32':
|
||||
# For tests that require Windows to run.
|
||||
features.add('system-windows')
|
||||
|
||||
# Seek sane tools in directories and set to $PATH.
|
||||
path = self.lit_config.getToolsPath(config.lit_tools_dir,
|
||||
config.environment['PATH'],
|
||||
['cmp.exe', 'grep.exe', 'sed.exe'])
|
||||
self.with_environment('PATH', path, append_path=True)
|
||||
|
||||
if use_lit_shell:
|
||||
# 0 is external, "" is default, and everything else is internal.
|
||||
self.use_lit_shell = (use_lit_shell != "0")
|
||||
else:
|
||||
# Otherwise we default to internal on Windows and external elsewhere, as
|
||||
# bash on Windows is usually very slow.
|
||||
self.use_lit_shell = (sys.platform in ['win32'])
|
||||
|
||||
self.use_lit_shell = litsh
|
||||
if not self.litsh:
|
||||
features.add('shell')
|
||||
|
||||
# Native compilation: host arch == default triple arch
|
||||
# FIXME: Consider cases that target can be executed
|
||||
# even if host_triple were different from target_triple.
|
||||
if config.host_triple == config.target_triple:
|
||||
features.add("native")
|
||||
|
||||
# Sanitizers.
|
||||
sanitizers = frozenset(x.lower() for x in getattr(config, 'llvm_use_sanitizer', []).split(';'))
|
||||
features.add(binary_feature('address' in sanitizers, 'asan', 'not_'))
|
||||
features.add(binary_feature('memory' in sanitizers, 'msan', 'not_'))
|
||||
features.add(binary_feature('undefined' in sanitizers, 'ubsan', 'not_'))
|
||||
|
||||
have_zlib = getattr(config, 'have_zlib', None)
|
||||
features.add(binary_feature(have_zlib, 'zlib', 'no'))
|
||||
|
||||
# Check if we should run long running tests.
|
||||
long_tests = lit_config.params.get("run_long_tests", None)
|
||||
if lit.util.pythonize_bool(long_tests):
|
||||
features.add("long_tests")
|
||||
|
||||
target_triple = getattr(config, 'target_triple', None)
|
||||
if target_triple:
|
||||
if re.match(r'^x86_64.*-linux', target_triple):
|
||||
features.add("x86_64-linux")
|
||||
if re.match(r'.*-win32$', target_triple):
|
||||
features.add('target-windows')
|
||||
|
||||
use_gmalloc = lit_config.params.get('use_gmalloc', None)
|
||||
if lit.util.pythonize_bool(use_gmalloc):
|
||||
# Allow use of an explicit path for gmalloc library.
|
||||
# Will default to '/usr/lib/libgmalloc.dylib' if not set.
|
||||
gmalloc_path_str = lit_config.params.get('gmalloc_path',
|
||||
'/usr/lib/libgmalloc.dylib')
|
||||
if gmalloc_path_str is not None:
|
||||
self.with_environment('DYLD_INSERT_LIBRARIES', gmalloc_path_str)
|
||||
|
||||
breaking_checks = getattr(config, 'enable_abi_breaking_checks')
|
||||
if lit.util.pythonize_bool(lit_config, breaking_checks):
|
||||
features.add('abi-breaking-checks')
|
||||
|
||||
def with_environment(self, variable, value, append_path = False):
|
||||
if append_path and variable in self.config.environment:
|
||||
def norm(x):
|
||||
return os.path.normcase(os.path.normpath(x))
|
||||
|
||||
# Move it to the front if it already exists, otherwise insert it at the
|
||||
# beginning.
|
||||
value = norm(value)
|
||||
current_value = self.config.environment[variable]
|
||||
items = [norm(x) for x in current_value.split(os.path.pathsep)]
|
||||
try:
|
||||
items.remove(value)
|
||||
except ValueError:
|
||||
pass
|
||||
value = os.path.pathsep.join([value] + items)
|
||||
self.config.environment[variable] = value
|
||||
|
||||
|
||||
def with_system_environment(self, variables, append_path = False):
|
||||
if isinstance(variables, basestring):
|
||||
variables = [variables]
|
||||
for v in variables:
|
||||
value = os.environ.get(v)
|
||||
if value:
|
||||
self.with_environment(v, value, append_path)
|
||||
|
||||
def feature_config(self, flag, feature):
|
||||
# Ask llvm-config about assertion mode.
|
||||
try:
|
||||
llvm_config_cmd = subprocess.Popen(
|
||||
[os.path.join(self.config.llvm_tools_dir, 'llvm-config'), flag],
|
||||
stdout = subprocess.PIPE,
|
||||
env=self.config.environment)
|
||||
except OSError:
|
||||
self.lit_config.fatal("Could not find llvm-config in " + self.config.llvm_tools_dir)
|
||||
|
||||
output, _ = llvm_config_cmd.communicate()
|
||||
if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
|
||||
self.config.available_features.add(feature)
|
@ -8,6 +8,22 @@ import subprocess
|
||||
import sys
|
||||
import threading
|
||||
|
||||
|
||||
def pythonize_bool(value):
|
||||
if value is None:
|
||||
return False
|
||||
if type(value) is bool:
|
||||
return value
|
||||
if isinstance(value, (int, long)):
|
||||
return value != 0
|
||||
if isinstance(value, basestring):
|
||||
if value.lower() in ('1', 'true', 'on', 'yes'):
|
||||
return True
|
||||
if value.lower() in ('0', 'false', 'off', 'no'):
|
||||
return False
|
||||
raise ValueError('"{}" is not a valid boolean'.format(value))
|
||||
|
||||
|
||||
def to_bytes(s):
|
||||
"""Return the parameter as type 'bytes', possibly encoding it.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user