xref: /openbsd-src/gnu/llvm/lldb/packages/Python/lldbsuite/test/builders/builder.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1be691f3bSpatrickimport os
2be691f3bSpatrickimport platform
3be691f3bSpatrickimport subprocess
4be691f3bSpatrickimport sys
5*f6aab3d8Srobertimport itertools
6be691f3bSpatrick
7be691f3bSpatrickimport lldbsuite.test.lldbtest as lldbtest
8be691f3bSpatrickimport lldbsuite.test.lldbutil as lldbutil
9be691f3bSpatrickfrom lldbsuite.test import configuration
10be691f3bSpatrickfrom lldbsuite.test_event import build_exception
11be691f3bSpatrick
12be691f3bSpatrick
13be691f3bSpatrickclass Builder:
14be691f3bSpatrick    def getArchitecture(self):
15be691f3bSpatrick        """Returns the architecture in effect the test suite is running with."""
16be691f3bSpatrick        return configuration.arch if configuration.arch else ""
17be691f3bSpatrick
18be691f3bSpatrick    def getCompiler(self):
19be691f3bSpatrick        """Returns the compiler in effect the test suite is running with."""
20be691f3bSpatrick        compiler = configuration.compiler if configuration.compiler else "clang"
21be691f3bSpatrick        compiler = lldbutil.which(compiler)
22be691f3bSpatrick        return os.path.abspath(compiler)
23be691f3bSpatrick
24*f6aab3d8Srobert    def getTriple(self, arch):
25*f6aab3d8Srobert        """Returns the triple for the given architecture or None."""
26*f6aab3d8Srobert        return None
27*f6aab3d8Srobert
28be691f3bSpatrick    def getExtraMakeArgs(self):
29be691f3bSpatrick        """
30be691f3bSpatrick        Helper function to return extra argumentsfor the make system. This
31be691f3bSpatrick        method is meant to be overridden by platform specific builders.
32be691f3bSpatrick        """
33*f6aab3d8Srobert        return []
34be691f3bSpatrick
35be691f3bSpatrick    def getArchCFlags(self, architecture):
36be691f3bSpatrick        """Returns the ARCH_CFLAGS for the make system."""
37*f6aab3d8Srobert        return []
38be691f3bSpatrick
39be691f3bSpatrick    def getMake(self, test_subdir, test_name):
40be691f3bSpatrick        """Returns the invocation for GNU make.
41be691f3bSpatrick        The first argument is a tuple of the relative path to the testcase
42be691f3bSpatrick        and its filename stem."""
43be691f3bSpatrick        if platform.system() == "FreeBSD" or platform.system() == "NetBSD":
44be691f3bSpatrick            make = "gmake"
45be691f3bSpatrick        else:
46be691f3bSpatrick            make = "make"
47be691f3bSpatrick
48be691f3bSpatrick        # Construct the base make invocation.
49be691f3bSpatrick        lldb_test = os.environ["LLDB_TEST"]
50be691f3bSpatrick        if not (lldb_test and configuration.test_build_dir and test_subdir
51be691f3bSpatrick                and test_name and (not os.path.isabs(test_subdir))):
52be691f3bSpatrick            raise Exception("Could not derive test directories")
53be691f3bSpatrick        build_dir = os.path.join(configuration.test_build_dir, test_subdir,
54be691f3bSpatrick                                 test_name)
55be691f3bSpatrick        src_dir = os.path.join(configuration.test_src_root, test_subdir)
56be691f3bSpatrick        # This is a bit of a hack to make inline testcases work.
57be691f3bSpatrick        makefile = os.path.join(src_dir, "Makefile")
58be691f3bSpatrick        if not os.path.isfile(makefile):
59be691f3bSpatrick            makefile = os.path.join(build_dir, "Makefile")
60be691f3bSpatrick        return [
61be691f3bSpatrick            make, "VPATH=" + src_dir, "-C", build_dir, "-I", src_dir, "-I",
62be691f3bSpatrick            os.path.join(lldb_test, "make"), "-f", makefile
63be691f3bSpatrick        ]
64be691f3bSpatrick
65be691f3bSpatrick    def getCmdLine(self, d):
66be691f3bSpatrick        """
67*f6aab3d8Srobert        Helper function to return a command line argument string used for the
68*f6aab3d8Srobert        make system.
69be691f3bSpatrick        """
70be691f3bSpatrick
71*f6aab3d8Srobert        # If d is None or an empty mapping, just return an empty list.
72be691f3bSpatrick        if not d:
73*f6aab3d8Srobert            return []
74be691f3bSpatrick
75be691f3bSpatrick        def setOrAppendVariable(k, v):
76be691f3bSpatrick            append_vars = ["CFLAGS", "CFLAGS_EXTRAS", "LD_EXTRAS"]
77be691f3bSpatrick            if k in append_vars and k in os.environ:
78be691f3bSpatrick                v = os.environ[k] + " " + v
79*f6aab3d8Srobert            return '%s=%s' % (k, v)
80be691f3bSpatrick
81*f6aab3d8Srobert        cmdline = [setOrAppendVariable(k, v) for k, v in list(d.items())]
82be691f3bSpatrick
83be691f3bSpatrick        return cmdline
84be691f3bSpatrick
85be691f3bSpatrick    def getArchSpec(self, architecture):
86be691f3bSpatrick        """
87be691f3bSpatrick        Helper function to return the key-value string to specify the architecture
88be691f3bSpatrick        used for the make system.
89be691f3bSpatrick        """
90*f6aab3d8Srobert        return ["ARCH=" + architecture] if architecture else []
91be691f3bSpatrick
92be691f3bSpatrick    def getCCSpec(self, compiler):
93be691f3bSpatrick        """
94be691f3bSpatrick        Helper function to return the key-value string to specify the compiler
95be691f3bSpatrick        used for the make system.
96be691f3bSpatrick        """
97be691f3bSpatrick        cc = compiler if compiler else None
98be691f3bSpatrick        if not cc and configuration.compiler:
99be691f3bSpatrick            cc = configuration.compiler
100be691f3bSpatrick        if cc:
101*f6aab3d8Srobert            return ["CC=\"%s\"" % cc]
102*f6aab3d8Srobert        return []
103be691f3bSpatrick
104be691f3bSpatrick    def getSDKRootSpec(self):
105be691f3bSpatrick        """
106be691f3bSpatrick        Helper function to return the key-value string to specify the SDK root
107be691f3bSpatrick        used for the make system.
108be691f3bSpatrick        """
109be691f3bSpatrick        if configuration.sdkroot:
110*f6aab3d8Srobert            return ["SDKROOT={}".format(configuration.sdkroot)]
111*f6aab3d8Srobert        return []
112be691f3bSpatrick
113be691f3bSpatrick    def getModuleCacheSpec(self):
114be691f3bSpatrick        """
115be691f3bSpatrick        Helper function to return the key-value string to specify the clang
116be691f3bSpatrick        module cache used for the make system.
117be691f3bSpatrick        """
118be691f3bSpatrick        if configuration.clang_module_cache_dir:
119*f6aab3d8Srobert            return ["CLANG_MODULE_CACHE_DIR={}".format(
120*f6aab3d8Srobert                configuration.clang_module_cache_dir)]
121*f6aab3d8Srobert        return []
122be691f3bSpatrick
123*f6aab3d8Srobert    def getLibCxxArgs(self):
124*f6aab3d8Srobert        if configuration.libcxx_include_dir and configuration.libcxx_library_dir:
125*f6aab3d8Srobert            libcpp_args = ["LIBCPP_INCLUDE_DIR={}".format(configuration.libcxx_include_dir),
126*f6aab3d8Srobert                           "LIBCPP_LIBRARY_DIR={}".format(configuration.libcxx_library_dir)]
127*f6aab3d8Srobert            if configuration.libcxx_include_target_dir:
128*f6aab3d8Srobert                libcpp_args.append("LIBCPP_INCLUDE_TARGET_DIR={}".format(
129*f6aab3d8Srobert                    configuration.libcxx_include_target_dir))
130*f6aab3d8Srobert            return libcpp_args
131*f6aab3d8Srobert        return []
132be691f3bSpatrick
133*f6aab3d8Srobert    def _getDebugInfoArgs(self, debug_info):
134*f6aab3d8Srobert        if debug_info is None:
135*f6aab3d8Srobert            return []
136*f6aab3d8Srobert        if debug_info == "dwarf":
137*f6aab3d8Srobert            return ["MAKE_DSYM=NO"]
138*f6aab3d8Srobert        if debug_info == "dwo":
139*f6aab3d8Srobert            return ["MAKE_DSYM=NO", "MAKE_DWO=YES"]
140*f6aab3d8Srobert        if debug_info == "gmodules":
141*f6aab3d8Srobert            return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"]
142*f6aab3d8Srobert        return None
143be691f3bSpatrick
144*f6aab3d8Srobert    def getBuildCommand(self, debug_info, architecture=None, compiler=None,
145*f6aab3d8Srobert            dictionary=None, testdir=None, testname=None, make_targets=None):
146*f6aab3d8Srobert        debug_info_args = self._getDebugInfoArgs(debug_info)
147*f6aab3d8Srobert        if debug_info_args is None:
148*f6aab3d8Srobert            return None
149*f6aab3d8Srobert        if make_targets is None:
150*f6aab3d8Srobert            make_targets = ["all"]
151*f6aab3d8Srobert        command_parts = [
152*f6aab3d8Srobert            self.getMake(testdir, testname), debug_info_args, make_targets,
153*f6aab3d8Srobert            self.getArchCFlags(architecture), self.getArchSpec(architecture),
154*f6aab3d8Srobert            self.getCCSpec(compiler), self.getExtraMakeArgs(),
155*f6aab3d8Srobert            self.getSDKRootSpec(), self.getModuleCacheSpec(),
156*f6aab3d8Srobert            self.getLibCxxArgs(), self.getCmdLine(dictionary)]
157*f6aab3d8Srobert        command = list(itertools.chain(*command_parts))
158be691f3bSpatrick
159*f6aab3d8Srobert        return command
160be691f3bSpatrick
161*f6aab3d8Srobert    def cleanup(self, dictionary=None):
162be691f3bSpatrick        """Perform a platform-specific cleanup after the test."""
163be691f3bSpatrick        return True
164