How to install a local library using Cabal? - haskell

I am a total Haskell beginner, and am going through the Hudak book Haskell School of Expression. I am working on the graphics chapter, and have found an updated version of the book's graphics library: https://github.com/noughtmare/haskell-school-of-expression. However, when I run cabal v1-build, I get
Resolving dependencies...
Warning: solver failed to find a solution:
Could not resolve dependencies:
[__0] trying: SOE-0.1.0.0 (user goal)
[__1] next goal: base (dependency of SOE)
[__1] rejecting: base-4.12.0.0/installed-4.12.0.0 (conflict: SOE => base>=4.13
&& <4.15)
[__1] fail (backjumping, conflict set: SOE, base)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: SOE, base
Trying configure anyway.
Configuring SOE-0.1.0.0...
cabal-3.6.2.0.exe: Encountered missing or private dependencies:
GLFW-b, base >=4.13 && <4.15, freetype2, old-time
I do know that base is just the Haskell Prelude, which I know I have, so I have no idea what to do here. Thanks!

The specific error you're seeing occurs because the version of GHC you have installed is not compatible with that package.
The reason is that the base package version is locked to a specific GHC version, so you cannot use newer versions of base with older versions of GHC. See this wiki page for a list of the corresponding GHC version for each base version.
You could upgrade to a newer GHC version, such as 8.10.7.
An alternative is to run cabal with --allow-older=base.
And now I have actually updated the package to change the lower bound from 4.13 to 4.12, so it should compile fine if you pull the latest changes.
Also, I would recommend using the default v2-build, but that is not immediately related to the error you're seeing.

Related

Compile Haskell program with third-party dependencies

I am trying to jump into some Haskell again after being away for a while. One piece of code I wrote ages ago inclues import qualified Data.MultiMap as MultiMap. Since Data.MultipMap is in the containers package, I get errors when I just run ghc program.hs. I've attempted to write a project.cabal file based on How to make a Haskell cabal project with library+executables that still run with runhaskell/ghci?. My latest attempt is
name: project
version: 1.0
executable project
main-is: project.hs
build-dependencies:
base >= 4 && <= 5
, containers
Now when I do cabal build project, I get
Resolving dependencies...
cabal.exe: Could not resolve dependencies:
[__0] trying: project-1.0 (user goal)
[__1] next goal: project:setup.Cabal (dependency of project)
[__1] rejecting: project:setup.Cabal-3.4.0.0/installed-3.4.0.0 (conflict:
project => project:setup.Cabal>=1.0 && <1.25)
[__1] skipping: project:setup.Cabal-3.4.0.0, project:setup.Cabal-3.2.1.0,
project:setup.Cabal-3.2.0.0, project:setup.Cabal-3.0.2.0,
project:setup.Cabal-3.0.1.0, project:setup.Cabal-3.0.0.0,
project:setup.Cabal-2.4.1.0, project:setup.Cabal-2.4.0.1,
project:setup.Cabal-2.4.0.0, project:setup.Cabal-2.2.0.1,
project:setup.Cabal-2.2.0.0, project:setup.Cabal-2.0.1.1,
project:setup.Cabal-2.0.1.0, project:setup.Cabal-2.0.0.2 (has the same
characteristics that caused the previous version to fail: excluded by
constraint '>=1.0 && <1.25' from 'project')
[__1] rejecting: project:setup.Cabal-1.24.2.0, project:setup.Cabal-1.24.0.0,
project:setup.Cabal-1.22.8.0, project:setup.Cabal-1.22.7.0,
project:setup.Cabal-1.22.6.0, project:setup.Cabal-1.22.5.0,
project:setup.Cabal-1.22.4.0, project:setup.Cabal-1.22.3.0,
project:setup.Cabal-1.22.2.0, project:setup.Cabal-1.22.1.1,
project:setup.Cabal-1.22.1.0, project:setup.Cabal-1.22.0.0,
project:setup.Cabal-1.20.0.4, project:setup.Cabal-1.20.0.3,
project:setup.Cabal-1.20.0.2, project:setup.Cabal-1.20.0.1,
project:setup.Cabal-1.20.0.0, project:setup.Cabal-1.18.1.7,
project:setup.Cabal-1.18.1.6, project:setup.Cabal-1.18.1.5,
project:setup.Cabal-1.18.1.4, project:setup.Cabal-1.18.1.3,
project:setup.Cabal-1.18.1.2, project:setup.Cabal-1.18.1.1,
project:setup.Cabal-1.18.1, project:setup.Cabal-1.18.0,
project:setup.Cabal-1.16.0.3, project:setup.Cabal-1.16.0.2,
project:setup.Cabal-1.16.0.1, project:setup.Cabal-1.16.0,
project:setup.Cabal-1.14.0, project:setup.Cabal-1.12.0,
project:setup.Cabal-1.10.2.0, project:setup.Cabal-1.10.1.0,
project:setup.Cabal-1.10.0.0, project:setup.Cabal-1.8.0.6,
project:setup.Cabal-1.8.0.4, project:setup.Cabal-1.8.0.2,
project:setup.Cabal-1.6.0.3, project:setup.Cabal-1.6.0.2,
project:setup.Cabal-1.6.0.1, project:setup.Cabal-1.4.0.2,
project:setup.Cabal-1.4.0.1, project:setup.Cabal-1.4.0.0,
project:setup.Cabal-1.2.4.0, project:setup.Cabal-1.2.3.0,
project:setup.Cabal-1.2.2.0, project:setup.Cabal-1.2.1,
project:setup.Cabal-1.1.6, project:setup.Cabal-1.24.1.0 (constraint from
minimum version of Cabal used by Setup.hs requires >=3.4)
[__1] fail (backjumping, conflict set: project, project:setup.Cabal)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: project:setup.Cabal, project
What am I missing to get this to work? What should I do to compile my Haskell program?
Change your project.cabal to:
cabal-version: 3.4
name: project
version: 1.0
executable project
main-is: project.hs
build-depends:
base >= 4 && <= 5
, multimap
cabal-version: 3.4 picks the latest version of the Cabal package format, which should be fine to use given that you are using Cabal 3.4 already. Left unspecified, cabal-version defaults to a very old version (as in recent versions the field is mandatory), which makes the build-type field default to Custom rather than Simple. That, in turn, leads to the error you got, as described in cabal issue #5278. In addition, I have changed build-dependencies to build-depends, and containers to multimap (as the latter package is the one that provides Data.MultiMap).

cabal sandbox hell: can not resolve depdencies

I'm trying to build my package using a sandbox. Without it, it compiles and works like a charm. Once I introduce a sandbox though cabal says it can't resolve dependencies. To my eyes these conflicts do not look like conflicts though.
The project structure is as follows:
application (depends on library-base, library-impl1 and library-impl2)
library
├ library-base
├ library-impl1 (depends on library-base)
└ library-impl2 (depends on library-base)
These are the commands I ran in that order
rm -rf ~/.cabal
rm -rf ~/.ghc
cabal update
rm -f cabal.sandbox.config
rm -rf .cabal-sandbox
cabal sandbox init
cabal sandbox add-source $LIB_HOME/library-base
cabal sandbox add-source $LIB_HOME/library-impl1
cabal sandbox add-source $LIB_HOME/library-impl2
cabal install --only-dependencies --force-reinstalls && cabal build
cabal install --only-dependencies --force-reinstalls produces the following output:
Resolving dependencies...
cabal: Could not resolve dependencies:
next goal: lens (dependency of library-base-0.1.0.0)
rejecting: lens-4.15.4/installed-I5C... (conflict: bifunctors==5.4.2, lens =>
bifunctors==5.4.2/installed-Hs7...)
trying: lens-4.15.4
trying: unordered-containers-0.2.8.0/installed-1tq... (dependency of
lens-4.15.4)
next goal: text (dependency of lens-4.15.4)
rejecting: text-1.2.2.2/installed-3EN... (conflict: binary==0.8.5.1, text =>
binary==0.8.3.0/installed-0.8...)
trying: text-1.2.2.2
next goal: hashable (dependency of lens-4.15.4)
rejecting: hashable-1.2.6.1/installed-2nP... (conflict: text==1.2.2.2,
hashable => text==1.2.2.2/installed-3EN...)
rejecting: hashable-1.2.6.1, hashable-1.2.6.0, hashable-1.2.5.0,
hashable-1.2.4.0, hashable-1.2.3.3, hashable-1.2.3.2, hashable-1.2.3.1,
hashable-1.2.3.0, hashable-1.2.2.0, hashable-1.2.1.0, hashable-1.2.0.10,
hashable-1.2.0.9, hashable-1.2.0.8, hashable-1.2.0.7, hashable-1.2.0.6,
hashable-1.2.0.5, hashable-1.2.0.4, hashable-1.2.0.3, hashable-1.2.0.2,
hashable-1.2.0.1, hashable-1.2.0.0, hashable-1.1.2.5, hashable-1.1.2.4,
hashable-1.1.2.3, hashable-1.1.2.2, hashable-1.1.2.1, hashable-1.1.2.0,
hashable-1.1.1.0, hashable-1.1.0.0, hashable-1.0.1.1, hashable-1.0.1.0,
hashable-1.0.0 (conflict: unordered-containers =>
hashable==1.2.6.1/installed-2nP...)
Dependency tree exhaustively searched.
Does anyone have an idea what is going on here?
First I will give an explanation of what the error message says. Then I will attempt to make some guesses about why you have the error. Then I will propose some next steps.
The error says:
Maybe version 4.15.4 of lens will work.
Maybe the installed version 0.2.8.0 of unordered-containers will satisfy lens' dependency on unordered-containers.
Maybe the installed version 1.2.2.2 of text will satisfy lens' dependency on text.
Crap. You asked for version 0.8.5.1 of binary, but the installed version of text was built against version 0.8.3.0. I have to rebuild text.
Maybe the installed version 1.2.6.1 version of hashable will satisfy lens' dependency on hashable.
Crap. We're rebuilding text, a dependency of hashable. I have to rebuild hashable.
Double crap. We already committed to using the installed version of unordered-containers, which depends on the installed version of hashable, which prevents us from rebuilding hashable.
(...and I tried a bunch of other stuff that didn't work, too, but I'm not telling you what, nya nya nya)
Normally sandboxes ignore local package databases, so this suggests to me that where it is talking about "installed versions" above it is either picking these up from your global package database or from your existing sandbox. You claim that you have just created this sandbox and run this cabal install command immediately. If this is true (is it? or is this a second run of the tool? why do you have --force-reinstalls?), it cannot be picking the installed versions from your sandbox, and therefore must be picking them up from your global package database. Installing things to the global package database is generally considered a Bad Idea, because it's much more difficult to correctly clear out a cluttered/broken global package database. Take it under future advisement.
Now, to make progress, I would try one of these two things:
The only part of the above error explanation that you have control over is the "You asked for version 0.8.5.1 of binary" part. Consider relaxing your version constraints on binary to accept the already-installed version 0.8.3.0.
You can often get significantly better error messages out of cabal by cutting down on its search space; because it only prints a part of the search space in its error, you sometimes need to guide it to the problematic part of the space so that it will show you the real problem in its error. If you're pretty sure the installed versions of unordered-containers et al are a good match for your library, consider
cabal install --only-dependencies --constraint 'unordered-containers installed' --constraint 'binary installed'
and so on for any other packages it mentions trying to rebuild that you don't want it to rebuild. Alternately you can put exact version constraints in the --constraint if you don't want one of the installed versions. Don't include --force-reinstalls, basically ever.

"Could not resolve dependencies" with cabal due to MonadCatchIO-transformers

I am trying to build a package to deploy using propellor, and have not even been able to get it to configure due to dependency issues.
Here is the error message that I get:
$ cabal new-configure
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: prod-0.0.1 (user goal)
trying: base-4.9.1.0/installed-4.9... (dependency of prod-0.0.1)
trying: transformers-0.5.2.0/installed-0.5... (dependency of propellor-2.17.0)
next goal: MonadCatchIO-transformers (dependency of prod-0.0.1)
rejecting: MonadCatchIO-transformers-0.3.1.3 (conflict:
base==4.9.1.0/installed-4.9..., MonadCatchIO-transformers => base<4.9)
rejecting: MonadCatchIO-transformers-0.3.1.2,
MonadCatchIO-transformers-0.3.1.1, MonadCatchIO-transformers-0.3.1.0
(conflict: base==4.9.1.0/installed-4.9..., MonadCatchIO-transformers =>
base<4.8)
rejecting: MonadCatchIO-transformers-0.3.0.0,
MonadCatchIO-transformers-0.2.2.3, MonadCatchIO-transformers-0.2.2.2,
MonadCatchIO-transformers-0.2.2.1, MonadCatchIO-transformers-0.2.2.0,
MonadCatchIO-transformers-0.2.1.0, MonadCatchIO-transformers-0.2.0.0
(conflict: base==4.9.1.0/installed-4.9..., MonadCatchIO-transformers =>
base<4.7)
rejecting: MonadCatchIO-transformers-0.1.0.1 (conflict:
transformers==0.5.2.0/installed-0.5..., MonadCatchIO-transformers =>
transformers==0.1.*)
rejecting: MonadCatchIO-transformers-0.1.0.0,
MonadCatchIO-transformers-0.0.2.0, MonadCatchIO-transformers-0.0.1.0
(conflict: transformers==0.5.2.0/installed-0.5..., MonadCatchIO-transformers
=> transformers<0.2)
Dependency tree exhaustively searched.
It seems that the package 'MonadCatchIO-transformers' package requires an older version of 'base', and a much older version of transformers.
I have tried following the advice of this post (editing the configuration of MonadCatchIO-transformers and then installing) to override these requirements, but somehow get the same error message.
I have also tried many other things including this with and without sandboxes, and reinstalling my entire ghc, etc. Is there any way out of this cabal hell?
The first thing you should do when facing unsatisfiable dependencies for Hackage packages is checking the package documentation at Hackage to have a broader picture of the problem. In this case, the documentation reveals that MonadCatchIO-transformers was deprecated in favour of the exceptions package, that provides a similar interface (which explains why MonadCatchIO-transforemrs wasn't updated for base 4.9). That being so, you have basically three approaches for getting your package to build:
1. Switch your code to exceptions
Since MonadCatchIO-transformers appears to be a dependency that you are directly using in your code (as opposed to a transitive dependency), the recommended long-term solution is updating your code to use exceptions rather than MonadCatchIO-transformers.
2. Use GHC 7.10 for this project
If you can't, or don't want to, switch to exceptions right now, an alternative is setting up a parallel GHC 7.10.x installation, so that you can use base 4.8. Suggestions of ways to conveniently using cabal-install with multiple versions of GHC are presented in Using cabal with multiple GHC versions (through cabal settings -- be sure to also read the more recent answers further down the page) and in this blog post by Edsko de Vries (by managing your bash environment). Another possibility is using Stack (rather than cabal-install) to build this specific project and switching to a resolver that provides base 4.8 and MonadCatchIO-transformers (such as the LTS 6.30 Stackage snapshot), as Stack can install and manage alternative GHC versions for projects that require it (cf. the stack setup command). Stack doesn't interfere with your usual cabal-install environment or with your system-wide GHC installation; that being so, if you switch this project to Stack you can remain using cabal-install everywhere else just fine.
3. Adjust the upper bounds of MonadCatchIO-transformers
There is also approach of installing a custom version of MonadCatchIO-transformers with adjusted upper bounds of base and transformers. While that may be the quickest way to get it up and running, in this case it is also the least sustainable one, considering that MonadCatchIO-transformers has been deprecated for several years already. As for why that didn't work for you...
I have tried following the advice of this post (editing the configuration of MonadCatchIO-transformers and then installing) to override these requirements, but somehow get the same error message.
... the fact you got literally the same error message suggests that cabal-install didn't pick your custom MonadCatchIO-transformers version. Have you changed the version of MonadCatchIO-transformers, both in the .cabal file you changed (as suggested in the Q&A you linked to) and in the .cabal file of your project?

Hackage name collision while using stack solver with extra-deps

Well it turns out that my app name is the same as one of the packages that is uploaded to hackage, so when I try to resolver extra dependencies using stack solver --resolver lts 7.12, I get the following error:
$ stack solver --resolver lts-7.12
Using configuration file: stack.yaml
Using cabal packages:
- html-parse.cabal
Using resolver: lts-7.12
Using compiler: ghc-8.0.1
Asking cabal to calculate a build plan...
Trying with packages from lts-7.12 as hard constraints...
Attempt failed.
>>>> Cabal errors begin
cabal.exe: Could not resolve dependencies:
next goal: html-parse (user goal)
rejecting: html-parse-0.2.0.0, 0.1.0.0 (global constraint requires ==0.0.0.3)
trying: html-parse-0.0.0.3
next goal: hunit (dependency of html-parse-0.0.0.3)
Dependency tree exhaustively searched.
<<<< Cabal errors end
Could not parse cabal-install errors:
>>>> Cabal errors begin
cabal.exe: Could not resolve dependencies:
next goal: html-parse (user goal)
rejecting: html-parse-0.2.0.0, 0.1.0.0 (global constraint requires ==0.0.0.3)
trying: html-parse-0.0.0.3
next goal: hunit (dependency of html-parse-0.0.0.3)
Dependency tree exhaustively searched.
<<<< Cabal errors end
My app/package name in .cabal file is html-parse and the current version is 0.0.0.3. It looks like my own package is listed as a dependency with a constraint of ==0.0.0.3, but there is another pacakge on hackage that has the same name but different versions.
Can I somehow solve this issue without renaming my own app?
Quoting the Cabal user guide (emphasis mine):
Package names and versions
All packages have a name, e.g. “HUnit”. Package names are assumed to be unique. Cabal package names can use letters, numbers and hyphens, but not spaces. The namespace for Cabal packages is flat, not hierarchical.
Accordingly, the Cabal library doesn't have a feature for handling package name conflicts, and neither do cabal-install nor stack. That being so, you will have to rename your package.
P.S.: I am deliberately not considering seriously the possibility of setting up your project to use a private Hackage that excludes the homonymous package, both because I don't know how it would play out in practice and because it is vastly more trouble than it is worth.

My installed transformers version is not considered by cabal-install

I am totally new to Haskell an cabal and I'm trying to make yesod work.
My cabal version is cabal-install version 1.20.0.3
using version 1.20.0.2 of the Cabal library
This is what happends when I tru to install alex:
$ cabal install alex
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: alex-3.1.4 (user goal)
next goal: QuickCheck (dependency of alex-3.1.4)
rejecting: QuickCheck-2.8.1, 2.8 (global constraint requires ==2.7.6)
trying: QuickCheck-2.7.6
next goal: transformers (dependency of QuickCheck-2.7.6)
rejecting: transformers-0.4.3.0, 0.4.2.0, 0.4.1.0, 0.3.0.0, 0.2.2.1, 0.2.2.0,
0.2.1.0, 0.2.0.0, 0.1.4.0, 0.1.3.0, 0.1.1.0, 0.1.0.1, 0.1.0.0, 0.0.1.0,
0.0.0.0, 0.4.0.0 (global constraint requires installed instance)
Dependency tree exhaustively searched.
Second attempt:
$ cabal install alex happy yesod-bin --allow-newer
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: alex-3.1.4 (user goal)
trying: QuickCheck-2.7.6/installed-1a8... (dependency of alex-3.1.4)
trying: tf-random-0.5/installed-ef3... (dependency of
QuickCheck-2.7.6/installed-1a8...)
next goal: primitive (dependency of tf-random-0.5/installed-ef3...)
rejecting: primitive-0.5.0.1/installed-8e5... (global constraint requires
==0.6)
rejecting: primitive-0.6 (conflict: tf-random =>
primitive==0.5.0.1/installed-8e5...)
rejecting: primitive-0.5.4.0, 0.5.3.0, 0.5.2.1, 0.5.1.0, 0.5.0.1, 0.5, 0.4.1,
0.4.0.1, 0.4, 0.3.1, 0.3, 0.2.1, 0.2, 0.1 (global constraint requires ==0.6)
Dependency tree exhaustively searched.
What do I have to do to install alex?
A related question is this one:
cabal install --- global constraint requires installed instance
The comment by #kosmikus on that question is:
So the Stackage LTS config file contains the constraint transformers
installed, meaning that only an already present version of
transformers can be used. This is reasonable, because GHC ships with a
specific version of transformers. For ghc-7.8, this is
transformers-0.3.0.0. For some reason, this installed version is not
considered by cabal-install. Your partial log doesn't contain
sufficient info to see why.
How can I fix my Stackage LTS config file? Where is it on Ubuntu?
Try this cabal install alex --allow-newer
The reason of the problem was that my GHC was too old. I downloaded a newer version and solved the problem.
Failed (and wrong) attempt
You should have a cabal.config file in your current directory. Open it with any text editor and serach for the transformers installed string.
Once you have found it, replace it with transformers ==0.4.3.0 or any other version you like.
It is a bad solution, because, as dfeurer writes:
transformers sits very far down in the package dependency structure. I
believe it depends only on base; I imagine a large majority of
packages on Hackage depend, directly or indirectly, on it. If you
upgrade transformers, practically every dependency in the system will
go screwy, which is the opposite of what you're going for if you're
using Stackage.
Clean solution by Sibi
Use the stackage packages as it is. If you have some global package causing problem, then remove them and use stackage exclusively. Also using sandbox for each project is a good idea.

Resources