diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py --- a/llvm/utils/lit/lit/run.py +++ b/llvm/utils/lit/lit/run.py @@ -1,5 +1,8 @@ +import itertools import multiprocessing import os +import pathlib +import shutil import time import lit.Test @@ -55,6 +58,28 @@ deadline = time.time() + timeout try: + # On Windows, copy the required DLLs from PATH into the test directory + # This avoids the loader finding DLLs in C:\Windows\System32 + if self.lit_config.isWindows: + def outputPath(path): + # this handles both the unit test C:\...\TestCases\Windows\foo.cpp, + # and also the regular test C:\...\X86_64WindowsDynamicConfig\Asan-x86_64-inline-Dynamic-Test.exe\16\18 + path = pathlib.Path(path) + parent = path.parent + while path.suffix == '': + path, parent = parent, parent.parent + assert(path != path.parent) + return parent / 'Output' + outputDirectories = {outputPath(test.getExecPath()) for test in self.tests} + toolsetDirectory = pathlib.Path(lit.util.which("cl.exe")).parent + for outputDirectory in outputDirectories: + lit.util.mkdir_p(outputDirectory) + for dllToCopy in itertools.chain(\ + toolsetDirectory.glob('msvcp*.dll'),\ + toolsetDirectory.glob('vcruntime*.dll'),\ + toolsetDirectory.glob('ucrtbase*.dll')): + shutil.copyfile(dllToCopy, outputDirectory / dllToCopy.name) + self._execute(deadline) finally: skipped = lit.Test.Result(lit.Test.SKIPPED) diff --git a/llvm/utils/lit/lit/util.py b/llvm/utils/lit/lit/util.py --- a/llvm/utils/lit/lit/util.py +++ b/llvm/utils/lit/lit/util.py @@ -241,10 +241,10 @@ # Get suffixes to search. # On Cygwin, 'PATHEXT' may exist but it should not be used. - if os.pathsep == ";": - pathext = os.environ.get("PATHEXT", "").split(";") + if os.path.splitext(command)[-1] != '' or os.pathsep != ';': + pathext = [''] else: - pathext = [""] + pathext = os.environ.get('PATHEXT', '').split(';') # Search the paths... for path in paths.split(os.pathsep):