llvm-project
332 строки · 11.9 Кб
1# -*- Python -*-
2
3# Configuration file for the 'lit' test runner.
4
5import os6import platform7import shlex8import shutil9import subprocess10import sys11
12import lit.formats13
14# name: The name of this test suite.
15config.name = "lldb-api"16
17# suffixes: A list of file extensions to treat as test files.
18config.suffixes = [".py"]19
20# test_source_root: The root path where tests are located.
21config.test_source_root = os.path.dirname(__file__)22
23# test_exec_root: The root path where tests should be run.
24config.test_exec_root = os.path.join(config.lldb_obj_root, "test", "API")25
26
27def mkdir_p(path):28import errno29
30try:31os.makedirs(path)32except OSError as e:33if e.errno != errno.EEXIST:34raise35if not os.path.isdir(path):36raise OSError(errno.ENOTDIR, "%s is not a directory" % path)37
38
39def find_sanitizer_runtime(name):40resource_dir = (41subprocess.check_output([config.cmake_cxx_compiler, "-print-resource-dir"])42.decode("utf-8")43.strip()44)45return os.path.join(resource_dir, "lib", "darwin", name)46
47
48def find_shlibpath_var():49if platform.system() in ["Linux", "FreeBSD", "NetBSD", "OpenBSD", "SunOS"]:50yield "LD_LIBRARY_PATH"51elif platform.system() == "Darwin":52yield "DYLD_LIBRARY_PATH"53elif platform.system() == "Windows":54yield "PATH"55
56
57# On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim python
58# binary as the ASan interceptors get loaded too late. Also, when SIP is
59# enabled, we can't inject libraries into system binaries at all, so we need a
60# copy of the "real" python to work with.
61def find_python_interpreter():62# This is only necessary when using DYLD_INSERT_LIBRARIES.63if "DYLD_INSERT_LIBRARIES" not in config.environment:64return None65
66# If we're running in a virtual environment, we have to copy Python into67# the virtual environment for it to work.68if sys.prefix != sys.base_prefix:69copied_python = os.path.join(sys.prefix, "bin", "copied-python")70else:71copied_python = os.path.join(config.lldb_build_directory, "copied-python")72
73# Avoid doing any work if we already copied the binary.74if os.path.isfile(copied_python):75return copied_python76
77# Find the "real" python binary.78real_python = (79subprocess.check_output(80[81config.python_executable,82os.path.join(83os.path.dirname(os.path.realpath(__file__)),84"get_darwin_real_python.py",85),86]87)88.decode("utf-8")89.strip()90)91
92shutil.copy(real_python, copied_python)93
94# Now make sure the copied Python works. The Python in Xcode has a relative95# RPATH and cannot be copied.96try:97# We don't care about the output, just make sure it runs.98subprocess.check_call([copied_python, "-V"])99except subprocess.CalledProcessError:100# The copied Python didn't work. Assume we're dealing with the Python101# interpreter in Xcode. Given that this is not a system binary SIP102# won't prevent us form injecting the interceptors, but when running in103# a virtual environment, we can't use it directly. Create a symlink104# instead.105os.remove(copied_python)106os.symlink(real_python, copied_python)107
108# The copied Python works.109return copied_python110
111
112def is_configured(attr):113"""Return the configuration attribute if it exists and None otherwise.114
115This allows us to check if the attribute exists before trying to access it."""
116return getattr(config, attr, None)117
118
119def delete_module_cache(path):120"""Clean the module caches in the test build directory.121
122This is necessary in an incremental build whenever clang changes underneath,
123so doing it once per lit.py invocation is close enough."""
124if os.path.isdir(path):125lit_config.note("Deleting module cache at %s." % path)126shutil.rmtree(path)127
128
129if is_configured("llvm_use_sanitizer"):130if "Address" in config.llvm_use_sanitizer:131config.environment["ASAN_OPTIONS"] = "detect_stack_use_after_return=1"132if "Darwin" in config.host_os:133config.environment["DYLD_INSERT_LIBRARIES"] = find_sanitizer_runtime(134"libclang_rt.asan_osx_dynamic.dylib"135)136config.environment["MallocNanoZone"] = "0"137
138if "Thread" in config.llvm_use_sanitizer:139config.environment["TSAN_OPTIONS"] = "halt_on_error=1"140if "Darwin" in config.host_os:141config.environment["DYLD_INSERT_LIBRARIES"] = find_sanitizer_runtime(142"libclang_rt.tsan_osx_dynamic.dylib"143)144
145if platform.system() == "Darwin":146python_executable = find_python_interpreter()147if python_executable:148lit_config.note(149"Using {} instead of {}".format(python_executable, config.python_executable)150)151config.python_executable = python_executable152
153# Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent.
154if is_configured("shared_libs"):155for shlibpath_var in find_shlibpath_var():156# In stand-alone build llvm_shlib_dir specifies LLDB's lib directory while157# llvm_libs_dir specifies LLVM's lib directory.158shlibpath = os.path.pathsep.join(159(160config.llvm_shlib_dir,161config.llvm_libs_dir,162config.environment.get(shlibpath_var, ""),163)164)165config.environment[shlibpath_var] = shlibpath166else:167lit_config.warning(168"unable to inject shared library path on '{}'".format(platform.system())169)170
171lldb_use_simulator = lit_config.params.get("lldb-run-with-simulator", None)172if lldb_use_simulator:173if lldb_use_simulator == "ios":174lit_config.note("Running API tests on iOS simulator")175config.available_features.add("lldb-simulator-ios")176elif lldb_use_simulator == "watchos":177lit_config.note("Running API tests on watchOS simulator")178config.available_features.add("lldb-simulator-watchos")179elif lldb_use_simulator == "tvos":180lit_config.note("Running API tests on tvOS simulator")181config.available_features.add("lldb-simulator-tvos")182else:183lit_config.error("Unknown simulator id '{}'".format(lldb_use_simulator))184
185# Set a default per-test timeout of 10 minutes. Setting a timeout per test
186# requires that killProcessAndChildren() is supported on the platform and
187# lit complains if the value is set but it is not supported.
188supported, errormsg = lit_config.maxIndividualTestTimeIsSupported189if supported:190lit_config.maxIndividualTestTime = 600191else:192lit_config.warning("Could not set a default per-test timeout. " + errormsg)193
194# Build dotest command.
195dotest_cmd = [os.path.join(config.lldb_src_root, "test", "API", "dotest.py")]196
197if is_configured("dotest_common_args_str"):198dotest_cmd.extend(config.dotest_common_args_str.split(";"))199
200# Library path may be needed to locate just-built clang and libcxx.
201if is_configured("llvm_libs_dir"):202dotest_cmd += ["--env", "LLVM_LIBS_DIR=" + config.llvm_libs_dir]203
204# Include path may be needed to locate just-built libcxx.
205if is_configured("llvm_include_dir"):206dotest_cmd += ["--env", "LLVM_INCLUDE_DIR=" + config.llvm_include_dir]207
208# This path may be needed to locate required llvm tools
209if is_configured("llvm_tools_dir"):210dotest_cmd += ["--env", "LLVM_TOOLS_DIR=" + config.llvm_tools_dir]211
212# If we have a just-built libcxx, prefer it over the system one.
213if is_configured("has_libcxx") and config.has_libcxx:214if platform.system() != "Windows":215if is_configured("libcxx_include_dir") and is_configured("libcxx_libs_dir"):216dotest_cmd += ["--libcxx-include-dir", config.libcxx_include_dir]217if is_configured("libcxx_include_target_dir"):218dotest_cmd += [219"--libcxx-include-target-dir",220config.libcxx_include_target_dir,221]222dotest_cmd += ["--libcxx-library-dir", config.libcxx_libs_dir]223
224# Forward ASan-specific environment variables to tests, as a test may load an
225# ASan-ified dylib.
226for env_var in ("ASAN_OPTIONS", "DYLD_INSERT_LIBRARIES"):227if env_var in config.environment:228dotest_cmd += ["--inferior-env", env_var + "=" + config.environment[env_var]]229
230if is_configured("test_arch"):231dotest_cmd += ["--arch", config.test_arch]232
233if is_configured("lldb_build_directory"):234dotest_cmd += ["--build-dir", config.lldb_build_directory]235
236if is_configured("lldb_module_cache"):237delete_module_cache(config.lldb_module_cache)238dotest_cmd += ["--lldb-module-cache-dir", config.lldb_module_cache]239
240if is_configured("clang_module_cache"):241delete_module_cache(config.clang_module_cache)242dotest_cmd += ["--clang-module-cache-dir", config.clang_module_cache]243
244if is_configured("lldb_executable"):245dotest_cmd += ["--executable", config.lldb_executable]246
247if is_configured("test_compiler"):248dotest_cmd += ["--compiler", config.test_compiler]249
250if is_configured("dsymutil"):251dotest_cmd += ["--dsymutil", config.dsymutil]252
253if is_configured("llvm_tools_dir"):254dotest_cmd += ["--llvm-tools-dir", config.llvm_tools_dir]255
256if is_configured("server"):257dotest_cmd += ["--server", config.server]258
259if is_configured("lldb_obj_root"):260dotest_cmd += ["--lldb-obj-root", config.lldb_obj_root]261
262if is_configured("lldb_libs_dir"):263dotest_cmd += ["--lldb-libs-dir", config.lldb_libs_dir]264
265if is_configured("lldb_framework_dir"):266dotest_cmd += ["--framework", config.lldb_framework_dir]267
268if (269"lldb-repro-capture" in config.available_features270or "lldb-repro-replay" in config.available_features271):272dotest_cmd += ["--skip-category=lldb-dap", "--skip-category=std-module"]273
274if "lldb-simulator-ios" in config.available_features:275dotest_cmd += ["--apple-sdk", "iphonesimulator", "--platform-name", "ios-simulator"]276elif "lldb-simulator-watchos" in config.available_features:277dotest_cmd += [278"--apple-sdk",279"watchsimulator",280"--platform-name",281"watchos-simulator",282]283elif "lldb-simulator-tvos" in config.available_features:284dotest_cmd += [285"--apple-sdk",286"appletvsimulator",287"--platform-name",288"tvos-simulator",289]290
291if is_configured("enabled_plugins"):292for plugin in config.enabled_plugins:293dotest_cmd += ["--enable-plugin", plugin]294
295# `dotest` args come from three different sources:
296# 1. Derived by CMake based on its configs (LLDB_TEST_COMMON_ARGS), which end
297# up in `dotest_common_args_str`.
298# 2. CMake user parameters (LLDB_TEST_USER_ARGS), which end up in
299# `dotest_user_args_str`.
300# 3. With `llvm-lit "--param=dotest-args=..."`, which end up in
301# `dotest_lit_args_str`.
302# Check them in this order, so that more specific overrides are visited last.
303# In particular, (1) is visited at the top of the file, since the script
304# derives other information from it.
305
306if is_configured("dotest_user_args_str"):307dotest_cmd.extend(config.dotest_user_args_str.split(";"))308
309if is_configured("dotest_lit_args_str"):310# We don't want to force users passing arguments to lit to use `;` as a311# separator. We use Python's simple lexical analyzer to turn the args into a312# list. Pass there arguments last so they can override anything that was313# already configured.314dotest_cmd.extend(shlex.split(config.dotest_lit_args_str))315
316# Load LLDB test format.
317sys.path.append(os.path.join(config.lldb_src_root, "test", "API"))318import lldbtest319
320# testFormat: The test format to use to interpret tests.
321config.test_format = lldbtest.LLDBTest(dotest_cmd)322
323# Propagate TERM or default to vt100.
324config.environment["TERM"] = os.getenv("TERM", default="vt100")325
326# Propagate FREEBSD_LEGACY_PLUGIN
327if "FREEBSD_LEGACY_PLUGIN" in os.environ:328config.environment["FREEBSD_LEGACY_PLUGIN"] = os.environ["FREEBSD_LEGACY_PLUGIN"]329
330# Propagate XDG_CACHE_HOME
331if "XDG_CACHE_HOME" in os.environ:332config.environment["XDG_CACHE_HOME"] = os.environ["XDG_CACHE_HOME"]333