import os
import platform
import re
import subprocess
import sys
import lit.formats
import lit.util
from lit.llvm import llvm_config
from lit.llvm.subst import ToolSubst
config.name = "cross-project-tests"
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
config.suffixes = [".c", ".cl", ".cpp", ".m"]
config.excludes = ["Inputs"]
config.test_source_root = config.cross_project_tests_src_root
config.test_exec_root = config.cross_project_tests_obj_root
llvm_config.use_default_substitutions()
tools = [
ToolSubst(
"%test_debuginfo",
command=os.path.join(
config.cross_project_tests_src_root,
"debuginfo-tests",
"llgdb-tests",
"test_debuginfo.pl",
),
),
ToolSubst("%llvm_src_root", config.llvm_src_root),
ToolSubst("%llvm_tools_dir", config.llvm_tools_dir),
]
def get_required_attr(config, attr_name):
attr_value = getattr(config, attr_name, None)
if attr_value == None:
lit_config.fatal(
"No attribute %r in test configuration! You may need to run "
"tests from your build directory or add this attribute "
"to lit.site.cfg " % attr_name
)
return attr_value
is_msvc = get_required_attr(config, "is_msvc")
if is_msvc:
config.available_features.add("msvc")
win_sdk = "C:/Program Files (x86)/Windows Kits/10/"
arch = "x64"
llvm_config.with_system_environment(["LIB", "LIBPATH", "INCLUDE"])
llvm_config.with_environment("_NT_SYMBOL_PATH", "")
tools.append(
ToolSubst("%cdb", '"%s"' % os.path.join(win_sdk, "Debuggers", arch, "cdb.exe"))
)
if not hasattr(config, "clang_src_dir"):
config.clang_src_dir = ""
llvm_config.use_clang(required=("clang" in config.llvm_enabled_projects))
if not hasattr(config, "lld_src_dir"):
config.lld_src_dir = ""
llvm_config.use_lld(required=("lld" in config.llvm_enabled_projects))
if "compiler-rt" in config.llvm_enabled_projects:
config.available_features.add("compiler-rt")
lldb_path = llvm_config.use_llvm_tool("lldb", search_env="LLDB")
if lldb_path is not None:
config.available_features.add("lldb")
def configure_dexter_substitutions():
"""Configure substitutions for host platform and return list of dependencies"""
dexter_path = os.path.join(
config.cross_project_tests_src_root, "debuginfo-tests", "dexter", "dexter.py"
)
dexter_test_cmd = '"{}" "{}" test'.format(sys.executable, dexter_path)
if lldb_path is not None:
dexter_test_cmd += ' --lldb-executable "{}"'.format(lldb_path)
tools.append(ToolSubst("%dexter", dexter_test_cmd))
dexter_base_cmd = '"{}" "{}"'.format(sys.executable, dexter_path)
tools.append(ToolSubst("%dexter_base", dexter_base_cmd))
if platform.system() == "Windows":
dependencies = ["clang", "lld-link"]
dexter_regression_test_builder = "clang-cl"
dexter_regression_test_debugger = "dbgeng"
dexter_regression_test_flags = "/Zi /Od"
else:
dependencies = ["clang", "lldb"]
dexter_regression_test_builder = "clang++"
dexter_regression_test_debugger = "lldb"
dexter_regression_test_flags = "-O0 -glldb -std=gnu++11"
tools.append(
ToolSubst("%dexter_regression_test_builder", dexter_regression_test_builder)
)
tools.append(
ToolSubst("%dexter_regression_test_debugger", dexter_regression_test_debugger)
)
tools.append(
ToolSubst("%dexter_regression_test_flags", dexter_regression_test_flags)
)
dexter_regression_test_run = " ".join(
[
'"{}"'.format(sys.executable),
'"{}"'.format(dexter_path),
"test",
"--fail-lt 1.0 -w",
"--debugger",
dexter_regression_test_debugger,
]
)
tools.append(ToolSubst("%dexter_regression_test_run", dexter_regression_test_run))
dexter_regression_test_build = " ".join(
[
dexter_regression_test_builder,
dexter_regression_test_flags,
]
)
tools.append(ToolSubst("%dexter_regression_test_build", dexter_regression_test_build))
return dependencies
def add_host_triple(clang):
return "{} --target={}".format(clang, config.host_triple)
targets = set(config.targets_to_build)
if "AArch64" in targets:
targets.add("arm64")
if "ARM" in config.targets_to_build:
targets.add("thumbv7")
def can_target_host():
return any(config.host_triple.lower().startswith(x.lower()) for x in targets)
if can_target_host():
if config.host_triple != config.target_triple:
print("Forcing dexter tests to use host triple {}.".format(config.host_triple))
dependencies = configure_dexter_substitutions()
if all(d in config.available_features for d in dependencies):
config.available_features.add("dexter")
llvm_config.with_environment(
"PATHTOCLANG", add_host_triple(llvm_config.config.clang)
)
llvm_config.with_environment(
"PATHTOCLANGPP", add_host_triple(llvm_config.use_llvm_tool("clang++"))
)
llvm_config.with_environment(
"PATHTOCLANGCL", add_host_triple(llvm_config.use_llvm_tool("clang-cl"))
)
else:
print(
"Host triple {} not supported. Skipping dexter tests in the "
"debuginfo-tests project.".format(config.host_triple)
)
tool_dirs = [config.llvm_tools_dir]
llvm_config.add_tool_substitutions(tools, tool_dirs)
lit.util.usePlatformSdkOnDarwin(config, lit_config)
if platform.system() == "Darwin":
xcode_lldb_vers = subprocess.check_output(["xcrun", "lldb", "--version"]).decode(
"utf-8"
)
match = re.search("lldb-(\d+)", xcode_lldb_vers)
if match:
apple_lldb_vers = int(match.group(1))
if apple_lldb_vers < 1000:
config.available_features.add("apple-lldb-pre-1000")
def get_gdb_version_string():
"""Return gdb's version string, or None if gdb cannot be found or the
--version output is formatted unexpectedly.
"""
try:
gdb_vers_lines = (
subprocess.check_output(["gdb", "--version"]).decode().splitlines()
)
except:
return None
if len(gdb_vers_lines) < 1:
print("Unkown GDB version format (too few lines)", file=sys.stderr)
return None
match = re.search("GNU gdb \(.*?\) ((\d|\.)+)", gdb_vers_lines[0].strip())
if match is None:
print(f"Unkown GDB version format: {gdb_vers_lines[0]}", file=sys.stderr)
return None
return match.group(1)
def get_clang_default_dwarf_version_string(triple):
"""Return the default dwarf version string for clang on this (host) platform
or None if we can't work it out.
"""
cmd = f'{llvm_config.use_llvm_tool("clang")} -g -xc -c - -v -### --target={triple}'
stderr = subprocess.run(cmd.split(), stderr=subprocess.PIPE).stderr.decode()
match = re.search("-dwarf-version=(\d+)", stderr)
if match is None:
print("Cannot determine default dwarf version", file=sys.stderr)
return None
return match.group(1)
dwarf_version_string = get_clang_default_dwarf_version_string(config.host_triple)
gdb_version_string = get_gdb_version_string()
if dwarf_version_string and gdb_version_string:
if int(dwarf_version_string) >= 5:
try:
from packaging import version
except:
lit_config.fatal("Running gdb tests requires the packaging package")
if version.parse(gdb_version_string) < version.parse("10.1"):
config.available_features.add("gdb-clang-incompatibility")
print(
"XFAIL some tests: use gdb version >= 10.1 to restore test coverage",
file=sys.stderr,
)
llvm_config.feature_config([("--build-mode", {"Debug|RelWithDebInfo": "debug-info"})])
for arch in config.targets_to_build:
config.available_features.add(arch.lower() + "-registered-target")