Skip to content

Commit

Permalink
[lit] Support running tests on Windows without GnuWin32.
Browse files Browse the repository at this point in the history
Historically, we have told contributors that GnuWin32 is a pre-requisite
because our tests depend on utilities such as sed, grep, diff, and more.
However, Git on Windows includes versions of these utilities in its
installation.  Furthermore, GnuWin32 has not been updated in many years.
For these reasons, it makes sense to have the ability to run llvm tests
in a way that is both:
  a) Easier on the user (less stuff to install)
  b) More up-to-date (The verions that ship with git are at least as
     new, if not newer, than the versions in GnuWin32.

We add support for this here by attempting to detect where Git is
installed using the Windows registry, confirming the existence of
several common Unix tools, and then adding this location to lit's PATH
environment.
  • Loading branch information
zturnerbx committed Aug 3, 2020
1 parent 21de4e7 commit dd18fa1
Showing 1 changed file with 39 additions and 7 deletions.
46 changes: 39 additions & 7 deletions llvm/utils/lit/lit/llvm/config.py
@@ -1,3 +1,4 @@
import itertools
import os
import platform
import re
Expand All @@ -20,13 +21,16 @@ def __init__(self, lit_config, config):
self.use_lit_shell = False
# Tweak PATH for Win32 to decide to use bash.exe or not.
if sys.platform == 'win32':
# For tests that require Windows to run.
features.add('system-windows')

# Seek sane tools in directories and set to $PATH.
path = self.lit_config.getToolsPath(config.lit_tools_dir,
config.environment['PATH'],
['cmp.exe', 'grep.exe', 'sed.exe'])
# Seek necessary tools in directories and set to $PATH.
path = None
lit_tools_dir = getattr(config, 'lit_tools_dir', None)
required_tools = ['cmp.exe', 'grep.exe', 'sed.exe', 'diff.exe', 'echo.exe']
if lit_tools_dir:
path = self.lit_config.getToolsPath(lit_tools_dir,
config.environment['PATH'],
required_tools)
if path is None:
path = self._find_git_windows_unix_tools(required_tools)
if path is not None:
self.with_environment('PATH', path, append_path=True)
# Many tools behave strangely if these environment variables aren't set.
Expand Down Expand Up @@ -115,6 +119,34 @@ def __init__(self, lit_config, config):
self.with_environment(
'DYLD_INSERT_LIBRARIES', gmalloc_path_str)

def _find_git_windows_unix_tools(self, tools_needed):
assert(sys.platform == 'win32')
if sys.version_info.major >= 3:
import winreg
else:
import _winreg as winreg

# Search both the 64-bit hives, as well as HKLM + HKCU
masks = [0, winreg.KEY_WOW64_64KEY]
hives = [winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE]
for mask, hive in itertools.product(masks, hives):
try:
with winreg.OpenKey(hive, r"SOFTWARE\GitForWindows", access=winreg.KEY_READ | mask) as key:
install_root, _ = winreg.QueryValueEx(key, 'InstallPath')

if not install_root:
continue
candidate_path = os.path.join(install_root, 'usr', 'bin')
if not lit.util.checkToolsPath(candidate_path, tools_needed):
continue

# We found it, stop enumerating.
return candidate_path
except:
continue

return None

def with_environment(self, variable, value, append_path=False):
if append_path:
# For paths, we should be able to take a list of them and process all
Expand Down

0 comments on commit dd18fa1

Please sign in to comment.