Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cabal install sandbox can't reinstall base or any other dependencies

EDIT FOR FUTURE SOULS STUMBLING ONTO THIS:

It would be unwise to copy any of my commands below, do not execute them. Just check out Zeta's answer for why I was approaching this incorrectly.

ORIGINAL QUESTION

My sandbox seems to be getting caught on a global version of some packages rather than using the sandbox versions. I've looked around on SO for answers to this, and many of the questions are answered without specific instructions to resolve this, or were slightly different, so I can't seem to get my setup running. Here's what I have:

1. Version of cabal is old:

$ cabal --v
cabal-install version 1.16.0.2
using version 1.16.0 of the Cabal library 

Oh dear, this is old and won't run sandbox.

2. Install cabal with cabal
$ cabal install cabal
Resolving dependencies...
Downloading Cabal-1.22.6.0...

...lots of stuf...

Registering Cabal-1.22.6.0...
Installed Cabal-1.22.6.0

Looks good.

3. Try it out:
$ cabal sandbox init
cabal: unrecognised command: sandbox (try --help)

Hmm.

$ which cabal
/usr/bin/cabal

Ahh.

$ ${HOME}/.cabal/bin/cabal --version
cabal-install version 1.22.2.0
using version 1.22.2.0 of the Cabal library 

Aha.

$ export PATH="${HOME}/.cabal/bin/:$PATH"
$ export PATH="${HOME}/.cabal/libs/:$PATH"

$ cabal --v
cabal-install version 1.22.2.0

Great.

4. Try it out again:
$ cabal sandbox init
Writing a default package environment file to
.../cabal.sandbox.config
Creating a new sandbox at .../.cabal-sandbox

$ cabal install Frames
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: Frames-0.1.2.1 (user goal)
next goal: base (dependency of Frames-0.1.2.1)
rejecting: base-4.6.0.1/installed-8aa... (conflict: Frames => base>=4.7 &&
<4.9)
rejecting: base-4.8.2.0, 4.8.1.0, 4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0, 4.6.0.1,
4.6.0.0, 4.5.1.0, 4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0, 4.3.0.0, 4.2.0.2,
4.2.0.1, 4.2.0.0, 4.1.0.0, 4.0.0.0, 3.0.3.2, 3.0.3.1 (global constraint
requires installed instance)
Dependency tree exhaustively searched.

Note: when using a sandbox, all packages are required to have consistent
dependencies. Try reinstalling/unregistering the offending packages or
recreating the sandbox.

Huh, so base is not compatible, OK.

$ cabal install base --reinstall
Resolving dependencies...
cabal: Could not resolve dependencies:
next goal: base (user goal)
rejecting: base-4.8.2.0, 4.8.1.0, 4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0, 4.6.0.1,
4.6.0.0, 4.5.1.0, 4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0, 4.3.0.0, 4.2.0.2,
4.2.0.1, 4.2.0.0, 4.1.0.0, 4.0.0.0 (only already installed instances can be
used)
rejecting: base-3.0.3.2 (conflict: base => base>=4.0 && <4.3)
rejecting: base-3.0.3.1 (conflict: base => base>=4.0 && <4.2)
Dependency tree exhaustively searched.

Note: when using a sandbox, all packages are required to have consistent
dependencies. Try reinstalling/unregistering the offending packages or
recreating the sandbox.

Huh, what about all dependencies?

$ cabal install --upgrade-dependencies
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: Frames-0.1.2.1 (user goal)
next goal: base (dependency of Frames-0.1.2.1)
rejecting: base-4.8.2.0, 4.8.1.0, 4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0 (global
constraint requires installed instance)
rejecting: base-4.6.0.1/installed-8aa... (conflict: Frames => base>=4.7 &&
<4.9)
rejecting: base-4.6.0.1, 4.6.0.0, 4.5.1.0, 4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0,
4.3.0.0, 4.2.0.2, 4.2.0.1, 4.2.0.0, 4.1.0.0, 4.0.0.0, 3.0.3.2, 3.0.3.1 (global
constraint requires installed instance)
Dependency tree exhaustively searched.

Note: when using a sandbox, all packages are required to have consistent
dependencies. Try reinstalling/unregistering the offending packages or
recreating the sandbox.

Seems I cannot reinstall/unregister the offending packages. I wish the error message would give me a little more on how to do this, because the "--reinstall" flag was my best shot.

Well, it offered 2 solutions, so let's try the other, to recreate the sandbox.

$ cabal sandbox delete
Deleting the sandbox located at .../.cabal-sandbox

$ cabal sandbox init
Writing a default package environment file to
.../cabal.sandbox.config
Creating a new sandbox at .../.cabal-sandbox

$ cabal install --upgrade-dependencies
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: Frames-0.1.2.1 (user goal)
next goal: base (dependency of Frames-0.1.2.1)
rejecting: base-4.8.2.0, 4.8.1.0, 4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0 (global
constraint requires installed instance)
rejecting: base-4.6.0.1/installed-8aa... (conflict: Frames => base>=4.7 &&
<4.9)
rejecting: base-4.6.0.1, 4.6.0.0, 4.5.1.0, 4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0,
4.3.0.0, 4.2.0.2, 4.2.0.1, 4.2.0.0, 4.1.0.0, 4.0.0.0, 3.0.3.2, 3.0.3.1 (global
constraint requires installed instance)
Dependency tree exhaustively searched.

Note: when using a sandbox, all packages are required to have consistent
dependencies. Try reinstalling/unregistering the offending packages or
recreating the sandbox.

This also did not help. Fresh out of ideas. How do I use sandbox? My read here is there is a global something that is causing a problem. A sandbox should not be bothered by that by design of sandboxing, right?

If it helps context, I'm just trying to run the demo for Frames:

https://github.com/acowley/Frames

...which is:

$ cabal sandbox init
$ cabal install --dependencies-only -f demos # <-- here

I see there's a closed issue on this step, but that seems like a different issue.

like image 368
Mittenchops Avatar asked Jan 24 '16 22:01

Mittenchops


1 Answers

A look behind the stage (or: What is special about base)

The version of base is tightly coupled to a GHC version. For example, base-4.6.0.1 ships with GHC 7.6.3. You cannot use another version of base with an incompatible GHC version. In order to use base-4.7.0.x, you need GHC 7.8.x.

Therefore, you cannot use a local sandbox for base. It's one of the (very few) packages that cannot get sandboxed.

Sandboxes need a strong base

If we take the figuratively notion of a sandbox, we'll see soon that a sandbox needs some kind of foundation. And that's exactly base. Everything else can live in the sandbox, and should work:

How do I use sandbox?

You use the sandbox correctly, but you don't have the right compiler/base installed.

I don't understand why cabal let me upgrade itself into a state so inconsistent I can't do anything.

Again, Cabal isn't in an inconsistent state. Frames restricts the minimal base version to 4.7, which usually means that it uses GHC features that were introduced with GHC 7.8. Even if you were able to install base-4.7.x.y, you would still miss those GHC features.

However, it isn't recommended to use recent versions of Cabal with old versions of GHC.

Trying other lower bounds

However, sometimes a library has a too strict lower bound. Maybe Frames does work with GHC 7.6. You can check this locally:

$ cabal unpack Frames
$ cd Frames-*
$ vim Frames.cabal # change the min base to something lower
$ cabal sandbox init
$ cabal build

If this works, the lower bound on base in Frames is actually too high and you can file a pull-request on the library.

Getting new stuff in old distributions

There are now four ways for this. In decreasing order of difficulty:

  1. Install GHC and Cabal by hand from the GHC download page (not recommended, only for experienced users).
  2. Install a minimal version of GHC and Cabal, see MinGHC.
  3. Install a recent version of the Haskell platform by hand (don't forget to get rid of the old one beforehand; use the shell script, not the package via apt-get on LTS distributions).
  4. Install stack and use stack setup (easiest one).

I'll focus on the MinGHC and the Stack one, since those provide easy methods to install several GHC versions along each other.

MinGHC installation (Linux specific)

Basically follow the instructions on this site. On Ubuntu you have to add a third party source to your apt sources and install a specific version of Cabal and GHC. Note that this will install GHC and Cabal to /opt/, so you have to add some directories to your path:

sudo apt-get update
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:hvr/ghc
sudo apt-get update
sudo apt-get install -y cabal-install-1.22 ghc-7.10.3
cat >> ~/.bashrc <<EOF
export PATH="\$HOME/.cabal/bin:/opt/cabal/1.20/bin:/opt/ghc/7.10.3/bin:\$PATH"
EOF
export PATH=~/.cabal/bin:/opt/cabal/1.22/bin:/opt/ghc/7.10.3/bin:$PATH

This enables you to install other versions of cabal and GHC rather easy with

sudo apt-get install -y cabal-install-1.xx ghc-7.yy.z

and then change your PATH variable. Afterwards, you can use the cabal sandbox * commands.

I also suggest you to read Stephen Diel's notes on Cabal. They provide great insight on some commonly used features.

Using stack

Again, follow the instructions on this site. It's basically the same: you add external sources and tell your distribution to trust those sources:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 575159689BEFB442
echo 'deb http://download.fpcomplete.com/ubuntu trusty main' | sudo tee /etc/apt/sources.list.d/fpco.list
sudo apt-get update && sudo apt-get install stack -y

Afterwards, you have to use stack init in an already existing Cabal project, or stack new to install a new project, followed by stack setup, which will install a fairly recent version of GHC:

$ stack new my-project
$ cd my-project
$ stack setup
# Loooooooooooooooooooooooong log, installs GHC in background

Note that stack installs all dependencies in a "sane" way. It uses an internal LTS system, you don't have to use cabal sandboxes. However, you cannot use Cabal commands anymore, instead you have to use stack build or stack ghc.

If you don't use a package, something like

stack ghc --package Frames -- -O2 --make -rtsopts File1.hs File2.hs

is possible. However, documenting every feature of stack would break the scope of this answer and get out of date soon, so have a look at the documentation.

like image 161
Zeta Avatar answered Nov 15 '22 05:11

Zeta