Do not pass environment variables to `happy`/`alex`, or at least allow a way to filter
Describe the bug
happy uses template files that need to be distributed with its executable, hence it uses the data-files field(?). This causes troubles during bootstrapping, which I will explain now. I have also attached a more minimal reproducer below, but the use case is important as well.
In https://github.com/haskell/happy/issues/262 and https://github.com/haskell/happy/issues/274 we have trouble bootstrapping happy-2. That is because while building happy-2 with cabal, the $happy_datadir environment variable is set to point to somewhere in the working directory (I have no idea why that is necessary). But the bootstrapping process (for package happy-tabular) runs a preinstalled happy-1.20 to compile happy's own grammar file. This run reads the $happy_datadir variable and consequently looks for its template file in the wrong location, leading to abrupt error.
To Reproduce Steps to reproduce the behavior:
(Files as a zip instead of heredoc)
$ cat << EOF > datadir-error.cabal
name: datadir-error
version: 0.1.0.0
build-type: Simple
library
exposed-modules: Parser
hs-source-dirs: .
EOF
$ cat << EOF > Parser.y
{
module Parser where
}
%name foo
%%
foo : { }
$ happy_datadir=. cabal build
Resolving dependencies...
Build profile: -w ghc-9.4.8 -O1
In order, the following will be built (use -v for more details):
- datadir-error-0.1.0.0 (lib:datadir-error) (first run)
Warning: datadir-error.cabal:0:0: A package using section syntax must specify
at least
'cabal-version: >= 1.2'.
Configuring datadir-error-0.1.0.0...
Preprocessing library for datadir-error-0.1.0.0..
happy: ./HappyTemplate-arrays-coerce: openFile: does not exist (No such file or directory)
Error: cabal: Failed to build datadir-error-0.1.0.0.
Expected behavior
Produce a Parser.hs file, try to build it, despite me setting an invalid environment variable for happy.
System information
- Ubuntu 22.04
- Cabal 3.10.2.1, GHC 9.4.8
These variables are used by the Paths module in order to determine where the data files are.
bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
bindir = "/home/matt/.cabal/bin"
libdir = "/home/matt/.cabal/lib/x86_64-linux-ghc-9.6.2/Cabal-3.11.0.0-inplace"
dynlibdir = "/home/matt/.cabal/lib/x86_64-linux-ghc-9.6.2"
datadir = "/home/matt/.cabal/share/x86_64-linux-ghc-9.6.2/Cabal-3.11.0.0"
libexecdir = "/home/matt/.cabal/libexec/x86_64-linux-ghc-9.6.2/Cabal-3.11.0.0"
sysconfdir = "/home/matt/.cabal/etc"
getBinDir = catchIO (getEnv "Cabal_bindir") (\_ -> return bindir)
getLibDir = catchIO (getEnv "Cabal_libdir") (\_ -> return libdir)
getDynLibDir = catchIO (getEnv "Cabal_dynlibdir") (\_ -> return dynlibdir)
getDataDir = catchIO (getEnv "Cabal_datadir") (\_ -> return datadir)
getLibexecDir = catchIO (getEnv "Cabal_libexecdir") (\_ -> return libexecdir)
getSysconfDir = catchIO (getEnv "Cabal_sysconfdir") (\_ -> return sysconfdir)
I'm not following the exact bootstrapping issue you are having. The solution here is probably to implement your own logic for finding data files rather than relying on getDataDir from Paths_happy.
Do note that the build succeeds when I omit happy_datadir=.. The point is that if I provide it, cabal should not forward it to happy; if I want to set some environment variables for the build tool happy, then I should do so through some kind of configuration flag (--happy-env or something similar).
I'm honestly having a hard time seeing how we could work around this issue in happy, because happy_datadir=. is set automatically by cabal-install, simply because happy-2 uses data-files in its build. If this can't be solved in Cabal, then the happy build should not be bootstrapped by default.
I've just faced a similar issue:
- The package I want to build has
build-tool-depends: happy:happy >= 1.20.0 - I have
happy 2.0.2globally installed (/usr/bin/happy) - For some reason Cabal puts
happy 2.1.3in the build plan - My globally installed
happy 2.0.2is called with the environment variablehappy_lib_datadirset to/path/to/happy-lib-2.1.3/data, hence it uses the wrongHappyTemplate.hsand the generated code doesn't compile.
(This is with cabal HEAD 3.15 and with cabal 3.14.1)