So far, the discussion around environment files in this thread has always been entangled with the idea of a "global state". GHC environment files (as written by `cabal install --lib`) are only global if they are placed in a directory where GHC will always look regardless of where GHC is currently running.

By default, `cabal install --lib PKG` will place the file in such a location (~/.ghc/x86_64-linux-9.4.7/environments/default in my particular setup), but one can use the `--package-env DIR` flag to change the directory to use. GHC will look in the current directory and its parent directories for environment files, hence the following works: (choosing `some` as an arbitrary light-weight non-boot package; the `cabal install` command prints little because I already have a compiled copy in my global store)

~$ mkdir experiments

~$ cd experiments

~/experiments$ cabal install --package-env . --lib some
Resolving dependencies...

~/experiments$ ghci
Loaded package environment from /home/tom/experiments/.ghc.environment.x86_64-linux-9.4.7
GHCi, version 9.4.7: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/tom/git/dotfiles/.ghci
Prelude> import Data.Some
Prelude Data.Some> :q
Leaving GHCi.

~/experiments$ cd ..

~$ rm -r experiments

Of course, normal GHC (i.e. not GHCi) will also work and pick up the environment file.

Using these "local" environment files allows one to create a local view of the global store that includes only a number of (presumably consistent) packages. Add to it by running `cabal install --package-env . --lib PKG` multiple times for different PKGs. No global state is modified, except potentially for compilation products of the libraries being installed -- but that is _append-only_ global state (the global cabal store), which is much less dangerous than general mutable global state.

Furthermore, as already noted indirectly by Oleg, GHC environment files are human-readable, if not very easily human-writable.

- Tom

On 10/07/2024 11:57, Hécate via ghc-devs wrote:
Reading this certainly motivates me to push for a better design of the respective boundaries of GHC and cabal. Removing magic from GHC that it uses to compensate for the absence of cabal or other build system would certainly help using it for simpler use-cases.

Le 10/07/2024 à 11:53, Oleg Grenrus a écrit :

On 10.7.2024 11.27, Simon Peyton Jones wrote:
I wonder if there is an articulate writeup of Cabal's mental model.

Sadly, i'm not aware of any. I'm also afraid, that Duncan's (who made initial v2-setup), Herbert's (who pushed v2 over the line) and mine models differ at least slightly.

The https://well-typed.com/blog/2015/01/how-we-might-abolish-cabal-hell-part-2/ is Duncan's view from 2015.

A side comment, we really should rename either the Cabal-the-library or cabal-install. Because I'm sure you are asking about mental model behind cabal-install v2-build, as "nothing" has changed in Cabal-the-library for a decade.

The idea is that cabal-install v2-build installs everything into single global store, and gives consistent views to that store. In practice the global store is unusable directly, as a whole it may not be consistent nor unambiguous (see e.g. https://gitlab.haskell.org/ghc/ghc/-/issues/24823 for funny side-effects of that, you may have dozens of installed units in the package db with the same package name and version).

e.g.  What is an environment file?

Essentially it's a set of `-package-db` and `-package-id` flags.
In other words, environment files are (specialized) response-files which ghc (tool, or lib) may pick up automatically. They are a way to encode a view into cabal's store (but technically there is no reason they cannot be used to give a view into stack's snapshot package databases too)

Why can't my GHC find Prelude?
Probably because there is -hide-all-packages, -clear-package-db (or both); without -package-db and -package-id for base (a package with module Prelude).

If you invoke plain ghc, what packages does it "see"?

It depends on the state you have. This is complicated (use cabal-install). If you have a default or local environment file, ghc will use those. If there aren't it will use a global package db.

To be honest, I'm not so sure what GHC does by default. I'm mostly familiar with programmatic execution, which often starts with `-clear-package-db`, `-hide-all-packages` etc to clear all the implicit stuff GHC may do.

- Oleg

_______________________________________________
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


_______________________________________________
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Reply via email to