Hadrian's `lookupInPath` looks beyond `$PATH` variable on Windows
Summary
Hadrian's use of System.Directory.findExecutable
leads to non-hermetic builds on Windows.
Steps to reproduce
Hadrian's lookupInPath
oracle is currently implemented via System.Directory.findExecutable
:
void $ addOracleCache $ \(LookupInPath name) -> do
let unpack = fromMaybe . error $ "Cannot find executable " ++ quote name
path <- unifyPath . unpack <$> liftIO (findExecutable name)
putLoud $ "| Executable found: " ++ name ++ " => " ++ path
return path
Note the haddock for findDirectory
. It has special behavior on Windows, where it will query the "SearchPath". That path will include C:/Windows/System32/
.
Why is that a problem? Well, in order to debug !4833 (closed), I needed to build GHC on my local Windows machine. I started from a clean slate my nuking my msys2 install. I followed all the rules from https://gitlab.haskell.org/ghc/ghc/-/wikis/building/preparation/windows (and fixed a few bitrotting bugs). Then, after a successful boot and configure (with autotarballs-download), I started the GHC build via hadrian, which failed while configuring gmp: "m4
: Command not found". Why?
It turns out that because I also have WSL installed, the lookup of bashPath
in hadrian would find C:/Windows/System32/bash.exe
and run configure in the environment of the WSL's bash! Chaos.
Proposal
Don't use findExecutable
, or somehow tell it not to meddle outside $PATH
.
Environment
- GHC version used: 8.10.2
- Operating System: Windows