diff --git a/lldb/packages/Python/lldbsuite/builders/__init__.py b/lldb/packages/Python/lldbsuite/builders/__init__.py new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/builders/__init__.py @@ -0,0 +1,16 @@ +""" +This module builds test binaries for the test suite using Make. + +Platform specific builders can override methods in the Builder base class. The +factory method below hands out builders based on the given platform. +""" + +from .builder import Builder + + +def get_builder(platform): + """Returns a Builder instance for the given platform.""" + if platform == 'darwin': + from .darwin import BuilderDarwin + return BuilderDarwin() + return Builder() diff --git a/lldb/packages/Python/lldbsuite/builders/builder.py b/lldb/packages/Python/lldbsuite/builders/builder.py new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/builders/builder.py @@ -0,0 +1,240 @@ +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 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. + """ + arch = architecture if architecture else None + if not arch and configuration.arch: + arch = configuration.arch + + return ("ARCH=" + arch) if arch 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 getDsymutilSpec(self): + """ + Helper function to return the key-value string to specify the dsymutil + used for the make system. + """ + if configuration.dsymutil: + return "DSYMUTIL={}".format(configuration.dsymutil) + 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.getArchSpec(architecture), + self.getCCSpec(compiler), + self.getDsymutilSpec(), + 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.getArchSpec(architecture), + self.getCCSpec(compiler), + self.getDsymutilSpec(), + 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.getArchSpec(architecture), + self.getCCSpec(compiler), + self.getDsymutilSpec(), + 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.getArchSpec(architecture), + self.getCCSpec(compiler), + self.getDsymutilSpec(), + 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): + # 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 diff --git a/lldb/packages/Python/lldbsuite/builders/darwin.py b/lldb/packages/Python/lldbsuite/builders/darwin.py new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/builders/darwin.py @@ -0,0 +1,28 @@ +from .builder import Builder + + +class BuilderDarwin(Builder): + def buildDsym(self, + sender=None, + architecture=None, + compiler=None, + dictionary=None, + testdir=None, + testname=None): + """Build the binaries with dsym debug info.""" + commands = [] + commands.append( + self.getMake(testdir, testname) + [ + "MAKE_DSYM=YES", + self.getArchSpec(architecture), + self.getCCSpec(compiler), + self.getDsymutilSpec(), + self.getSDKRootSpec(), + self.getModuleCacheSpec(), "all", + self.getCmdLine(dictionary) + ]) + + self.runBuildCommands(commands, sender=sender) + + # True signifies that we can handle building dsym. + return True diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -65,6 +65,7 @@ from . import lldbtest_config from . import lldbutil from . import test_categories +from lldbsuite.builders import get_builder from lldbsuite.support import encoded_file from lldbsuite.support import funcutils @@ -532,17 +533,7 @@ def builder_module(): - if sys.platform.startswith("freebsd"): - return __import__("builder_freebsd") - if sys.platform.startswith("openbsd"): - return __import__("builder_openbsd") - if sys.platform.startswith("netbsd"): - return __import__("builder_netbsd") - if sys.platform.startswith("linux"): - # sys.platform with Python-3.x returns 'linux', but with - # Python-2.x it returns 'linux2'. - return __import__("builder_linux") - return __import__("builder_" + sys.platform) + return get_builder(sys.platform) class Base(unittest2.TestCase): @@ -1891,7 +1882,7 @@ - The build methods buildDefault, buildDsym, and buildDwarf are used to build the binaries used during a particular test scenario. A plugin should be provided for the sys.platform running the test suite. The - Mac OS X implementation is located in plugins/darwin.py. + Mac OS X implementation is located in builders/darwin.py. """ # Subclasses can set this to true (if they don't depend on debug info) to avoid running the diff --git a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules --- a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules +++ b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules @@ -172,7 +172,7 @@ # CC defaults to clang. # # If you change the defaults of CC, be sure to also change it in the file -# test/plugins/builder_base.py, which provides a Python way to return the +# test/builders/builder_base.py, which provides a Python way to return the # value of the make variable CC -- getCompiler(). # # See also these functions: diff --git a/lldb/packages/Python/lldbsuite/test/plugins/builder_base.py b/lldb/packages/Python/lldbsuite/test/plugins/builder_base.py deleted file mode 100644 --- a/lldb/packages/Python/lldbsuite/test/plugins/builder_base.py +++ /dev/null @@ -1,249 +0,0 @@ -""" -If the build* function is passed the compiler argument, for example, 'llvm-gcc', -it is passed as a make variable to the make command. Otherwise, we check the -LLDB_CC environment variable; if it is defined, it is passed as a make variable -to the make command. - -If neither the compiler keyword argument nor the LLDB_CC environment variable is -specified, no CC make variable is passed to the make command. The Makefile gets -to define the default CC being used. - -Same idea holds for LLDB_ARCH environment variable, which maps to the ARCH make -variable. -""" - -# System imports -import os -import platform -import subprocess -import sys - -# Our imports -import lldbsuite.test.lldbtest as lldbtest -import lldbsuite.test.lldbutil as lldbutil -from lldbsuite.test import configuration -from lldbsuite.test_event import build_exception - - -def getArchitecture(): - """Returns the architecture in effect the test suite is running with.""" - return configuration.arch if configuration.arch else "" - - -def getCompiler(): - """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 getMake(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 getArchSpec(architecture): - """ - Helper function to return the key-value string to specify the architecture - used for the make system. - """ - arch = architecture if architecture else None - if not arch and configuration.arch: - arch = configuration.arch - - return ("ARCH=" + arch) if arch else "" - - -def getCCSpec(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 getDsymutilSpec(): - """ - Helper function to return the key-value string to specify the dsymutil - used for the make system. - """ - if configuration.dsymutil: - return "DSYMUTIL={}".format(configuration.dsymutil) - return "" - -def getSDKRootSpec(): - """ - 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(): - """ - 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 getCmdLine(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(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 buildDefault( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None, - testname=None): - """Build the binaries the default way.""" - commands = [] - commands.append(getMake(testdir, testname) + - ["all", - getArchSpec(architecture), - getCCSpec(compiler), - getDsymutilSpec(), - getSDKRootSpec(), - getModuleCacheSpec(), - getCmdLine(dictionary)]) - - runBuildCommands(commands, sender=sender) - - # True signifies that we can handle building default. - return True - - -def buildDwarf( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None, - testname=None): - """Build the binaries with dwarf debug info.""" - commands = [] - commands.append(getMake(testdir, testname) + - ["MAKE_DSYM=NO", - getArchSpec(architecture), - getCCSpec(compiler), - getDsymutilSpec(), - getSDKRootSpec(), - getModuleCacheSpec(), - getCmdLine(dictionary)]) - - runBuildCommands(commands, sender=sender) - # True signifies that we can handle building dwarf. - return True - - -def buildDwo( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None, - testname=None): - """Build the binaries with dwarf debug info.""" - commands = [] - commands.append(getMake(testdir, testname) + - ["MAKE_DSYM=NO", - "MAKE_DWO=YES", - getArchSpec(architecture), - getCCSpec(compiler), - getDsymutilSpec(), - getSDKRootSpec(), - getModuleCacheSpec(), - getCmdLine(dictionary)]) - - runBuildCommands(commands, sender=sender) - # True signifies that we can handle building dwo. - return True - - -def buildGModules( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None, - testname=None): - """Build the binaries with dwarf debug info.""" - commands = [] - commands.append(getMake(testdir, testname) + - ["MAKE_DSYM=NO", - "MAKE_GMODULES=YES", - getArchSpec(architecture), - getCCSpec(compiler), - getDsymutilSpec(), - getSDKRootSpec(), - getModuleCacheSpec(), - getCmdLine(dictionary)]) - - runBuildCommands(commands, sender=sender) - # True signifies that we can handle building with gmodules. - return True - - -def cleanup(sender=None, dictionary=None): - """Perform a platform-specific cleanup after the test.""" - return True diff --git a/lldb/packages/Python/lldbsuite/test/plugins/builder_darwin.py b/lldb/packages/Python/lldbsuite/test/plugins/builder_darwin.py deleted file mode 100644 --- a/lldb/packages/Python/lldbsuite/test/plugins/builder_darwin.py +++ /dev/null @@ -1,28 +0,0 @@ - -import lldbsuite.test.lldbtest as lldbtest - -from builder_base import * - -def buildDsym( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None, - testname=None): - """Build the binaries with dsym debug info.""" - commands = [] - commands.append(getMake(testdir, testname) + - ["MAKE_DSYM=YES", - getArchSpec(architecture), - getCCSpec(compiler), - getDsymutilSpec(), - getSDKRootSpec(), - getModuleCacheSpec(), - "all", - getCmdLine(dictionary)]) - - runBuildCommands(commands, sender=sender) - - # True signifies that we can handle building dsym. - return True diff --git a/lldb/packages/Python/lldbsuite/test/plugins/builder_freebsd.py b/lldb/packages/Python/lldbsuite/test/plugins/builder_freebsd.py deleted file mode 100644 --- a/lldb/packages/Python/lldbsuite/test/plugins/builder_freebsd.py +++ /dev/null @@ -1,10 +0,0 @@ -from builder_base import * - - -def buildDsym( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None): - return False diff --git a/lldb/packages/Python/lldbsuite/test/plugins/builder_linux.py b/lldb/packages/Python/lldbsuite/test/plugins/builder_linux.py deleted file mode 100644 --- a/lldb/packages/Python/lldbsuite/test/plugins/builder_linux.py +++ /dev/null @@ -1,10 +0,0 @@ -from builder_base import * - - -def buildDsym( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None): - return False diff --git a/lldb/packages/Python/lldbsuite/test/plugins/builder_netbsd.py b/lldb/packages/Python/lldbsuite/test/plugins/builder_netbsd.py deleted file mode 100644 --- a/lldb/packages/Python/lldbsuite/test/plugins/builder_netbsd.py +++ /dev/null @@ -1,10 +0,0 @@ -from builder_base import * - - -def buildDsym( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None): - return False diff --git a/lldb/packages/Python/lldbsuite/test/plugins/builder_openbsd.py b/lldb/packages/Python/lldbsuite/test/plugins/builder_openbsd.py deleted file mode 100644 --- a/lldb/packages/Python/lldbsuite/test/plugins/builder_openbsd.py +++ /dev/null @@ -1,10 +0,0 @@ -from builder_base import * - - -def buildDsym( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None): - return False diff --git a/lldb/packages/Python/lldbsuite/test/plugins/builder_win32.py b/lldb/packages/Python/lldbsuite/test/plugins/builder_win32.py deleted file mode 100644 --- a/lldb/packages/Python/lldbsuite/test/plugins/builder_win32.py +++ /dev/null @@ -1,10 +0,0 @@ -from builder_base import * - - -def buildDsym( - sender=None, - architecture=None, - compiler=None, - dictionary=None, - testdir=None): - return False