How to create binary distributions of applications with cabal (the tool) or stack

512 Views Asked by At

I've written an application in Haskell and it's starting to become slightly useful to users. However my application isn't targeted at technically adept folks, let alone Haskell developers, so building my application from source isn't really something I can expect them to do.

So to make my application available to my users, I would like build the application myself, put its executable, data files, dependencies, the dependencies' data files, required licensing information and other required files into one archive and put that archive up onto a website. Now users can download that archive, unpack it and have everything required to run my application.

The process I described above seems like a fairly common way to distribute binaries of applications to me. However, I can't figure out what tools to use or how to configure them to build my application into a binary distribution described above.

Cabal (the library) seems to have the features that are required for this. Usual Setup.hs scripts (without cabal (the tool) or stack as wrappers) support options such as --prefix and --enable-relocatable that let you install a package to the given prefix and compile them in such a way as to ensure that data files can still be located if the prefix (as a whole) is moved somewhere else.

But using the raw Setup.hs has the downside that it doesn't handle automatically installing dependencies. And since many decently sized Haskell applications will have hundreds of dependencies (or at least mine does), configuring and building each of them by hand isn't really feasible.

The obvious solution to the problem of installing dependencies would be to use a wrapper tool such as cabal (the tool) or stack, since they are specifically made to deal with the problem of large dependency trees. However, they all seem to have problems preventing me from building my application as a binary distribution:

  • stack build doesn't have the options --prefix or --enable-relocatable and instead always installs to .stack-work and ~/.stack.

  • cabal v2-* has the options --prefix and --enable-relocatable but seems to ignore them entirely and instead always installs to dist-newstyle and ~/.cabal.

  • cabal v1-* seems to do what I want for very simple cases. However, for more complicated cases it produces obscure build failures, where GHC complains about not finding modules from dependencies and cabal complains about partially installed packages. But even putting these failures aside, using legacy commands for a new workflow doesn't seems like a good idea in general.

So, since I seem to be out of luck with these tools, what other tools can i use to build Haskell applications into binary distributions? Or maybe one of the tools I listed actually does what I want and I'm just using it the wrong way?

Some limitations in scope:

  • For now I'm mostly interested in builds for Windows, but solutions for other platforms would be interesting as well.
  • When I'm talking about dependencies, I mostly mean Haskell dependencies (i.e. Cabal packages). Solutions which also bundle foreign C dependencies would be interesting, but that's not a strict requirement.
1

There are 1 best solutions below

2
On

A workaround is to use cabal repl like this (from the directory with your-package.cabal):

$ cabal repl -b Cabal
...
ghci> :load /path/to/Setup.hs
...
ghci> :main configure --prefix=/my/prefix
...
ghci> :main build
...
ghci> :main copy --destdir=/my/dest/dir
...

That should take care of building all your dependencies, while still being able to use Setup.hs.

I think this can still cause issues if your dependencies use data-files.