[Tooling Tip] relevant if you use private sublibraries in cabal

Cabal supports sublibraries, wherein you could specify multiple libraries to be built in addition to the main one (the one without a name) in the package.

Cabal also supports specifying the visibility of these sublibraries, public or private, which by default is “private.” (EDIT: it is private per doc.)

An example:

library lvm
  import:     basic-options
  visibility: private
  --
  hs-source-dirs:  ./internal/lvm
  exposed-modules: ...
  build-depends: ...

However, I recently learned that my default setup doesn’t jibe well with this setting. I am using haskell-language-server (HLS) 2.9.0.0 and Emacs 29.4. As far as I am aware, this tip should also apply to vscode + HLS too.

What I did to make my setup work better are:

cabal.project

multi-repl: true

doc link:

–enable-multi-repl

Allow starting GHCi with multiple targets. This requires GHC with multiple home unit support (GHC-9.4+)

The closure of required components will be loaded.

emacs’s lsp-haskell configuration

(use-package haskell-mode
;; ...
:custom
  (lsp-haskell-session-loading "multipleComponents")
;;

vscode HLS configuration

According to people using vscode, similarly, you should use:

haskell.sessionLoading: "multipleComponents"

I am not aware of the full story behind these settings, and I wonder if this option should become the default. But in any case, hope it can be helpful to you too.

7 Likes

Well-Typed has a blog post describing this: Multi Component Support in HLS with cabal-install 3.12 - Well-Typed: The Haskell Consultants

In particular this setting requires:

  • GHC version 9.4 or later
  • cabal-install version 3.12.0.0 or later
  • HLS version 2.6.0.0 or later
3 Likes

Thanks, I had not known. I quote the relevant section in the blog post on why it is not a default setting yet:

We disabled the feature by default because we discovered that HLS did not handle the setup dependency requirement gracefully: it would fail if any package in your dependency tree did not support version 3.12.0.0 of the Cabal library. In due course, we hope to re-enable this feature by default as more libraries become compatible with newer versions of the Cabal library.

thank you for posting this ~ I was wondering why I got the bug with the not loaded libraries since that was enabled ~ it turns out that the blogpost linked by @jaror has a typo (and I blindly copied from there), it’s
multipleComponents as you said, not multiComponent as shown in the blogpost!

1 Like

Ah, perhaps @adamgundry can fix the typo?

The specification of the Cabal package format is that the visibility of named sub-libraries is private by default. That default is consistent with the history of the feature (no sub-libraries and then only ‘internal’ sub-libraries). See: 1. Package Description — <package>.cabal File — Cabal 3.12.1.0 User's Guide

Is Cabal behaving differently to the specification?

You are right; I edited my post. Doc says it is private by default.

1 Like

Thanks, the post will be fixed on the next deploy of the site. This is the peril of writing posts before the feature implementation has fully stabilized…

This may be relevant: Multi Component Support in HLS with cabal-install 3.12 - Well-Typed: The Haskell Consultants “We disabled the feature by default because we discovered that HLS did not handle the setup dependency requirement gracefully: it would fail if any package in your dependency tree did not support version 3.12.0.0 of the Cabal library. In due course, we hope to re-enable this feature by default as more libraries become compatible with newer versions of the Cabal library.“

1 Like