Compile Haskell program with third-party dependencies - haskell

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

Related

Why does omitting cabal-version cause the build to fail?

I have a minimal example project:
Test
Test
Test.hs
Test.cabal
Test.hs contains an empty module Test.Test. The contents of Test.cabal are as follows:
name: Test
version: 0.0.0
library
build-depends: base
exposed-modules: Test.Test
Running cabal build fails with a long, confusing error message (copied below) unless I add cabal-version: 2.2 to the cabal file. Higher than 2.2 works as well but lower versions result in a similar error. My cabal version is 3.2. Why does the build fail unless I specify a cabal version and why are versions lower than 2.2 not sufficient?
The error message that I get without specifying cabal version is as follows:
Resolving dependencies...
cabal.exe: Could not resolve dependencies:
[__0] trying: Test-0.0.0 (user goal)
[__1] next goal: Test:setup.Cabal (dependency of Test)
[__1] rejecting: Test:setup.Cabal-3.2.0.0/installed-3.2.0.0 (conflict: Test =>
Test:setup.Cabal>=0 && <1.25)
[__1] skipping: Test:setup.Cabal-3.6.3.0, Test:setup.Cabal-3.6.2.0,
Test:setup.Cabal-3.6.1.0, Test:setup.Cabal-3.6.0.0, Test:setup.Cabal-3.4.1.0,
Test:setup.Cabal-3.4.0.0, Test:setup.Cabal-3.2.1.0, Test:setup.Cabal-3.2.0.0,
Test:setup.Cabal-3.0.2.0, Test:setup.Cabal-3.0.1.0, Test:setup.Cabal-3.0.0.0,
Test:setup.Cabal-2.4.1.0, Test:setup.Cabal-2.4.0.1, Test:setup.Cabal-2.4.0.0,
Test:setup.Cabal-2.2.0.1, Test:setup.Cabal-2.2.0.0, Test:setup.Cabal-2.0.1.1,
Test:setup.Cabal-2.0.1.0, Test:setup.Cabal-2.0.0.2 (has the same
characteristics that caused the previous version to fail: excluded by
constraint '>=0 && <1.25' from 'Test')
[__1] rejecting: Test:setup.Cabal-1.24.2.0, Test:setup.Cabal-1.24.0.0,
Test:setup.Cabal-1.22.8.0, Test:setup.Cabal-1.22.7.0,
Test:setup.Cabal-1.22.6.0, Test:setup.Cabal-1.22.5.0,
Test:setup.Cabal-1.22.4.0, Test:setup.Cabal-1.22.3.0,
Test:setup.Cabal-1.22.2.0, Test:setup.Cabal-1.22.1.1,
Test:setup.Cabal-1.22.1.0, Test:setup.Cabal-1.22.0.0,
Test:setup.Cabal-1.20.0.4, Test:setup.Cabal-1.20.0.3,
Test:setup.Cabal-1.20.0.2, Test:setup.Cabal-1.20.0.1,
Test:setup.Cabal-1.20.0.0, Test:setup.Cabal-1.18.1.7,
Test:setup.Cabal-1.18.1.6, Test:setup.Cabal-1.18.1.5,
Test:setup.Cabal-1.18.1.4, Test:setup.Cabal-1.18.1.3,
Test:setup.Cabal-1.18.1.2, Test:setup.Cabal-1.18.1.1, Test:setup.Cabal-1.18.1,
Test:setup.Cabal-1.18.0, Test:setup.Cabal-1.16.0.3, Test:setup.Cabal-1.16.0.2,
Test:setup.Cabal-1.16.0.1, Test:setup.Cabal-1.16.0, Test:setup.Cabal-1.14.0,
Test:setup.Cabal-1.12.0, Test:setup.Cabal-1.10.2.0, Test:setup.Cabal-1.10.1.0,
Test:setup.Cabal-1.10.0.0, Test:setup.Cabal-1.8.0.6, Test:setup.Cabal-1.8.0.4,
Test:setup.Cabal-1.8.0.2, Test:setup.Cabal-1.6.0.3, Test:setup.Cabal-1.6.0.2,
Test:setup.Cabal-1.6.0.1, Test:setup.Cabal-1.4.0.2, Test:setup.Cabal-1.4.0.1,
Test:setup.Cabal-1.4.0.0, Test:setup.Cabal-1.2.4.0, Test:setup.Cabal-1.2.3.0,
Test:setup.Cabal-1.2.2.0, Test:setup.Cabal-1.2.1, Test:setup.Cabal-1.1.6,
Test:setup.Cabal-1.24.1.0 (constraint from minimum version of Cabal used by
Setup.hs requires >=3.2)
[__1] fail (backjumping, conflict set: Test, Test:setup.Cabal)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: Test:setup.Cabal, Test

How to install a local library using Cabal?

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.

How to override hackage depedency in Stack with git branch

I am experiencing trouble with proto-lens library on GHC 8.10.
It has not been supported. Team fixed issue, but didn't published update on Hackage and I am trying to pull the fix just from github tag.
I don't see any difference in building process after added following section to stack.yaml
allow-newer: true
extra-deps:
- github: google/proto-lens
commit: 0bef8c2f3da645f068b8a26ac168c1da41608182
subdirs: proto-lens
I guess I missed something.
It is not clear for me how Stack sees this custom dependency.
Where is association that it is source for proto-len?
What if I made a typo in subdirs or url?
So Stack could get something else and it could be even a correct Stack library, but not proto-lens.
Log of failing build
Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.0.2.0 supports
'ghc' version < 8.10): /opt/ghc/8.10.1/bin/ghc is version 8.10.1
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: megaexample-0.4.2 (user goal)
[__1] trying: base-4.14.0.0/installed-4.1... (dependency of megaexample)
[__2] trying: opentelemetry-extra-0.4.2 (user goal)
[__3] next goal: proto-lens (dependency of opentelemetry-extra)
[__3] rejecting: proto-lens-0.6.0.0 (conflict:
base==4.14.0.0/installed-4.1..., proto-lens => base>=4.10 && <4.14)
[__3] rejecting: proto-lens-0.5.1.0, proto-lens-0.5.0.1, proto-lens-0.5.0.0,
proto-lens-0.4.0.1 (conflict: base==4.14.0.0/installed-4.1..., proto-lens =>
Another supplementary question: where is library version in Stack specified?
Stack starts with 0.6, but there is no such literal in the source tree.
Link to source
Should I tweak cabal file also?
The proto-lens library is referenced in cabal file.
executable eventlog-to-opentelemetry
import: options
main-is: Main.hs
hs-source-dirs: exe/eventlog-to-opentelemetry
other-modules: Console, Json, Resource, Attribute, Spans
build-depends:
aeson,
base,
bytestring,
clock,
filepath,
microlens,
microlens-th,
opentelemetry >= 0.4.0,
opentelemetry-extra,
opentelemetry-proto,
optparse-applicative,
proto-lens,
text,
unordered-containers,
default-language: Haskell2010
Log of failing build
That error log is from cabal, not stack. cabal doesn't read stack.yaml, but cabal.project.
Here is the relevant part of cabal's documentation to specify remote dependencies: Cabal user manual
stack wouldn't try different versions of packages. The stack.yaml file specifies package versions upfront: every package is set to at most one specific version, either via extra-deps (where you specify individual packages explicitly) or resolver (which is a whole set of specific package versions, that you can browse on https://stackage.org).
I guess I missed something. It is not clear for me how Stack sees this custom dependency. Where is association that it is source for proto-len? What if I made a typo in subdirs or url? So Stack could get something else and it could be even a correct Stack library, but not proto-lens.
It is indeed strange that doesn't seem to have an option to explicitly name the expected remote packages. This is an issue worth bringing up to stack maintainers.

Cabal sandbox is using a global dependency. Could not resolve

I'm trying to add timerep onto an existing application. I can't get it to resolve my dependencies. It looks like it is using the globally installed version of time == 1.4.2, when >= 1.5 would be ideal for my application.
How can I get cabal to use time 1.5? I've poked through unix, tls, process, timerep, and they all seem like they would work fine if it would just use time >= 1.5.
Here's the error:
serials> cabal install --only-dependencies
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: serials-0.1.0.2 (user goal)
trying: mandrill-0.2.2.0 (dependency of serials-0.1.0.2)
trying: http-client-tls-0.2.2 (dependency of mandrill-0.2.2.0)
trying: tls-1.2.17 (dependency of http-client-tls-0.2.2)
trying: x509-validation-1.5.2 (dependency of tls-1.2.17)
trying: process-1.2.0.0/installed-487... (dependency of x509-validation-1.5.2)
next goal: unix (dependency of process-1.2.0.0/installed-487...)
rejecting: unix-2.7.0.1/installed-299... (conflict: unix =>
time==1.4.2/installed-bf9..., serials => time>=1.5)
rejecting: unix-2.7.1.0, 2.7.0.1, 2.7.0.0, 2.6.0.1, 2.6.0.0, 2.5.1.1, 2.5.1.0,
2.5.0.0, 2.4.2.0, 2.4.1.0, 2.4.0.2, 2.4.0.1, 2.4.0.0, 2.3.2.0, 2.3.1.0,
2.3.0.0, 2.2.0.0, 2.0 (conflict: process => unix==2.7.0.1/installed-299...)
Dependency tree exhaustively searched.
Cabal file:
-- Initial serials.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: serials
version: 0.1.0.2
synopsis: serials
description: serials
license: MIT
license-file: LICENSE
author: Sean Hess
maintainer: Sean Hess
-- copyright:
category: Web Scraper
build-type: Simple
extra-source-files: README.md
cabal-version: >=1.10
Source-repository head
type: git
location: git#github.com:seanhess/serials.git
executable serials
main-is: Main.hs
hs-source-dirs: server
ghc-options: -fcontext-stack=36
-- other-modules:
-- other-extensions:
default-language: Haskell2010
build-depends:
base >=4.7 && <5,
tagsoup,
text,
scalpel,
containers,
network-uri,
monad-loops,
wreq,
lens,
bytestring,
parsec,
utf8-string,
tagsoup,
xml,
feed,
regex-pcre,
aeson,
network,
wai,
wai-extra,
wai-cors,
wai-middleware-static,
warp,
servant-server >= 0.4,
rethinkdb >= 1.16,
transformers,
either,
unordered-containers,
mtl,
http-types,
safe,
hashable,
resource-pool,
time >= 1.5,
pooled-io,
shelly,
string-conversions,
bcrypt,
random,
jwt,
cookie,
entropy,
mandrill == 0.2.2.0,
email-validate,
blaze-markup,
blaze-html,
iso8601-time,
scotty == 0.10.0,
timerep >= 2.0.0
It is difficult for cabal-install to produce a complete description of the mutual incompatibilities of an installation problem. It instead decides to print the first path to failure.
However, it prints Dependency tree exhaustively searched. which indicates that there actually is no solution to the given problem.
One thing that often helps is to look at the choices cabal-install has made, find one that seems suboptimal, and then add an explicit constraint to change that. This may result in a better error message.
Let's try [note that I'm not sure if I have exactly the same package DB as you have, so it may produce different results on your system].
You had (modulo hashes of installed packages):
$ cabal install --only-dependencies
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: serials-0.1.0.2 (user goal)
trying: mandrill-0.2.2.0 (dependency of serials-0.1.0.2)
trying: http-client-tls-0.2.2 (dependency of mandrill-0.2.2.0)
trying: tls-1.2.17 (dependency of http-client-tls-0.2.2)
trying: x509-validation-1.5.2 (dependency of tls-1.2.17)
trying: process-1.2.0.0/installed-06c... (dependency of x509-validation-1.5.2)
next goal: unix (dependency of process-1.2.0.0/installed-06c...)
rejecting: unix-2.7.0.1/installed-f86... (conflict: unix =>
time==1.4.2/installed-9b3..., serials => time>=1.5)
rejecting: unix-2.7.1.0, 2.7.0.1, 2.7.0.0, 2.6.0.1, 2.6.0.0, 2.5.1.1, 2.5.1.0,
2.5.0.0, 2.4.2.0, 2.4.1.0, 2.4.0.2, 2.4.0.1, 2.4.0.0, 2.3.2.0, 2.3.1.0,
2.3.0.0, 2.2.0.0, 2.0 (conflict: process => unix==2.7.0.1/installed-f86...)
Dependency tree exhaustively searched.
Looking through this, the error occurs with unix, which is a dependency of process. So the installed instance of process being chosen leads to trouble. So what if we disallow choosing that instance of process?
$ cabal install --only-dependencies --constraint="process source"
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: serials-0.1.0.2 (user goal)
next goal: time (dependency of serials-0.1.0.2)
rejecting: time-1.4.2/installed-9b3... (conflict: serials => time>=1.5)
trying: time-1.5.0.1
next goal: rethinkdb (dependency of serials-0.1.0.2)
rejecting: rethinkdb-1.16.0.0 (conflict: time==1.5.0.1, rethinkdb =>
time==1.4.*)
rejecting: rethinkdb-1.15.2.1, 1.15.2.0, 1.15.1.0, 1.15.0.0, 1.8.0.5, 1.8.0.4,
1.8.0.3, 1.8.0.2, 1.8.0.1, 1.8.0.0, 0.1.0.0 (conflict: serials =>
rethinkdb>=1.16)
Dependency tree exhaustively searched.
Aha! So rethinkdb, which is a direct dependency of serials, has an explicit dependency on time == 1.4.*. This is in direct conflict with the dependency of serials on time >= 1.5.
This is not easy to fix. You either need to make rethinkdb work with the newer time library, or serials with the older.
We enter the realm of speculation now: It is possible, but not guaranteed, that rethinkdb actually works with a newer version of time. We can try to instruct cabal-install to consider such install plans:
$ cabal install --only-dependencies --allow-newer=time
This actually yields an install plan on my machine. I have not tried building it, and I don't know whether it works. But it may be worth a try.

Error "unknown package: ghc" when building heroku app with yesod

I'm trying to build a heroku app with a new version of yesod (1.1.9), unfortunately it fails becauce of the ghc-paths dependency (yesod version 1.1.2 works since it does not have this dependency). I tried various dependencies and all possible ghc-paths versions, but in the end I always get this awkward error message that ghc is an unknown package. A local build works just fine with the same dependencies.
main-is: main.hs
hs-source-dirs: app
build-depends: base == 4.5.*
, http-types
, shakespeare == 1.0.2
, template-haskell
, wai
, wai-extra
, warp
, yesod == 1.1.9
.
[176] rejecting: ghc-paths-0.1.0.9 (unknown package: ghc)
[__6] fail (backjumping, conflict set: TestHeroku, ghc, yesod)
[__5] rejecting: yesod-1.1.8.2, ... , 0.0.0.2, 0.0.0.1, 0.0.0 (conflict: TestHeroku => yesod==1.1.9)
[__0] fail (backjumping, conflict set: TestHeroku, ghc, yesod)
Shakespeare is needed because of the error mentioned here and I use the heroku-buildpack-haskell.
If anyone struggles with the same problem, I took matters into my own hands and created a new buildpack based on the versions that are already circulating. It runs with yesod-1.1.9.
https://github.com/ichistmeinname/heroku-buildpack-haskell

Resources