aprantl created this revision. This patch is the result of a discussion on lldb-dev, see http://lists.llvm.org/pipermail/lldb-dev/2018-January/013111.html for background.
This is a first sketch of how to move building of the testcases in the LLDB testsuite out of the source tree. The patch is buggy and incomplete, but I would like to develop this as much in the open as possible to solicit early feedback in case I'm unwittingly cutting any corners that will break somebody's platform. For each test (should be eventually: each test configuration) a separate build directory is created and we execute `make VPATH=$srcdir/path/to/test -C $builddir/path/to/test -f $srcdir/path/to/test/Makefile -I $srcdir/path/to/test`. In order to make this work all LLDB tests need to be updated to find the executable in the test build directory, since CWD still points at the test's source directory, which is a requirement for unittest2. That patch is very boring and therefore outsourced to https://reviews.llvm.org/D42280 to make this review easier to read. https://reviews.llvm.org/D42281 Files: packages/Python/lldbsuite/test/configuration.py packages/Python/lldbsuite/test/dotest.py packages/Python/lldbsuite/test/dotest_args.py packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py packages/Python/lldbsuite/test/lldbtest.py packages/Python/lldbsuite/test/plugins/builder_base.py
Index: packages/Python/lldbsuite/test/plugins/builder_base.py =================================================================== --- packages/Python/lldbsuite/test/plugins/builder_base.py +++ packages/Python/lldbsuite/test/plugins/builder_base.py @@ -50,13 +50,23 @@ return ("ARCHFLAG=" + archflag) if archflag else "" - -def getMake(): - """Returns the name for GNU make""" +def getMake(rel_testdir): + """Returns the invocation for GNU make""" if platform.system() == "FreeBSD" or platform.system() == "NetBSD": - return "gmake" + make = "gmake" else: - return "make" + make = "make" + + # Construct the base make invocation. + lldb_test = os.environ["LLDB_TEST"] + lldb_build = os.environ["LLDB_BUILD"] + build_dir = os.path.join(lldb_build, rel_testdir) + test_dir = os.path.join(lldb_test, rel_testdir) + return [make, + "VPATH="+test_dir, + "-C", build_dir, + "-I", test_dir, + "-f", os.path.join(test_dir, "Makefile")] def getArchSpec(architecture): @@ -121,12 +131,13 @@ architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Build the binaries the default way.""" commands = [] if clean: - commands.append([getMake(), "clean", getCmdLine(dictionary)]) - commands.append([getMake(), getArchSpec(architecture), + commands.append(getMake(testdir) + ["clean", getCmdLine(dictionary)]) + commands.append(getMake(testdir) + [getArchSpec(architecture), getCCSpec(compiler), getCmdLine(dictionary)]) runBuildCommands(commands, sender=sender) @@ -140,12 +151,13 @@ architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Build the binaries with dwarf debug info.""" commands = [] if clean: - commands.append([getMake(), "clean", getCmdLine(dictionary)]) - commands.append([getMake(), "MAKE_DSYM=NO", getArchSpec( + commands.append(getMake(testdir) + ["clean", getCmdLine(dictionary)]) + commands.append(getMake(testdir) + ["MAKE_DSYM=NO", getArchSpec( architecture), getCCSpec(compiler), getCmdLine(dictionary)]) runBuildCommands(commands, sender=sender) @@ -158,13 +170,17 @@ architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Build the binaries with dwarf debug info.""" commands = [] if clean: - commands.append([getMake(), "clean", getCmdLine(dictionary)]) - commands.append([getMake(), "MAKE_DSYM=NO", "MAKE_DWO=YES", getArchSpec( - architecture), getCCSpec(compiler), getCmdLine(dictionary)]) + commands.append(getMake(testdir) + ["clean", getCmdLine(dictionary)]) + commands.append(getMake(testdir) + + ["MAKE_DSYM=NO", "MAKE_DWO=YES", + getArchSpec(architecture), + getCCSpec(compiler), + getCmdLine(dictionary)]) runBuildCommands(commands, sender=sender) # True signifies that we can handle building dwo. @@ -176,12 +192,13 @@ architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Build the binaries with dwarf debug info.""" commands = [] if clean: - commands.append([getMake(), "clean", getCmdLine(dictionary)]) - commands.append([getMake(), + commands.append(getMake(testdir) + ["clean", getCmdLine(dictionary)]) + commands.append([getMake(testdir), "MAKE_DSYM=NO", "MAKE_GMODULES=YES", getArchSpec(architecture), @@ -195,12 +212,13 @@ def cleanup(sender=None, dictionary=None): """Perform a platform-specific cleanup after the test.""" - #import traceback - # traceback.print_stack() - commands = [] - if os.path.isfile("Makefile"): - commands.append([getMake(), "clean", getCmdLine(dictionary)]) - - runBuildCommands(commands, sender=sender) - # True signifies that we can handle cleanup. return True + # #import traceback + # # traceback.print_stack() + # commands = [] + # if os.path.isfile("Makefile"): + # commands.append(getMake("") + ["clean", getCmdLine(dictionary)]) + # + # runBuildCommands(commands, sender=sender) + # # True signifies that we can handle cleanup. + # return True Index: packages/Python/lldbsuite/test/lldbtest.py =================================================================== --- packages/Python/lldbsuite/test/lldbtest.py +++ packages/Python/lldbsuite/test/lldbtest.py @@ -553,6 +553,7 @@ print("Change dir to:", full_dir, file=sys.stderr) os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir)) + # TODO: Obsolete this by creating one working dir per configuration. if debug_confirm_directory_exclusivity: import lock cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock")) @@ -1490,84 +1491,69 @@ architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Platform specific way to build the default binaries.""" module = builder_module() dictionary = lldbplatformutil.finalize_build_dictionary(dictionary) - if not module.buildDefault( - self, - architecture, - compiler, - dictionary, - clean): + if not module.buildDefault(self, architecture, compiler, + dictionary, clean, testdir): raise Exception("Don't know how to build default binary") def buildDsym( self, architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Platform specific way to build binaries with dsym info.""" module = builder_module() dictionary = lldbplatformutil.finalize_build_dictionary(dictionary) - if not module.buildDsym( - self, - architecture, - compiler, - dictionary, - clean): + if not module.buildDsym(self, architecture, compiler, + dictionary, clean, testdir): raise Exception("Don't know how to build binary with dsym") def buildDwarf( self, architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Platform specific way to build binaries with dwarf maps.""" module = builder_module() dictionary = lldbplatformutil.finalize_build_dictionary(dictionary) - if not module.buildDwarf( - self, - architecture, - compiler, - dictionary, - clean): + if not module.buildDwarf(self, architecture, compiler, + dictionary, clean, testdir): raise Exception("Don't know how to build binary with dwarf") def buildDwo( self, architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Platform specific way to build binaries with dwarf maps.""" module = builder_module() dictionary = lldbplatformutil.finalize_build_dictionary(dictionary) - if not module.buildDwo( - self, - architecture, - compiler, - dictionary, - clean): + if not module.buildDwo(self, architecture, compiler, + dictionary, clean, testdir): raise Exception("Don't know how to build binary with dwo") def buildGModules( self, architecture=None, compiler=None, dictionary=None, - clean=True): + clean=True, + testdir=None): """Platform specific way to build binaries with gmodules info.""" module = builder_module() dictionary = lldbplatformutil.finalize_build_dictionary(dictionary) - if not module.buildGModules( - self, - architecture, - compiler, - dictionary, - clean): + if not module.buildGModules(self, architecture, compiler, + dictionary, clean, testdir): raise Exception("Don't know how to build binary with gmodules") def buildGo(self): @@ -2253,18 +2239,30 @@ clean=True): """Platform specific way to build the default binaries.""" module = builder_module() + + # Create the test-specific working directory if ${LLDB_BUILD} is defined. + # See also dotest.py which sets up ${LLDB_BUILD}. + if ("LLDB_BUILD" in os.environ): + full_dir = os.path.join(os.environ["LLDB_BUILD"], self.mydir) + try: os.makedirs(full_dir) + except: pass + dictionary = lldbplatformutil.finalize_build_dictionary(dictionary) if self.debug_info is None: - return self.buildDefault(architecture, compiler, dictionary, clean) + return self.buildDefault(architecture, compiler, dictionary, + clean, self.mydir) elif self.debug_info == "dsym": - return self.buildDsym(architecture, compiler, dictionary, clean) + return self.buildDsym(architecture, compiler, dictionary, + clean, self.mydir) elif self.debug_info == "dwarf": - return self.buildDwarf(architecture, compiler, dictionary, clean) + return self.buildDwarf(architecture, compiler, dictionary, + clean, self.mydir) elif self.debug_info == "dwo": - return self.buildDwo(architecture, compiler, dictionary, clean) + return self.buildDwo(architecture, compiler, dictionary, + clean, self.mydir) elif self.debug_info == "gmodules": - return self.buildGModules( - architecture, compiler, dictionary, clean) + return self.buildGModules(architecture, compiler, dictionary, + clean, self.mydir) else: self.fail("Can't build for debug info: %s" % self.debug_info) Index: packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py =================================================================== --- packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py +++ packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/TestStepNoDebug.py @@ -92,7 +92,7 @@ (name, pattern)) def get_to_starting_point(self): - exe = os.path.join(os.getcwd(), "a.out") + exe = os.path.join(os.environ["LLDB_BUILD"], self.mydir, "a.out") error = lldb.SBError() self.target = self.dbg.CreateTarget(exe) Index: packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile =================================================================== --- packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile +++ packages/Python/lldbsuite/test/functionalities/step-avoids-no-debug/Makefile @@ -5,4 +5,4 @@ include $(LEVEL)/Makefile.rules without-debug.o: without-debug.c - $(CC) $(CFLAGS_NO_DEBUG) -c without-debug.c + $(CC) $(CFLAGS_NO_DEBUG) -c $< Index: packages/Python/lldbsuite/test/dotest_args.py =================================================================== --- packages/Python/lldbsuite/test/dotest_args.py +++ packages/Python/lldbsuite/test/dotest_args.py @@ -159,6 +159,11 @@ metavar='Codesigning identity', default='lldb_codesign', help='The codesigning identity to use') + group.add_argument( + '--build-dir', + dest='test_build_dir', + metavar='Test build directory', + help='The root build directory for the tests') # Configuration options group = parser.add_argument_group('Remote platform options') Index: packages/Python/lldbsuite/test/dotest.py =================================================================== --- packages/Python/lldbsuite/test/dotest.py +++ packages/Python/lldbsuite/test/dotest.py @@ -472,6 +472,8 @@ configuration.lldb_platform_url = args.lldb_platform_url if args.lldb_platform_working_dir: configuration.lldb_platform_working_dir = args.lldb_platform_working_dir + if args.test_build_dir: + configuration.test_build_dir = args.test_build_dir if args.event_add_entries and len(args.event_add_entries) > 0: entries = {} @@ -620,6 +622,7 @@ sys.exit(-1) os.environ["LLDB_TEST"] = scriptPath + os.environ["LLDB_BUILD"] = configuration.test_build_dir # Set up the LLDB_SRC environment variable, so that the tests can locate # the LLDB source code. @@ -1185,6 +1188,15 @@ configuration.lldb_platform_working_dir = None configuration.lldb_platform_url = None + # Set up the working directory. + # Note that it's not dotest's job to clean this directory. + orig_working_dir = os.getcwd() + if configuration.test_build_dir: + try: os.makedirs(configuration.test_build_dir, 448) + except: pass + else: + configuration.test_build_dir = os.getcwd() + target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2] checkLibcxxSupport() Index: packages/Python/lldbsuite/test/configuration.py =================================================================== --- packages/Python/lldbsuite/test/configuration.py +++ packages/Python/lldbsuite/test/configuration.py @@ -141,6 +141,9 @@ lldb_platform_url = None lldb_platform_working_dir = None +# The base directory in which the tests are being built. +test_build_dir = None + # Parallel execution settings is_inferior_test_runner = False multiprocess_test_subdir = None
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits