haskell/hie-bios

Passing Cabal flags

sheepforce opened this issue ยท 13 comments

I'm currently trying to deal with the problems described in haskell/haskell-language-server#365 where TemplateHaskell code with C dependencies breaks the HLS for a module. The suggested workaround (and it is not a nice one) is to use CPP magic to eliminate the problem causing code for HLS and switch it out by a stub. I'm doing so via cpp-options in cabal, which are themselves triggered by a cabal flag.

Basically I want cabal -fdevelop for HLS and cabal -f-develop for everything else. Is it somehow possible using the hie-bios to pass such flags to HLS?

fendor commented

Hi, thank you for the bug report!

Currently, there is no released HLS version that allows this, iirc, since it would depend on the relatively new version 0.13.0 of hie-bios. However, once haskell/haskell-language-server#3462 is merged, the following should work.

I think you can specify flags in cabal.project files, right?
Then you can create a cabal.hls.project file, specify the packages and flags.
You can instruct HLS to use this cabal.project.hls file by creating a hie.yaml file with the contents:

cradle:
  cabal:
    cabalProject: "cabal.hls.project"

I think you can specify flags in cabal.project files, right?

Yes, this was also something I've tried and setting the flag there also works

Then you can create a cabal.hls.project file, specify the packages and flags. You can instruct HLS to use this cabal.project.hls file by creating a hie.yaml file with the contents:

This looks very good and exactly like a solution to my problem. Unfortunately HLS -> GHCIDE does not support the hie-bios 0.13.0 where this was introduced, yet ๐Ÿ˜ฌ I guess this solution also has to wait for the next HLS, then?

fendor commented

Yes, or build the PR from source and give it a spin. Compiling from source is easy with ghcup :)

Otherwise, I am afraid wait for the release that incorporates hie-bios 0.13.0, I can imagine there will be a release with that version this year, but I can't promise.

Thank you very much! I'm on a Nix setup as my project has some crazy Python, Fortran and C deps and I wasn't successful yet with building the HLS form the PR there. ๐Ÿ˜ฌ

I will report back when the HLS with hie-bios 0.13.0 becomes available, but I'm very optimistic that it solves this problem :)

Alright, HLS 2.6 and the hie-bios 0.13.1 made it to nixkgs (at least in the haskell-updates branch). I'm using a hie.yaml file that contains

cradle:
  cabal:
    cabalProject: "nix-cabal.project"

and starting the HLS it also gets this option passed:

$ haskell-language-server-wrapper 
Found "/home/phillip/Dokumente/Git/Spicy/spicy-chemistry/hie.yaml" for "/home/phillip/Dokumente/Git/Spicy/spicy-chemistry/a"
Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper) Version 2.6.0.0 x86_64 ghc-9.6.4
Current directory: /home/phillip/Dokumente/Git/Spicy/spicy-chemistry
Operating system: linux
Arguments: []
Cradle directory: /home/phillip/Dokumente/Git/Spicy/spicy-chemistry
Cradle type: Cabal

Tool versions found on the $PATH
cabal:          3.10.2.1
stack:          Not found
ghc:            9.6.4


Consulting the cradle to get project GHC version...
2024-01-26T10:06:42.011792Z | Debug | cabal exec --project-file /home/phillip/Dokumente/Git/Spicy/spicy-chemistry/nix-cabal.project -v0 -- ghc --print-libdir
Failed to find the GHC version of this Cabal project.
Error when calling cabal exec --project-file /home/phillip/Dokumente/Git/Spicy/spicy-chemistry/nix-cabal.project -v0 -- ghc --print-libdir

When using configuration(s) from /home/phillip/Dokumente/Git/Spicy/nix-cabal.project, the following errors occurred:
The package directory '.' does not contain any .cabal file.

But apparently the option doesn't work as expected. Indeed cabal exec --project-file /home/phillip/Dokumente/Git/Spicy/spicy-chemistry/nix-cabal.project -v0 -- ghc --print-libdir gives the same error also when run independently. However, giving only the relative path to the project file works flawlessly:

$ cabal exec --project-file=nix-cabal.project -v0 -- ghc --print-libdir
/nix/store/nsiq29cbm67byvh8rm4dn7gnf42ndcsi-ghc-9.6.4-with-packages/lib/ghc-9.6.4/lib

Am I doing something wrong here? ๐Ÿ™‚

Hm, looks like project-file option is deprecated. I get the warning

Warning: Specifying an absolute path to the project file is deprecated. Use
--project-dir to set the project's directory.

on my cabal HEAD binary.

what's the output without the -v0 flag?

I can not reproduce:

$ cabal-3.10.2.1 exec --project-file /home/hugin/Documents/haskell/eventlog2html/cabal.project -- ghc --print-libdir
Resolving dependencies...
/home/hugin/.ghcup/ghc/9.4.8/lib/ghc-9.4.8/lib
$ cabal-3.10.1.0 exec --project-file /home/hugin/Documents/haskell/eventlog2html/cabal.project -- ghc --print-libdir
Resolving dependencies...
/home/hugin/.ghcup/ghc/9.4.8/lib/ghc-9.4.8/lib
$  cabal-3.6.2.0 exec --project-file /home/hugin/Documents/haskell/eventlog2html/cabal.project -- ghc --print-libdir 
Resolving dependencies...
/home/hugin/.ghcup/ghc/9.4.8/lib/ghc-9.4.8/lib

This cabal issue may be relevant: haskell/cabal#7695

PR that explains the warning above: haskell/cabal#8454

Hm, but it's not me who is generating this option. It directly comes from hie-bios/HLS, doesn't it? Even if I change my hie.yaml to

cradle:
  cabal:
    cabalProject: ./nix-cabal.project

and be explicit about being a relative path haskell-language-server-wrapper generates the path absolute in the cabal call. So I can use --project-file $RELATIVE_PATH or --project-dir $ABSOLUTE_PATH and that's perfectly fine. But how do I tell hie-bios/HLS to do so?

EDIT: the otuput without -v0 is

When using configuration(s) from /home/phillip/Dokumente/Git/Spicy/nix-cabal.project, the following errors occurred:
The package directory '.' does not contain any .cabal file.

Ah nevermind. The problem is something different. I have a monorepo with many subprojects. The nix-cabal.project resides in the top-level directory and is symlinked into each subproject. For some reasons it resolves the project directory to the top-level directory, not to that of the subproject. If I instead copy the nix-cabal.project file into the subproject it just works. A little bit surprising behaviour but I can deal with that ๐Ÿ˜„

Yeah, the behaviour of --project-file seems to be surprising... We will have to rethink our approach, as currently we force the absolute path.

Indeed ๐Ÿ˜„ But easy to work around if one's aware. However, the cabalProject option solved my problem exactly as you've advertised. If you'd like we can close the ticket :) Thank you very much! ๐Ÿ‘

Closing it for now, thanks for verifying it works (roughly) as advertised!