Revert "[lldb] Explicitly use the configuration architecture when building test execu...
[lldb.git] / lldb / packages / Python / lldbsuite / test / builders / builder.py
1 import os
2 import platform
3 import subprocess
4 import sys
5
6 import lldbsuite.test.lldbtest as lldbtest
7 import lldbsuite.test.lldbutil as lldbutil
8 from lldbsuite.test import configuration
9 from lldbsuite.test_event import build_exception
10
11
12 class Builder:
13     def getArchitecture(self):
14         """Returns the architecture in effect the test suite is running with."""
15         return configuration.arch if configuration.arch else ""
16
17     def getCompiler(self):
18         """Returns the compiler in effect the test suite is running with."""
19         compiler = configuration.compiler if configuration.compiler else "clang"
20         compiler = lldbutil.which(compiler)
21         return os.path.abspath(compiler)
22
23     def getExtraMakeArgs(self):
24         """
25         Helper function to return extra argumentsfor the make system. This
26         method is meant to be overridden by platform specific builders.
27         """
28         return ""
29
30     def getArchCFlags(self, architecture):
31         """Returns the ARCH_CFLAGS for the make system."""
32         return ""
33
34     def getMake(self, test_subdir, test_name):
35         """Returns the invocation for GNU make.
36         The first argument is a tuple of the relative path to the testcase
37         and its filename stem."""
38         if platform.system() == "FreeBSD" or platform.system() == "NetBSD":
39             make = "gmake"
40         else:
41             make = "make"
42
43         # Construct the base make invocation.
44         lldb_test = os.environ["LLDB_TEST"]
45         if not (lldb_test and configuration.test_build_dir and test_subdir
46                 and test_name and (not os.path.isabs(test_subdir))):
47             raise Exception("Could not derive test directories")
48         build_dir = os.path.join(configuration.test_build_dir, test_subdir,
49                                  test_name)
50         src_dir = os.path.join(configuration.test_src_root, test_subdir)
51         # This is a bit of a hack to make inline testcases work.
52         makefile = os.path.join(src_dir, "Makefile")
53         if not os.path.isfile(makefile):
54             makefile = os.path.join(build_dir, "Makefile")
55         return [
56             make, "VPATH=" + src_dir, "-C", build_dir, "-I", src_dir, "-I",
57             os.path.join(lldb_test, "make"), "-f", makefile
58         ]
59
60     def getCmdLine(self, d):
61         """
62         Helper function to return a properly formatted command line argument(s)
63         string used for the make system.
64         """
65
66         # If d is None or an empty mapping, just return an empty string.
67         if not d:
68             return ""
69         pattern = '%s="%s"' if "win32" in sys.platform else "%s='%s'"
70
71         def setOrAppendVariable(k, v):
72             append_vars = ["CFLAGS", "CFLAGS_EXTRAS", "LD_EXTRAS"]
73             if k in append_vars and k in os.environ:
74                 v = os.environ[k] + " " + v
75             return pattern % (k, v)
76
77         cmdline = " ".join(
78             [setOrAppendVariable(k, v) for k, v in list(d.items())])
79
80         return cmdline
81
82     def runBuildCommands(self, commands, sender):
83         try:
84             lldbtest.system(commands, sender=sender)
85         except subprocess.CalledProcessError as called_process_error:
86             # Convert to a build-specific error.
87             # We don't do that in lldbtest.system() since that
88             # is more general purpose.
89             raise build_exception.BuildError(called_process_error)
90
91     def getArchSpec(self, architecture):
92         """
93         Helper function to return the key-value string to specify the architecture
94         used for the make system.
95         """
96         arch = architecture if architecture else None
97         if not arch and configuration.arch:
98             arch = configuration.arch
99
100         return ("ARCH=" + arch) if arch else ""
101
102     def getCCSpec(self, compiler):
103         """
104         Helper function to return the key-value string to specify the compiler
105         used for the make system.
106         """
107         cc = compiler if compiler else None
108         if not cc and configuration.compiler:
109             cc = configuration.compiler
110         if cc:
111             return "CC=\"%s\"" % cc
112         else:
113             return ""
114
115     def getSDKRootSpec(self):
116         """
117         Helper function to return the key-value string to specify the SDK root
118         used for the make system.
119         """
120         if configuration.sdkroot:
121             return "SDKROOT={}".format(configuration.sdkroot)
122         return ""
123
124     def getModuleCacheSpec(self):
125         """
126         Helper function to return the key-value string to specify the clang
127         module cache used for the make system.
128         """
129         if configuration.clang_module_cache_dir:
130             return "CLANG_MODULE_CACHE_DIR={}".format(
131                 configuration.clang_module_cache_dir)
132         return ""
133
134     def buildDefault(self,
135                      sender=None,
136                      architecture=None,
137                      compiler=None,
138                      dictionary=None,
139                      testdir=None,
140                      testname=None):
141         """Build the binaries the default way."""
142         commands = []
143         commands.append(
144             self.getMake(testdir, testname) + [
145                 "all",
146                 self.getArchCFlags(architecture),
147                 self.getArchSpec(architecture),
148                 self.getCCSpec(compiler),
149                 self.getExtraMakeArgs(),
150                 self.getSDKRootSpec(),
151                 self.getModuleCacheSpec(),
152                 self.getCmdLine(dictionary)
153             ])
154
155         self.runBuildCommands(commands, sender=sender)
156
157         # True signifies that we can handle building default.
158         return True
159
160     def buildDwarf(self,
161                    sender=None,
162                    architecture=None,
163                    compiler=None,
164                    dictionary=None,
165                    testdir=None,
166                    testname=None):
167         """Build the binaries with dwarf debug info."""
168         commands = []
169         commands.append(
170             self.getMake(testdir, testname) + [
171                 "MAKE_DSYM=NO",
172                 self.getArchCFlags(architecture),
173                 self.getArchSpec(architecture),
174                 self.getCCSpec(compiler),
175                 self.getExtraMakeArgs(),
176                 self.getSDKRootSpec(),
177                 self.getModuleCacheSpec(),
178                 self.getCmdLine(dictionary)
179             ])
180
181         self.runBuildCommands(commands, sender=sender)
182         # True signifies that we can handle building dwarf.
183         return True
184
185     def buildDwo(self,
186                  sender=None,
187                  architecture=None,
188                  compiler=None,
189                  dictionary=None,
190                  testdir=None,
191                  testname=None):
192         """Build the binaries with dwarf debug info."""
193         commands = []
194         commands.append(
195             self.getMake(testdir, testname) + [
196                 "MAKE_DSYM=NO", "MAKE_DWO=YES",
197                 self.getArchCFlags(architecture),
198                 self.getArchSpec(architecture),
199                 self.getCCSpec(compiler),
200                 self.getExtraMakeArgs(),
201                 self.getSDKRootSpec(),
202                 self.getModuleCacheSpec(),
203                 self.getCmdLine(dictionary)
204             ])
205
206         self.runBuildCommands(commands, sender=sender)
207         # True signifies that we can handle building dwo.
208         return True
209
210     def buildGModules(self,
211                       sender=None,
212                       architecture=None,
213                       compiler=None,
214                       dictionary=None,
215                       testdir=None,
216                       testname=None):
217         """Build the binaries with dwarf debug info."""
218         commands = []
219         commands.append(
220             self.getMake(testdir, testname) + [
221                 "MAKE_DSYM=NO", "MAKE_GMODULES=YES",
222                 self.getArchCFlags(architecture),
223                 self.getArchSpec(architecture),
224                 self.getCCSpec(compiler),
225                 self.getExtraMakeArgs(),
226                 self.getSDKRootSpec(),
227                 self.getModuleCacheSpec(),
228                 self.getCmdLine(dictionary)
229             ])
230
231         self.runBuildCommands(commands, sender=sender)
232         # True signifies that we can handle building with gmodules.
233         return True
234
235     def buildDsym(self,
236                   sender=None,
237                   architecture=None,
238                   compiler=None,
239                   dictionary=None,
240                   testdir=None,
241                   testname=None):
242         # False signifies that we cannot handle building with dSYM.
243         return False
244
245     def cleanup(self, sender=None, dictionary=None):
246         """Perform a platform-specific cleanup after the test."""
247         return True