[lldb/Util] Add a utility to run transparently capture and replay tests.
[lldb.git] / lldb / test / Shell / helper / toolchain.py
1 import os
2 import itertools
3 import platform
4 import subprocess
5 import sys
6
7 import lit.util
8 from lit.llvm import llvm_config
9 from lit.llvm.subst import FindTool
10 from lit.llvm.subst import ToolSubst
11
12
13 def _get_lldb_init_path(config):
14     return os.path.join(config.test_exec_root, 'Shell', 'lit-lldb-init')
15
16
17 def use_lldb_substitutions(config):
18     # Set up substitutions for primary tools.  These tools must come from config.lldb_tools_dir
19     # which is basically the build output directory.  We do not want to find these in path or
20     # anywhere else, since they are specifically the programs which are actually being tested.
21
22     dsname = 'debugserver' if platform.system() in ['Darwin'] else 'lldb-server'
23     dsargs = [] if platform.system() in ['Darwin'] else ['gdbserver']
24
25     build_script = os.path.dirname(__file__)
26     build_script = os.path.join(build_script, 'build.py')
27     build_script_args = [build_script,
28                         '--compiler=any', # Default to best compiler
29                         '--arch=' + str(config.lldb_bitness)]
30     if config.lldb_lit_tools_dir:
31         build_script_args.append('--tools-dir={0}'.format(config.lldb_lit_tools_dir))
32     if config.lldb_tools_dir:
33         build_script_args.append('--tools-dir={0}'.format(config.lldb_tools_dir))
34     if config.llvm_libs_dir:
35         build_script_args.append('--libs-dir={0}'.format(config.llvm_libs_dir))
36
37     lldb_init = _get_lldb_init_path(config)
38
39     primary_tools = [
40         ToolSubst('%lldb',
41                   command=FindTool('lldb'),
42                   extra_args=['--no-lldbinit', '-S', lldb_init]),
43         ToolSubst('%lldb-init',
44                   command=FindTool('lldb'),
45                   extra_args=['-S', lldb_init]),
46         ToolSubst('%debugserver',
47                   command=FindTool(dsname),
48                   extra_args=dsargs,
49                   unresolved='ignore'),
50         ToolSubst('%platformserver',
51                   command=FindTool('lldb-server'),
52                   extra_args=['platform'],
53                   unresolved='ignore'),
54         'lldb-test',
55         'lldb-instr',
56         ToolSubst('%build',
57                   command="'" + sys.executable + "'",
58                   extra_args=build_script_args)
59         ]
60
61     llvm_config.add_tool_substitutions(primary_tools,
62                                        [config.lldb_tools_dir])
63
64 def _use_msvc_substitutions(config):
65     # If running from a Visual Studio Command prompt (e.g. vcvars), this will
66     # detect the include and lib paths, and find cl.exe and link.exe and create
67     # substitutions for each of them that explicitly specify /I and /L paths
68     cl = lit.util.which('cl')
69     link = lit.util.which('link')
70
71     if not cl or not link:
72         return
73
74     cl = '"' + cl + '"'
75     link = '"' + link + '"'
76     includes = os.getenv('INCLUDE', '').split(';')
77     libs = os.getenv('LIB', '').split(';')
78
79     config.available_features.add('msvc')
80     compiler_flags = ['"/I{}"'.format(x) for x in includes if os.path.exists(x)]
81     linker_flags = ['"/LIBPATH:{}"'.format(x) for x in libs if os.path.exists(x)]
82
83     tools = [
84         ToolSubst('%msvc_cl', command=cl, extra_args=compiler_flags),
85         ToolSubst('%msvc_link', command=link, extra_args=linker_flags)]
86     llvm_config.add_tool_substitutions(tools)
87     return
88
89 def use_support_substitutions(config):
90     # Set up substitutions for support tools.  These tools can be overridden at the CMake
91     # level (by specifying -DLLDB_LIT_TOOLS_DIR), installed, or as a last resort, we can use
92     # the just-built version.
93     host_flags = ['--target=' + config.host_triple]
94     if platform.system() in ['Darwin']:
95         try:
96             out = subprocess.check_output(['xcrun', '--show-sdk-path']).strip()
97             res = 0
98         except OSError:
99             res = -1
100         if res == 0 and out:
101             sdk_path = lit.util.to_string(out)
102             llvm_config.lit_config.note('using SDKROOT: %r' % sdk_path)
103             host_flags += ['-isysroot', sdk_path]
104     elif platform.system() in ['NetBSD', 'OpenBSD', 'Linux']:
105         host_flags += ['-pthread']
106
107     if sys.platform.startswith('netbsd'):
108         # needed e.g. to use freshly built libc++
109         host_flags += ['-L' + config.llvm_libs_dir,
110                   '-Wl,-rpath,' + config.llvm_libs_dir]
111
112     # The clang module cache is used for building inferiors.
113     host_flags += ['-fmodules-cache-path={}'.format(config.clang_module_cache)]
114
115     host_flags = ' '.join(host_flags)
116     config.substitutions.append(('%clang_host', '%clang ' + host_flags))
117     config.substitutions.append(('%clangxx_host', '%clangxx ' + host_flags))
118     config.substitutions.append(('%clang_cl_host', '%clang_cl --target='+config.host_triple))
119
120     additional_tool_dirs=[]
121     if config.lldb_lit_tools_dir:
122         additional_tool_dirs.append(config.lldb_lit_tools_dir)
123
124     llvm_config.use_clang(additional_flags=['--target=specify-a-target-or-use-a-_host-substitution'],
125                           additional_tool_dirs=additional_tool_dirs,
126                           required=True)
127
128
129     if sys.platform == 'win32':
130         _use_msvc_substitutions(config)
131
132     have_lld = llvm_config.use_lld(additional_tool_dirs=additional_tool_dirs,
133                                    required=False)
134     if have_lld:
135         config.available_features.add('lld')
136
137
138     support_tools = ['yaml2obj', 'obj2yaml', 'llvm-pdbutil',
139                      'llvm-mc', 'llvm-readobj', 'llvm-objdump',
140                      'llvm-objcopy', 'lli']
141     additional_tool_dirs += [config.lldb_tools_dir, config.llvm_tools_dir]
142     llvm_config.add_tool_substitutions(support_tools, additional_tool_dirs)
143
144
145 def use_lldb_repro_substitutions(config, mode):
146     lldb_init = _get_lldb_init_path(config)
147     substitutions = [
148         ToolSubst(
149             '%lldb',
150             command=FindTool('lldb-repro'),
151             extra_args=[mode, '--no-lldbinit', '-S', lldb_init]),
152         ToolSubst(
153             '%lldb-init',
154             command=FindTool('lldb-repro'),
155             extra_args=[mode, '-S', lldb_init]),
156     ]
157     llvm_config.add_tool_substitutions(substitutions)