[OptTable] Fix typo VALUE => VALUES (NFCI) (#121523)
[llvm-project.git] / lldb / test / Shell / helper / toolchain.py
blob42968128f27026928db88a328d4fe293e4676857
1 import os
2 import itertools
3 import platform
4 import re
5 import subprocess
6 import sys
8 import lit.util
9 from lit.formats import ShTest
10 from lit.llvm import llvm_config
11 from lit.llvm.subst import FindTool
12 from lit.llvm.subst import ToolSubst
14 import posixpath
16 def _get_lldb_init_path(config):
17 return os.path.join(config.test_exec_root, "lit-lldb-init-quiet")
20 def _disallow(config, execName):
21 warning = """
22 echo '*** Do not use \'{0}\' in tests; use \'%''{0}\'. ***' &&
23 exit 1 && echo
24 """
25 config.substitutions.append((" {0} ".format(execName), warning.format(execName)))
28 def get_lldb_args(config, suffix=""):
29 lldb_args = []
30 if "remote-linux" in config.available_features:
31 lldb_args += [
32 "-O",
33 '"platform select remote-linux"',
34 "-O",
35 f'"platform connect {config.lldb_platform_url}"',
37 if config.lldb_platform_working_dir:
38 dir = posixpath.join(f"{config.lldb_platform_working_dir}", "shell")
39 if suffix:
40 dir += posixpath.join(dir, f"{suffix}")
41 lldb_args += [
42 "-O",
43 f'"platform shell mkdir -p {dir}"',
44 "-O",
45 f'"platform settings -w {dir}"',
47 lldb_args += ["--no-lldbinit", "-S", _get_lldb_init_path(config)]
48 return lldb_args
51 class ShTestLldb(ShTest):
52 def __init__(
53 self, execute_external=False, extra_substitutions=[], preamble_commands=[]
55 super().__init__(execute_external, extra_substitutions, preamble_commands)
57 def execute(self, test, litConfig):
58 # Run each Shell test in a separate directory (on remote).
60 # Find directory change command in %lldb substitution.
61 for i, t in enumerate(test.config.substitutions):
62 if re.match(t[0], "%lldb"):
63 cmd = t[1]
64 if '-O "platform settings -w ' in cmd:
65 # If command is present, it is added by get_lldb_args.
66 # Replace the path with the tests' path in suite.
67 # Example:
68 # bin/lldb
69 # -O "platform shell mkdir -p /home/user/shell"
70 # -O "platform settings -w /home/user/shell" ...
71 # =>
72 # bin/lldb
73 # -O "platform shell mkdir -p /home/user/shell/SymbolFile/Breakpad/inline-record.test"
74 # -O "platform settings -w /home/user/shell/SymbolFile/Breakpad/inline-record.test" ...
75 args_def = " ".join(get_lldb_args(test.config))
76 args_unique = " ".join(
77 get_lldb_args(
78 test.config,
79 posixpath.join(*test.path_in_suite),
82 test.config.substitutions[i] = (
83 t[0],
84 cmd.replace(args_def, args_unique),
86 break
87 return super().execute(test, litConfig)
90 def use_lldb_substitutions(config):
91 # Set up substitutions for primary tools. These tools must come from config.lldb_tools_dir
92 # which is basically the build output directory. We do not want to find these in path or
93 # anywhere else, since they are specifically the programs which are actually being tested.
95 dsname = "debugserver" if platform.system() in ["Darwin"] else "lldb-server"
96 dsargs = [] if platform.system() in ["Darwin"] else ["gdbserver"]
98 build_script = os.path.dirname(__file__)
99 build_script = os.path.join(build_script, "build.py")
100 build_script_args = [
101 build_script,
103 "--compiler=clang" if config.enable_remote else "--compiler=any"
104 ), # Default to best compiler
105 "--arch=" + str(config.lldb_bitness),
107 if config.lldb_lit_tools_dir:
108 build_script_args.append("--tools-dir={0}".format(config.lldb_lit_tools_dir))
109 if config.lldb_tools_dir:
110 build_script_args.append("--tools-dir={0}".format(config.lldb_tools_dir))
111 if config.llvm_libs_dir:
112 build_script_args.append("--libs-dir={0}".format(config.llvm_libs_dir))
113 if config.objc_gnustep_dir:
114 build_script_args.append(
115 '--objc-gnustep-dir="{0}"'.format(config.objc_gnustep_dir)
117 if config.cmake_sysroot:
118 build_script_args.append("--sysroot={0}".format(config.cmake_sysroot))
120 lldb_init = _get_lldb_init_path(config)
122 primary_tools = [
123 ToolSubst(
124 "%lldb",
125 command=FindTool("lldb"),
126 extra_args=get_lldb_args(config),
127 unresolved="fatal",
129 ToolSubst(
130 "%lldb-init",
131 command=FindTool("lldb"),
132 extra_args=["-S", lldb_init],
133 unresolved="fatal",
135 ToolSubst(
136 "%lldb-noinit",
137 command=FindTool("lldb"),
138 extra_args=["--no-lldbinit"],
139 unresolved="fatal",
141 ToolSubst(
142 "%lldb-server",
143 command=FindTool("lldb-server"),
144 extra_args=[],
145 unresolved="ignore",
147 ToolSubst(
148 "%debugserver",
149 command=FindTool(dsname),
150 extra_args=dsargs,
151 unresolved="ignore",
153 ToolSubst(
154 "%platformserver",
155 command=FindTool("lldb-server"),
156 extra_args=["platform"],
157 unresolved="ignore",
159 "lldb-test",
160 "lldb-dap",
161 ToolSubst(
162 "%build", command="'" + sys.executable + "'", extra_args=build_script_args
166 _disallow(config, "lldb")
167 _disallow(config, "lldb-server")
168 _disallow(config, "debugserver")
169 _disallow(config, "platformserver")
171 llvm_config.add_tool_substitutions(primary_tools, [config.lldb_tools_dir])
174 def _use_msvc_substitutions(config):
175 # If running from a Visual Studio Command prompt (e.g. vcvars), this will
176 # detect the include and lib paths, and find cl.exe and link.exe and create
177 # substitutions for each of them that explicitly specify /I and /L paths
178 cl = lit.util.which("cl")
180 if not cl:
181 return
183 # Don't use lit.util.which() for link.exe: In `git bash`, it will pick
184 # up /usr/bin/link (another name for ln).
185 link = os.path.join(os.path.dirname(cl), "link.exe")
187 cl = '"' + cl + '"'
188 link = '"' + link + '"'
189 includes = os.getenv("INCLUDE", "").split(";")
190 libs = os.getenv("LIB", "").split(";")
192 config.available_features.add("msvc")
193 compiler_flags = ['"/I{}"'.format(x) for x in includes if os.path.exists(x)]
194 linker_flags = ['"/LIBPATH:{}"'.format(x) for x in libs if os.path.exists(x)]
196 tools = [
197 ToolSubst("%msvc_cl", command=cl, extra_args=compiler_flags),
198 ToolSubst("%msvc_link", command=link, extra_args=linker_flags),
200 llvm_config.add_tool_substitutions(tools)
201 return
204 def use_support_substitutions(config):
205 # Set up substitutions for support tools. These tools can be overridden at the CMake
206 # level (by specifying -DLLDB_LIT_TOOLS_DIR), installed, or as a last resort, we can use
207 # the just-built version.
208 if config.enable_remote:
209 host_flags = ["--target=" + config.target_triple]
210 else:
211 host_flags = ["--target=" + config.host_triple]
212 if platform.system() in ["Darwin"]:
213 try:
214 out = subprocess.check_output(["xcrun", "--show-sdk-path"]).strip()
215 res = 0
216 except OSError:
217 res = -1
218 if res == 0 and out:
219 sdk_path = lit.util.to_string(out)
220 llvm_config.lit_config.note("using SDKROOT: %r" % sdk_path)
221 host_flags += ["-isysroot", sdk_path]
222 elif sys.platform != "win32":
223 host_flags += ["-pthread"]
225 if sys.platform.startswith("netbsd"):
226 # needed e.g. to use freshly built libc++
227 host_flags += [
228 "-L" + config.llvm_libs_dir,
229 "-Wl,-rpath," + config.llvm_libs_dir,
232 # The clang module cache is used for building inferiors.
233 host_flags += ["-fmodules-cache-path={}".format(config.clang_module_cache)]
235 if config.cmake_sysroot:
236 host_flags += ["--sysroot={}".format(config.cmake_sysroot)]
238 if config.enable_remote and config.has_libcxx:
239 host_flags += [
240 "-L{}".format(config.libcxx_libs_dir),
241 "-lc++",
244 host_flags = " ".join(host_flags)
245 config.substitutions.append(("%clang_host", "%clang " + host_flags))
246 config.substitutions.append(("%clangxx_host", "%clangxx " + host_flags))
247 config.substitutions.append(
248 ("%clang_cl_host", "%clang_cl --target=" + config.host_triple)
251 additional_tool_dirs = []
252 if config.lldb_lit_tools_dir:
253 additional_tool_dirs.append(config.lldb_lit_tools_dir)
255 llvm_config.use_clang(
256 additional_flags=["--target=specify-a-target-or-use-a-_host-substitution"],
257 additional_tool_dirs=additional_tool_dirs,
258 required=True,
259 use_installed=True,
262 if sys.platform == "win32":
263 _use_msvc_substitutions(config)
265 have_lld = llvm_config.use_lld(
266 additional_tool_dirs=additional_tool_dirs, required=False, use_installed=True
268 if have_lld:
269 config.available_features.add("lld")
271 support_tools = [
272 "yaml2obj",
273 "obj2yaml",
274 "llvm-dwp",
275 "llvm-pdbutil",
276 "llvm-mc",
277 "llvm-readobj",
278 "llvm-objdump",
279 "llvm-objcopy",
280 "lli",
282 additional_tool_dirs += [config.lldb_tools_dir, config.llvm_tools_dir]
283 llvm_config.add_tool_substitutions(support_tools, additional_tool_dirs)
285 _disallow(config, "clang")