[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.

6 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…