Question about relationship of Cabal and Stack

I’m just getting started with Haskell and got interested in the available Haskell tool chains. I have done development with Java before and my first thought was that Cabal is like Apache Maven. But then I found Stack and now I wonder what is the relationship between Cabal and Stack. When does one use Cabal and when Stack?

Thanks in advance.

1 Like

Use stack :slight_smile:

There are actually Cabal, the library and package format; and cabal-install, the package manager. Both, Stack and cabal-install, use Cabal, the library.
For cabal-install you have to wrte .cabal files yourself; Stack has a friendlier package format and generates .cabal files (similar to cmake and make or meson and ninja).
Stack provides more project management features, reproducible builds.

Here is a similar question with more information: https://stackoverflow.com/a/42601219/2737998.

2 Likes

Quite frankly this is a strange claim; in what way is the native .cabal format unfriendly? In fact, if anything I’d recommend against Stack’s “friendly” format; see e.g. https://mail.haskell.org/pipermail/haskell-community/2016-September/000262.html

As for reproducible builds, this is not exclusive to Stack; it may surprise people, but Cabal supported “reproducible builds” since around Cabal 1.18 (released in 2013); it’s something you tend to need when you use Haskell professionally; and if you want to extend the reproducibility beyond the Haskell layer, augmenting Cabal with NixOS is currently the most principled solution I know of.

Moreover, I’d like to offer a more comprehensive answer to OP (taken from https://gist.github.com/merijn/8152d561fb8b011f9313c48d876ceb07):


The Cabal/Stack Disambiguation Guide

One of the most frequently asked Haskell beginner questions in recent
years is:

“Stack or cabal?”

I will helpfully not answer this question. Instead I will hope to
eliminate the confusion that many of the askers seem to have about the
various different things named “cabal” and how they relate to each other
and stack.

So, how many things named “cabal” do we have? We have:

  1. CABAL (the spec)

    CABAL is the Common Architecture for Building Applications &
    Libraries. It’s a specification for defining how Haskell
    applications and libraries should be built, defining dependencies,
    etc.

  2. .cabal (the file format)

    The file format used to write down the aforementioned definitions
    for a specific package.

  3. Cabal (the library)

    The library implementing the above specification and file format.

  4. cabal (the executable)

    The cabal executable, more accurately named cabal-install, is a
    commandline tool that uses Cabal (the library) to resolve
    dependencies from Hackage and build packages.

How does Stack relate to all this CABAL stuff?

Stack is a replacement for cabal-install, i.e. the cabal executable.
The stack commandline tool, like cabal-install is a tool that uses
Cabal (the library) to resolve dependencies and build packages. The main
difference between cabal-install and stack is how they resolve
dependencies.

So, what do cabal-install and stack do differently?

cabal-install looks at the declared version ranges of a package in the
.cabal file and using the available versions on Hackage it computes a
build plan satisfying the version constraints, then compiles using this
build plan.

stack on the other hand uses “resolvers”. A resolver is a snapshot of
various package versions on Stackage and dependencies are resolved by
“just use the exact version specified by the resolver”.

It is possible to make stack resolve things dynamically[^1] as
cabal-install and vice versa, you can create snapshots (freeze files)
using cabal-install to accomplish what stack does.

So which tool should I use?

Honestly, at this point I don’t think there is much difference, use
whichever tool best fits your workflow. The only real strong opinion I
have is that you should avoid Stack’s (optional) use of hpack at all
costs.

hpack is a tool that generates .cabal files from package.yaml. In
the past there were some (in my personal opinion, weak) reasons for
using package.yaml, but those are nowadays possible in .cabal too.

package.yaml does not support all CABAL features and requires all your
potential users to install extra tooling. The .cabal format is
understood by both cabal-install and stack without extra tools, so
everyone can just use/contribute with their preferred tools.

[^1]: As of Stack 2.x this functionality has been dropped from Stack and
so this is no longer possible.

10 Likes

I think the post hvr linked is good. I’d like to share another one that I like about the differences between the two: https://sigkill.dk/blog/2019-10-17-haskell-build-systems-for-non-haskellers.html

And also share an article that describes how to use each tool: https://kowainik.github.io/posts/2018-06-21-haskell-build-tools.html

Have fun!

2 Likes

I’m sorry for asking FAQ. Will read more documentation first

Don’t be sorry for asking an FAQ, its a sign that we as a community need to do more to make the information you seek more accessible. Please keep asking.

6 Likes

How do you get the .cabal file to dynamically export modules? In projects, I create a lot of new modules and do not like modifying the cabal file to export those each time when hpack does it for me.

1 Like

Just for the files, here’s the official Stack FAQ entry that answers my question.

What is the relationship between stack and cabal?

Thanks for all the replies.