Haskell-language-server: ghc version could not be determined

Hi, I am working with Obsidiansystems Obelisk and try to get the haskell-language-server running.

I am stuck with a somewhat frustrating detail. The hls doesn’t want to start, erroring out with

Found "/home/ruben/code/my-palantype/learn-palantype/hie.yaml" for "/home/ruben/code/my-palantype/learn-palantype/a"
Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper) Version 1.6.1.0, Git revision f4022c5bb8530cd306c53b941878244bf27a5d41 (dirty) x86_64 ghc-8.10.7
Current directory: /home/ruben/code/my-palantype/learn-palantype
Operating system: linux
Arguments: ["--lsp","-d","-l","/run/user/1000/hls.log"]
Cradle directory: /home/ruben/code/my-palantype/learn-palantype
Cradle type: Cabal

Tool versions found on the $PATH
cabal:		3.8.1.0
stack:		2.9.1
ghc:		Not found


Consulting the cradle to get project GHC version...
Failed to get project GHC version:CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitFailure 1, cradleErrorStderr = ["Error when calling cabal --builddir=/home/ruben/.cache/hie-bios/dist-learn-palantype-8a6791f81bf6f884398119cfc941c18b v2-exec --with-compiler /home/ruben/.cache/hie-bios/wrapper-13a09b18ea883dd377d59db5e821a86b ghc -v0 -- --numeric-version","","Error: cabal: The program 'ghc' version >=7.0.1 is required but the version of\n/home/ruben/.cache/hie-bios/wrapper-13a09b18ea883dd377d59db5e821a86b could not\nbe determined.\n\n"]}

Process lsp-haskell stderr finished

However, running the command in question in the terminal, works perfectly fine:

$ cabal --builddir=/home/ruben/.cache/hie-bios/dist-learn-palantype-8a6791f81bf6f884398119cfc941c18b v2-exec --with-compiler /home/ruben/.cache/hie-bios/wrapper-13a09b18ea883dd377d59db5e821a86b ghc -v0 -- --numeric-version
8.10.7

I am working on the development branch of Obelisk, to get GHC 8.10.7 and I am using easy-hls-nix to select the haskell-language-server for me. In the obelisk configuration this looks like this:

-- default.nix
  with pkgs.haskell.lib;
  obelisk.project ./. ({ ... }: {
    shellToolOverrides = self: super: {
      inherit easy-hls;
      inherit (pkgs) cabal-install;
      inherit (pkgs.haskell.compiler) ghc8107Binary;
    };
    -- ...
  })

This is why I am effectively using haskell-language-server version 1.6.1.0.

Also, note that I run a nix shell specific to obelisk projects

$ nix-shell -A shells.ghc

prior to starting emacs (which then tries to connect to hls) and also when testing hls outside of emacs.

Hi!

What Editor are you using, and are you making sure everything is correctly set up? It seems like there is no ghc on the $PATH. That’s per se not wrong, just curious.
Are you launching your editor of choice from the same context as your obelisk shell, such that GHC 8.10.7 and HLS is on your $PATH?

I assume you don’t have a cabal.project file, which would affect the results as well.

I am using emacs, and the setup is straightforward. I double-checked the configuration variables, but it’s a setup that generally works.

Yes, I don’t have ghc on path (using NixOS). Instead, it’s part of the shell that I am launching. I installed ghc independently just to be sure but it makes no difference.

Yes I am launching my editor from the nix-shell (that has ghc, haskell-language-server-wrapper) and from the same shell the offending command (which throws the error) works fine.

I have a cabal.project file:

optional-packages:
  *
write-ghc-environment-files: never

Ok, but there is something that doesn’t quite add up: If you launch emacs from the obelisk shell, then there is a GHC version on $PATH right? But HLS isn’t finding it?
When you launch hls-wrapper from the cli, does the same error occur? E.g. haskell-language-server-wrapper --debug <some-source-file>

Indeed it doesn’t add up.

I can run all these commands just fine (from inside the same shell where I start emacs):

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.7
$ haskell-language-server-wrapper --version
haskell-language-server version: 1.6.1.0 (GHC: 8.10.7) (PATH: /nix/store/f47pcsmzd94z7big4h6nwp5j2gkz5xz8-haskell-language-server-1.6.1.0-installer/bin/haskell-language-server-wrapper) (GIT hash: f4022c5bb8530cd306c53b941878244bf27a5d41)

And even the command that fails according to the log output of haskell-language-server within emacs:

$ cabal --builddir=/home/ruben/.cache/hie-bios/dist-learn-palantype-8a6791f81bf6f884398119cfc941c18b v2-exec --with-compiler /home/ruben/.cache/hie-bios/wrapper-13a09b18ea883dd377d59db5e821a86b ghc -v0 -- --numeric-version
8.10.7

I deleted hie.yaml and got a different error that seems to point into the right direction:

Failed to get project GHC version:CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitFailure 127, cradleErrorStderr = ["Error when calling ghc --numeric-version","","/nix/store/dzrvibwj2vjwqmc34wk3x1ffsjpp4av7-bash-4.4-p23/bin/bash: symbol lookup error: /usr/lib/libc.so.6: undefined symbol: _dl_audit_symbind_alt, version GLIBC_PRIVATE\n"]}

There seems to be a problem with bash. Or, more specific: when emacs calls ghc --numeric-version, some broken bash is invoked. Or there is a mismatch between libc versions.

The cause could simply be that my haskell-language-server-wrapper is downloaded binary (from easy-hls-nix) and not built from source for NixOS.

So new question then:

Where in the depths of nixpkgs can I find the newest binary of haskell-language-server for GHC 8.10.7?

The bigger problem is to find the exact same ghc for obelisk to compile HLS with. I am afraid, I haven’t found a simple way so far.

My technique was to checkout HLS from source and install it manually with the exact ghc version used to compile obelisk, e.g. cabal install -w <nix-path-to-ghc-8.10.7-from-obelisk-shell> exe:haskell-language-server and then invoke my editor of choice (in this case VSCode) for my obelisk projects with exactly that HLS version.

Thanks for your help. I got it to work in the way that you described.

  • I checked out haskell-language-server locally.
  • Within my obelisk project: nix-shell -A shells.ghc (I don’t know the difference to ob shell btw)
  • cd into the haskell-language-server directory
  • cabal install
  • configured emacs/lsp-haskell to find the hls server executable at $HOME/.cabal/bin/haskell-language-server (the wrapper doesn’t work, weird)
  • enjoying now haskell-language-server 1.9.1.0 in all its glory in my obelisk project

Some notes:

I had to switch to the develop branch to obelisk and activate useGHC8107 = true.

Also, my obelisk setup is simplified really:

-- default.nix
  with pkgs.haskell.lib;
  obelisk.project ./. ({ ... }: {
    shellToolOverrides = self: super: {
      inherit (pkgs) cabal-install;
    };
    -- ...
  })

There is no need to specify a path to obelisk’s ghc. The one obelisk is using is the only one I have available when inside nix-shell -A shells.ghc or ob shell.

Note: I had to run cabal update before cabal install. But that was it. Thanks again. There are some stan findings that I have to check now. Oh boy! :stuck_out_tongue: