Occasionally when I’m using HLS (via emacs’s lsp
mode) I see that in the background ghcup
is installing some version of GHC that I don’t have. Often I don’t have enough free space, so it just dies. I’ve ended up with .ghcup/tmp
containing 8 GB of temporary files from aborted installs!
I don’t understand why HLS is asking ghcup
to install anything. lsp
mode and HLS are working fine, so it doesn’t seem like I need a new version of GHC installed.
Why is it happening, and is there a way I can disable this behaviour?
(I’m currently using HLS 2.5.0.0
but it also happened with whichever version of HLS I was using before, too.)
That seems extremely weird. HLS does not call ghcup, it does call your build tool to get flag information but that’s about it.
The vscode extension does call ghcup to install HLS, but not GHC. Not that that’s relevant since you’re using Emacs.
1 Like
Oh, OK, thanks, how mysterious. Next time it happens I’ll do a pstree
to try to determine exactly what process is causing ghcup
to be run. It must be something to do with HLS because I only ever see this when using HLS (through lsp
). That doesn’t mean it’s HLS that is responsible, of course. It could be something else in my emacs
config that’s doing it …
Is it a stack project where you installed stack with ghcup? It looks like then stack will call ghcup sometimes. I think HLS calls something like stack setup
, so conceivably in that situation it could trigger downloading GHC?
2 Likes
I have one stack-using project open, which is stan
, and indeed I have stack
installed via ghcup
(although I don’t use stack
myself). I don’t see anything in the current stan
that would request ghc-9.4.7
, which is what ghcup
was trying to download, but perhaps this is indeed the problem. I’ll keep an eye on it.
Although if I do stack build
in the stan
directory it does try to download ghc-9.6.4
, so maybe this is the root cause. I was pretty sure HLS was using cabal
on this project though … It looks like I don’t have a hie.yaml
here, so I am not certain …
If there is both cabal and stack configuration in a project and no hie.yaml
, then we guess stack. Sounds like that’s the culprit.
2 Likes
That sounds pretty plausible but I don’t really understand what I’m seeing, because in the logs I see this from 10 minutes ago when I just tried (and posted my message):
2024-02-05T16:42:35.349366Z | Debug | executing command: cabal --builddir=/home/tom/.cache/hie-bios/dist-stan-624f6e53d42a862e637781e3061ca192 v2-repl --with-compiler /home/tom/.cache/hie-bios/wrapper-b54f81dea4c0e6d1626911c526bc4e36 --with-hc-pkg /home/tom/.cache/hie-bios/ghc-pkg-6ab590ecd05b25ce2522f0302b32bac5 lib:stan
I don’t see any evidence it has tried to use stack
for anything and I definitely don’t have a hie.yaml
.
The other variable is that stack
needs to be on the path, if that could have changed.
Doesn’t look like it. Seems like it’s been there since October:
% ls -l $(which stack)
lrwxrwxrwx 1 tom tom 12 Oct 29 15:02 /home/tom/.ghcup/bin/stack -> stack-2.11.1
OK, I think I’ve seen enough to understand most of what’s going on now. Here’s pstree
during the latest occurrence:
|-screen(1428354)---emacs(1428356)-+-aspell(1526625)
| |-haskell-languag(1913455)-+-{haskell-languag}(1913785)
| | |-{haskell-languag}(1913786)
...
| |-stack(1965609)-+-sh(1965614)---ghcup(1965616)-+-{ghcup}(1965624)
| | | |-{ghcup}(1965625)
...
| | |-{stack}(1965610)
...
| |-{emacs}(1428408)
...
So ghcup
is being called by stack
which itself is being called by emacs
.I would have expected to see it called by haskell-language-server
, but maybe there’s some parent misattribution there. ghcup
is trying to install ghc-9.4.7
% ps aux | grep '[^.]ghcu[p]'
tom 1965616 32.3 0.2 1073760360 23280 ? Sl 19:17 0:15 ghcup run --ghc 9.4.7 --install
emacs
's *Messages*
gives a clue why 9.4.7
specifically:
/home/tom/.ghcup/ghc/9.4.7/bin/ghc: getFileStatus: does not exist (No such file or directory)
Error: [S-6362]
No compiler found, expected minor version match with ghc-9.4.7 (x86_64-tinfo6-libc6-pre232) (based on resolver setting in /home/tom/.stack/global-project/stack.yaml).
To install the correct GHC into /home/tom/.stack/programs/x86_64-linux/, try running 'stack setup' or use the '--install-ghc' flag. To use your system GHC installation, run 'stack config set system-ghc --global true', or use the '--system-ghc' flag.
Try installing a more recent version of haskell-stack-ghc, and please open a bug report if the issue persists in the latest release. Thanks!
and indeed:
% cat .stack/global-project/stack.yaml
...
packages: []
resolver: lts-21.18
LTS 21.18 is ghc-9.4.7
. I don’t, however, understand why stack
run through HLS is using stack/global-project/stack.yaml
when there’s a stack.yaml
in stan
's top-level directory.
Anyway, the main mystery is resolved. I guess I should just use hie.yaml
and ask for cabal
. Thanks again for your help, @michaelpj.
Since going all in on ghcup, I’ve configured stack to only use the system ghc and not to install it with:
$ stack config set system-ghc true --global
$ stack config set install-ghc false --global
$ cat ~/.stack/config.yaml
...
system-ghc: true
install-ghc: false
I don’t see stack trying to install GHC anymore with this configuration.
2 Likes
Stack will use GHCup to manage versions of GHC if you have (a) customised Stack to do so (possibly by asking GHCup to customise Stack in that way on set up) and (b) not set Stack to try to use the version of GHC on the PATH (system-ghc: true
) - see Configuration (project and global) - The Haskell Tool Stack. If you want Stack to manage versions of GHC directly, delete ghc-install.sh
from the hooks
directory in the Stack root directory (stack path --stack-root
).
When GHCup is being used to manage versions of Stack, it puts a small exectuable named stack
on the PATH that runs the specified version of Stack (also named stack
). (As an aside, this interferes with Stack’s own management of versions of Stack.)
If you set system-ghc: true
, Stack will try to use the GHC version on the PATH, if it is the correct version. If you set install-ghc: false
and Stack is managing versions of GHC directly (not via GHCup), Stack will not try to install the correct version of GHC if it is not available.
EDIT: So, as @philderbeast rightly advises, if somebody is using GHCup to manage manually the version of GHC on the PATH and that user does not want Stack to fetch automatically (via GHCup or otherwise) GHC if the correct version is not available to Stack on the PATH, the user needs to configure Stack with system-ghc: true
and install-ghc: false
(either at the level of the individual project in stack.yaml
or, more likely, globally in config.yaml
).
1 Like