[Haskell-cafe] Best approach to avoid dependency hells
Bill Casarin
bill at casarin.ca
Thu Dec 6 17:51:21 CET 2012
After using Haskell in production for awhile this is my go-to method for
minimizing pain when dealing with dependencies. As long as you follow these
steps you should be able to deal with most dependency issues.
1. NEVER use cabal, always use cabal-dev. Preferably with latest version
that supports parallelized builds with -j<cores>. It's just not worth
having your builds break all the time. Rebuilding the world isn't too bad
with -j12 and cabal won't trip up as much trying to resolve version
conflicts. Sometimes you will get a "this will break existing packages"
message when using cabal-dev but I think that's just because cabal is
confused, --force-reinstalls is your friend in this situation and shouldn't
really break anything because it's a sandboxed build.
2. Make a directory called lib in your project and drop any of your
dependencies in there, then your build rule will be the same for all your
projects:
cabal-dev install . ./lib*
This is handy because now you can drop any misbehaving packages in your lib
folder if you need to fix any version conflicts (although I don't find
myself doing this much)
3. Dealing with version conflicts:
In my experience most version conflicts are caused by unnecessary upper
bound constraits (4.*, && < 5.0). I'd recommend anyone writing packages to
only include these if you know the newer version actually breaks something
or causes unacceptable performance changes. All my projects only have lower
bounds (>= v) and I've never had any problems with dependency issues
between my packages.
If you get to this point and you still have a misbehaving package, simply
download the tarball from hackage and drop it in your lib folder, remove
upper bounds, and voila, it will work most of the time.
Cheers,
Bill
On Wed, Dec 5, 2012 at 1:52 PM, Ivan Perez <ivanperezdominguez at gmail.com>wrote:
> Hello everyone,
>
> I've spent the last couple of days fighting my way around a dependency
> hell with my own libraries and packages.
>
> If I install them package by package (by hand), I'm very likely to hit
> one of these conflicts that I'm talking about. A simple example of
> something that did happen:
> - Package A depends on bytestring, and is compatible with both 0.9.* and
> 0.10.*
> - Package B depends on ghc, which I installed using the package
> manager and which depends on bytestring 0.9.2
> - Package B depends on package A.
>
> I do not want to add to the cabal files that B depends on bytestring
> 0.9.*, because it's not true, or that A depends on bytstring 0.9,
> because it's also not true.
>
> I would like to the best approach to 1) avoid these situations and 2)
> fix them when they happen.
>
> Regarding (2), Is there any way to automatically rebuild all the
> broken packages?
> Regarding (1), I thought about using cabal-dev, but I think I'll just
> have the same problem, won't I? After all, I started from a clean
> fresh ghc installation and I just installed what I needed to make my
> program run.
> I also thought about adding process, bytestring and other global
> packages to the list of constraints in ~/.cabal/config. Would this be
> a good approach, or will it lead to bigger headaches in the future
> (for instance, in the form of programs that just cannot be installed
> at all)?
>
> Also, is there any way to detect potential dependency hells without
> having to install a package? (Some tool that will analyse the
> dependency information (statically) and determine more strict or
> incorrect upper and lower bounds for the dependencies of a package.)
>
> Cheers,
> Ivan
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20121206/452e4a77/attachment.htm>
More information about the Haskell-Cafe
mailing list