Clone this wiki locally
Let's say I want to see if I can compile my project against the latest in the LTS 1 series. For the sake of demonstration, let's pretend that
semigroups is my project. :P
$ cabal unpack semigroups-0.16.2.2 $ cd semigroups-0.16.2.2 $ stackage sandbox init lts/1 Writing a default package environment file to /home/dan/semigroups-0.16.2.2/cabal.sandbox.config Using an existing sandbox located at /home/dan/.stackage/sandboxes/ghc-7.8.4/lts-1.15
stackage sandbox init wrote a
cabal.config and a
cabal.sandbox.config for us.
The latest in the lts/1 series is lts-1.15, and I've already installed some things in that sandbox before.
$ cabal install --only-dependencies Resolving dependencies... Notice: installing into a sandbox located at /home/dan/.stackage/sandboxes/ghc-7.8.4/lts-1.15 Configuring nats-1... Building nats-1... Installed nats-1
Some of the dependencies of my project were already installed in the sandbox. But
nats was not. Cabal gives us a nice notice about where the sandbox is located when it performs the install. Note that it picked nats-1 because that's what our generated
cabal.config told it to pick.
$ cat cabal.config | grep nats nats ==1,
When working with shared sandboxes, I recommend using
cabal build and avoiding
cabal install. Semigroups is actually already part of stackage. What happens if we cabal install it?
$ cabal install ... Installed semigroups-0.16.2.2
As it happens, the version number in my local
semigroups.cabal matches the constraint in
$ cat cabal.config | grep semigroups semigroups ==0.16.2.2,
So if you try to
cabal install a local project into a shared sandbox, it will work, as long as the local
cabal.config constraint agrees with the version number found in
yourproject.cabal. You probably don't want to install local modifications into your shared sandbox, which is why I recommend using
cabal build instead of
cabal install to build your local projects.
Let's go ahead and remove that from our sandbox db.
$ stackage sandbox unregister semigroups
stackage sandbox unregister is just a wrapper around
ghc-pkg unregister that conveniently detects the location of your sandbox package-db and passes it in as an argument for you. You can see what's in the sandbox with
stackage sandbox list:
$ stackage sandbox list /home/dan/.stackage/sandboxes/ghc-7.8.4/lts-1.15/x86_64-linux-ghc-7.8.4-packages.conf.d hashable-188.8.131.52 nats-1 text-184.108.40.206 unordered-containers-0.2.5.1
Again, just a light wrapper around
Let's see what happens when we try to install an older version of semigroups:
$ cd .. $ cabal unpack semigroups-0.16.2.1 $ cd semigroups-0.16.2.1 $ stackage sandbox init lts-1.15 Writing a default package environment file to /home/dan/semigroups-0.16.2.1/cabal.sandbox.config Using an existing sandbox located at /home/dan/.stackage/sandboxes/ghc-7.8.4/lts-1.15 $ # notice it reused the same lts-1.15 sandbox $ cabal install --only-dependencies ... rejecting: semigroups-0.16.2.2/installed-c36..., 0.16.2.2 (global constraint requires ==0.16.2.1) rejecting: semigroups-0.16.2.1 (global constraint requires ==0.16.2.2) ...
First of all,
cabal install --only-dependencies failed, because even though I specified only dependencies, cabal is mad at me for trying to install the wrong version of semigroups. Which I'm not... but whatever.
I can use
cabal install dep1 dep2 dep3 to manually install the dependencies I need. But since this is a shared sandbox, I already have those dependencies installed from last time.
Thankfully, cabal isn't as annoying about
$ cabal build
It builds! But if you try to install...
$ cabal install ... rejecting: semigroups-0.16.2.2/installed-c36..., 0.16.2.2 (global constraint requires ==0.16.2.1) rejecting: semigroups-0.16.2.1 (global constraint requires ==0.16.2.2) ...
It will stop you, because you're trying to install a version of
semigroups that differs from the constraint in lts-1.15, which your local
cabal.config is enforcing for you. This is good. We don't want to mess up the shared lts-1.15 sandbox.
Notice that stackage is allowing us to do something that has traditionally been quite difficult: running a build as though we had rolled back hackage to some point in the past. We can select a stackage snapshot from any point in time, and build stuff against it. Like
cabal freeze, we can use stackage snapshots as a reference point to share build strategies with other people. Unlike
cabal freeze, stackage snapshots are predetermined and public. If you and I both develop our projects against the same stackage snapshot, then we can prevent the "cabal butterfly effect".
Sandbox management via
stackage sandbox extends these benefits of stackage to shared sandboxes. By sharing sandboxes, we can strike a balance between the extremes of installing everything in userspace, and installing everything in a new sandbox for every project. Of course, if you are doing weird stuff with your sandbox for a given project, you might not want to share that sandbox with your other projects. But for projects that you simply want to build against a given stackage snapshot,
stackage sandbox is for you!