Fixing "breaking packages"
marlowsd at gmail.com
Fri Mar 1 22:19:51 CET 2013
On 01/03/13 18:24, Max Bolingbroke wrote:
> On 1 March 2013 14:15, Ian Lynagh <ian at well-typed.com> wrote:
>> On Fri, Mar 01, 2013 at 03:02:41PM +0100, Jan Stolarek wrote:
>>> fixing things. I would like cabal to prevent such things from
>>> ever happening, the same way that
>>> Linux rpm/deb managers keep packages on the system in a consistent state.
>> There's one big difference here: rpm/dpkg are only used to install
>> things by the system administrator. But in the case of Cabal, a user
>> could install 'mypackage' (in their user package database) and the next
>> day the sysadmin could install a different instance of 'mypackage' in
>> the global database.
> I thought that "cabal install" should be viewed as installing an
> instance of the requested package by recompiling the whole transitive
> closure of dependencies from scratch, in a sort of NixOS-like way.
> Given this view, Cabal's reuse of already compiled and installed
> packages is purely an optimization that can prevent it from
> recompiling some things if it is absolutely certain that doing so is
> unnecessary. The problem then is just that Cabal is currently brokenly
> unable to handle multiple instances of an installed package with the
> same name and version.
Cabal comes under fire a lot, so I'd like to point out that it's not
just Cabal that can't handle this right now, GHC can't either :-)
And various people have been thinking a lot about how to fix it, there
was even a SoC project last year to tackle it. The design notes are here:
> In this view, the existence of local and global
> databases is straightforward: packages should always be installed in
> the most-accessible DB to which you have write permissions (for
> maximum sharing) and should be sourced from whichever is convenient
> when they are required.
Right - when the DB is semantically just a cache, it doesn't matter
whether stuff is installed in the global or local database. All those
problems just go away.
> It seems to me that the ideal mental model for "cabal install
> mylibrary-1.1" is that it appends to a global mapping from package
> name to version which are essentially the packages that are available
> when you do "ghc -package mylibrary" and when using ghci. Cabals
> promise should be that it adds the requested package to the global
> mapping and then recompiles *everything* on your system as necessary
> in order to make it possible for every package in that global mapping
> to be imported simultaneously into a GHCi session.
The new library that you just asked to be installed might be
incompatible with some other libraries that you asked to be installed,
and yet you want to be able to use them both with GHCi (just not at the
same time). I don't think we should prevent the user from doing that.
So whether "cabal install foo-1.0" should store some state somewhere
that says the user prefers foo-1.0 over other versions of foo is an
interesting question. (see the section "Simplistic Dependency
Resolution" on the wiki page for some other thoughts on this). One
stance is that "cabal install foo-1.0" should do nothing except populate
the cache; that is, it is semantically a no-op. To have it modify some
state breaks this nice no-op notion.
More information about the ghc-devs