cabal icon indicating copy to clipboard operation
cabal copied to clipboard

Do not pass environment variables to `happy`/`alex`, or at least allow a way to filter

Open sgraf812 opened this issue 1 year ago • 2 comments

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

sgraf812 avatar Jun 06 '24 14:06 sgraf812

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.

mpickering avatar Jun 10 '24 08:06 mpickering

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.

sgraf812 avatar Jun 10 '24 16:06 sgraf812

I've just faced a similar issue:

  1. The package I want to build has build-tool-depends: happy:happy >= 1.20.0
  2. I have happy 2.0.2 globally installed (/usr/bin/happy)
  3. For some reason Cabal puts happy 2.1.3 in the build plan
  4. My globally installed happy 2.0.2 is called with the environment variable happy_lib_datadir set to /path/to/happy-lib-2.1.3/data, hence it uses the wrong HappyTemplate.hs and the generated code doesn't compile.

(This is with cabal HEAD 3.15 and with cabal 3.14.1)

hsyl20 avatar Dec 03 '24 08:12 hsyl20