244 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
| import os
 | |
| import platform
 | |
| import subprocess
 | |
| import sys
 | |
| 
 | |
| import lldbsuite.test.lldbtest as lldbtest
 | |
| import lldbsuite.test.lldbutil as lldbutil
 | |
| from lldbsuite.test import configuration
 | |
| from lldbsuite.test_event import build_exception
 | |
| 
 | |
| 
 | |
| class Builder:
 | |
|     def getArchitecture(self):
 | |
|         """Returns the architecture in effect the test suite is running with."""
 | |
|         return configuration.arch if configuration.arch else ""
 | |
| 
 | |
|     def getCompiler(self):
 | |
|         """Returns the compiler in effect the test suite is running with."""
 | |
|         compiler = configuration.compiler if configuration.compiler else "clang"
 | |
|         compiler = lldbutil.which(compiler)
 | |
|         return os.path.abspath(compiler)
 | |
| 
 | |
|     def getExtraMakeArgs(self):
 | |
|         """
 | |
|         Helper function to return extra argumentsfor the make system. This
 | |
|         method is meant to be overridden by platform specific builders.
 | |
|         """
 | |
|         return ""
 | |
| 
 | |
|     def getArchCFlags(self, architecture):
 | |
|         """Returns the ARCH_CFLAGS for the make system."""
 | |
|         return ""
 | |
| 
 | |
|     def getMake(self, test_subdir, test_name):
 | |
|         """Returns the invocation for GNU make.
 | |
|         The first argument is a tuple of the relative path to the testcase
 | |
|         and its filename stem."""
 | |
|         if platform.system() == "FreeBSD" or platform.system() == "NetBSD":
 | |
|             make = "gmake"
 | |
|         else:
 | |
|             make = "make"
 | |
| 
 | |
|         # Construct the base make invocation.
 | |
|         lldb_test = os.environ["LLDB_TEST"]
 | |
|         if not (lldb_test and configuration.test_build_dir and test_subdir
 | |
|                 and test_name and (not os.path.isabs(test_subdir))):
 | |
|             raise Exception("Could not derive test directories")
 | |
|         build_dir = os.path.join(configuration.test_build_dir, test_subdir,
 | |
|                                  test_name)
 | |
|         src_dir = os.path.join(configuration.test_src_root, test_subdir)
 | |
|         # This is a bit of a hack to make inline testcases work.
 | |
|         makefile = os.path.join(src_dir, "Makefile")
 | |
|         if not os.path.isfile(makefile):
 | |
|             makefile = os.path.join(build_dir, "Makefile")
 | |
|         return [
 | |
|             make, "VPATH=" + src_dir, "-C", build_dir, "-I", src_dir, "-I",
 | |
|             os.path.join(lldb_test, "make"), "-f", makefile
 | |
|         ]
 | |
| 
 | |
|     def getCmdLine(self, d):
 | |
|         """
 | |
|         Helper function to return a properly formatted command line argument(s)
 | |
|         string used for the make system.
 | |
|         """
 | |
| 
 | |
|         # If d is None or an empty mapping, just return an empty string.
 | |
|         if not d:
 | |
|             return ""
 | |
|         pattern = '%s="%s"' if "win32" in sys.platform else "%s='%s'"
 | |
| 
 | |
|         def setOrAppendVariable(k, v):
 | |
|             append_vars = ["CFLAGS", "CFLAGS_EXTRAS", "LD_EXTRAS"]
 | |
|             if k in append_vars and k in os.environ:
 | |
|                 v = os.environ[k] + " " + v
 | |
|             return pattern % (k, v)
 | |
| 
 | |
|         cmdline = " ".join(
 | |
|             [setOrAppendVariable(k, v) for k, v in list(d.items())])
 | |
| 
 | |
|         return cmdline
 | |
| 
 | |
|     def runBuildCommands(self, commands, sender):
 | |
|         try:
 | |
|             lldbtest.system(commands, sender=sender)
 | |
|         except subprocess.CalledProcessError as called_process_error:
 | |
|             # Convert to a build-specific error.
 | |
|             # We don't do that in lldbtest.system() since that
 | |
|             # is more general purpose.
 | |
|             raise build_exception.BuildError(called_process_error)
 | |
| 
 | |
|     def getArchSpec(self, architecture):
 | |
|         """
 | |
|         Helper function to return the key-value string to specify the architecture
 | |
|         used for the make system.
 | |
|         """
 | |
|         return ("ARCH=" + architecture) if architecture else ""
 | |
| 
 | |
|     def getCCSpec(self, compiler):
 | |
|         """
 | |
|         Helper function to return the key-value string to specify the compiler
 | |
|         used for the make system.
 | |
|         """
 | |
|         cc = compiler if compiler else None
 | |
|         if not cc and configuration.compiler:
 | |
|             cc = configuration.compiler
 | |
|         if cc:
 | |
|             return "CC=\"%s\"" % cc
 | |
|         else:
 | |
|             return ""
 | |
| 
 | |
|     def getSDKRootSpec(self):
 | |
|         """
 | |
|         Helper function to return the key-value string to specify the SDK root
 | |
|         used for the make system.
 | |
|         """
 | |
|         if configuration.sdkroot:
 | |
|             return "SDKROOT={}".format(configuration.sdkroot)
 | |
|         return ""
 | |
| 
 | |
|     def getModuleCacheSpec(self):
 | |
|         """
 | |
|         Helper function to return the key-value string to specify the clang
 | |
|         module cache used for the make system.
 | |
|         """
 | |
|         if configuration.clang_module_cache_dir:
 | |
|             return "CLANG_MODULE_CACHE_DIR={}".format(
 | |
|                 configuration.clang_module_cache_dir)
 | |
|         return ""
 | |
| 
 | |
|     def buildDefault(self,
 | |
|                      sender=None,
 | |
|                      architecture=None,
 | |
|                      compiler=None,
 | |
|                      dictionary=None,
 | |
|                      testdir=None,
 | |
|                      testname=None):
 | |
|         """Build the binaries the default way."""
 | |
|         commands = []
 | |
|         commands.append(
 | |
|             self.getMake(testdir, testname) + [
 | |
|                 "all",
 | |
|                 self.getArchCFlags(architecture),
 | |
|                 self.getArchSpec(architecture),
 | |
|                 self.getCCSpec(compiler),
 | |
|                 self.getExtraMakeArgs(),
 | |
|                 self.getSDKRootSpec(),
 | |
|                 self.getModuleCacheSpec(),
 | |
|                 self.getCmdLine(dictionary)
 | |
|             ])
 | |
| 
 | |
|         self.runBuildCommands(commands, sender=sender)
 | |
| 
 | |
|         # True signifies that we can handle building default.
 | |
|         return True
 | |
| 
 | |
|     def buildDwarf(self,
 | |
|                    sender=None,
 | |
|                    architecture=None,
 | |
|                    compiler=None,
 | |
|                    dictionary=None,
 | |
|                    testdir=None,
 | |
|                    testname=None):
 | |
|         """Build the binaries with dwarf debug info."""
 | |
|         commands = []
 | |
|         commands.append(
 | |
|             self.getMake(testdir, testname) + [
 | |
|                 "MAKE_DSYM=NO",
 | |
|                 self.getArchCFlags(architecture),
 | |
|                 self.getArchSpec(architecture),
 | |
|                 self.getCCSpec(compiler),
 | |
|                 self.getExtraMakeArgs(),
 | |
|                 self.getSDKRootSpec(),
 | |
|                 self.getModuleCacheSpec(),
 | |
|                 self.getCmdLine(dictionary)
 | |
|             ])
 | |
| 
 | |
|         self.runBuildCommands(commands, sender=sender)
 | |
|         # True signifies that we can handle building dwarf.
 | |
|         return True
 | |
| 
 | |
|     def buildDwo(self,
 | |
|                  sender=None,
 | |
|                  architecture=None,
 | |
|                  compiler=None,
 | |
|                  dictionary=None,
 | |
|                  testdir=None,
 | |
|                  testname=None):
 | |
|         """Build the binaries with dwarf debug info."""
 | |
|         commands = []
 | |
|         commands.append(
 | |
|             self.getMake(testdir, testname) + [
 | |
|                 "MAKE_DSYM=NO", "MAKE_DWO=YES",
 | |
|                 self.getArchCFlags(architecture),
 | |
|                 self.getArchSpec(architecture),
 | |
|                 self.getCCSpec(compiler),
 | |
|                 self.getExtraMakeArgs(),
 | |
|                 self.getSDKRootSpec(),
 | |
|                 self.getModuleCacheSpec(),
 | |
|                 self.getCmdLine(dictionary)
 | |
|             ])
 | |
| 
 | |
|         self.runBuildCommands(commands, sender=sender)
 | |
|         # True signifies that we can handle building dwo.
 | |
|         return True
 | |
| 
 | |
|     def buildGModules(self,
 | |
|                       sender=None,
 | |
|                       architecture=None,
 | |
|                       compiler=None,
 | |
|                       dictionary=None,
 | |
|                       testdir=None,
 | |
|                       testname=None):
 | |
|         """Build the binaries with dwarf debug info."""
 | |
|         commands = []
 | |
|         commands.append(
 | |
|             self.getMake(testdir, testname) + [
 | |
|                 "MAKE_DSYM=NO", "MAKE_GMODULES=YES",
 | |
|                 self.getArchCFlags(architecture),
 | |
|                 self.getArchSpec(architecture),
 | |
|                 self.getCCSpec(compiler),
 | |
|                 self.getExtraMakeArgs(),
 | |
|                 self.getSDKRootSpec(),
 | |
|                 self.getModuleCacheSpec(),
 | |
|                 self.getCmdLine(dictionary)
 | |
|             ])
 | |
| 
 | |
|         self.runBuildCommands(commands, sender=sender)
 | |
|         # True signifies that we can handle building with gmodules.
 | |
|         return True
 | |
| 
 | |
|     def buildDsym(self,
 | |
|                   sender=None,
 | |
|                   architecture=None,
 | |
|                   compiler=None,
 | |
|                   dictionary=None,
 | |
|                   testdir=None,
 | |
|                   testname=None):
 | |
|         # False signifies that we cannot handle building with dSYM.
 | |
|         return False
 | |
| 
 | |
|     def cleanup(self, sender=None, dictionary=None):
 | |
|         """Perform a platform-specific cleanup after the test."""
 | |
|         return True
 |