haskell / hie-bios

Set up a GHC API session for various Haskell Projects
https://hackage.haskell.org/package/hie-bios
BSD 3-Clause "New" or "Revised" License
177 stars 61 forks source link

Passing Cabal flags #423

Closed sheepforce closed 5 months ago

sheepforce commented 7 months ago

I'm currently trying to deal with the problems described in https://github.com/haskell/haskell-language-server/issues/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 7 months ago

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 https://github.com/haskell/haskell-language-server/pull/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"
sheepforce commented 7 months ago

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 :grimacing: I guess this solution also has to wait for the next HLS, then?

fendor commented 7 months ago

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.

sheepforce commented 7 months ago

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. :grimacing:

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 :)

sheepforce commented 5 months ago

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? :slightly_smiling_face:

fendor commented 5 months ago

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?

fendor commented 5 months ago

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
fendor commented 5 months ago

This cabal issue may be relevant: https://github.com/haskell/cabal/issues/7695

PR that explains the warning above: https://github.com/haskell/cabal/pull/8454

sheepforce commented 5 months ago

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.
sheepforce commented 5 months ago

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 :smile:

fendor commented 5 months ago

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

sheepforce commented 5 months ago

Indeed :smile: 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! :sheep:

fendor commented 5 months ago

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