Ticket #220 (closed enhancement: fixed)

Opened 10 months ago

Last modified 10 months ago

detect inconsistent package dependencies

Reported by: duncan Assigned to:
Priority: normal Milestone:
Component: Cabal library Version: 1.2.3.0
Severity: normal Keywords:
Cc: Difficulty: hard (< 1 day)
GHC Version: 6.8.2 Platform:

Description

Now that packages are more fine grained and upgradeable we're commonly getting situations where we build a package that uses two other packages that were built against different versions of another common package.

The most common example in the wild at the moment is people installing bytestring-0.9.0.4 in addition to the bytestring-0.9.0.1 that came with ghc-6.8.2 and then half their packages are built against one version and half against the other and when they try to use packages built against different versions we get a type error about bytestring-0.9.0.1:Data.ByteString.ByteString not being the same as bytestring-0.9.0.4:Data.ByteString.ByteString.

Cabal could and should detect this situation, and cabal-install should plan around it in its dependency resolution algorithm. However in both cases we require the dependency information of the existing installed packages.

See http://hackage.haskell.org/trac/ghc/ticket/1839

The simplest thing is to get the full InstalledPackageInfo for all the packages in the package databases. From that we can find all the dependencies.

When we do find this situation it is not guaranteed to cause a compiler error, it's just rather likely. So it's not obvious if Cabal should warn or error. cabal-install could try to fix up inconsistencies but in general only by re-installing existing packages against different versions of their dependencies.

The longer term solution is to allow installing multiple instances of the same versions of a package built against different versions of its dependencies. This is the functional Nix approach however it would probably also require support from ghc.

Change History

(in reply to: ↑ description ) 01/27/08 11:29:25 changed by ross@soi.city.ac.uk

Replying to duncan:

The longer term solution is to allow installing multiple instances of the same versions of a package built against different versions of its dependencies. This is the functional Nix approach however it would probably also require support from ghc.

Couldn't this lead to an exponential explosion in the number of package instances?

02/02/08 09:04:50 changed by duncan

This is a serious problem, package developers have responed by hard-coding package versions which they happen to know work with ghc-6.8.2 without hitting this problem.

For example yi-0.3 specifies:

build-depends: bytestring ==0.9.0.1
            -- >= 0.9 && < 0.9.0.4

It is clear that the real dependency is >= 0.9 && < 0.9.1 because the API is exactly the same for the 0.9.0.x series. However because yi depends on the ghc package, with ghc-6.8.2 we would hit the problem that the ghc package is built with bytestring-0.9.0.1. So hard coding the bytestring version is a quick fix but it means of course that this package will not work with any other version of ghc and cannot take advantage of rebuilding the ghc package to use a different bytestring version.

The solution is for the package manger to resolve this problem and not for packages to hard code binary dependencies, they should stick to api dependencies.

02/19/08 05:56:17 changed by duncan

  • status changed from new to closed.
  • resolution set to fixed.
Tue Feb 19 00:01:39 GMT 2008  Duncan Coutts <duncan@haskell.org>
  * Detect broken and inconsistent package deps
  We now check for packages that are broken due to their dependencies having
  been unregistered. We fail and print a fairly sensible message in this case.
  We also check for inconsistent dependencies and give a warning saying which
  packages are depending on inconsistent versions of a third. This is a warning
  not an error because it does not always lead to failure. Hopefully it'll help
  people who are otherwise just running into random compile errors.
  This fixes ticket #220.

We now get warnings like this:

Configuring Foo-1.0...
Warning: This package indirectly depends on multiple versions of the same
package. This is highly likely to cause a compile failure.
package rss-3000.0.1 requires HaXml-1.13.3
package Foo-1.0 requires HaXml-1.19.2

This was for a Foo-1.0 package that depended on rss and HaXml where both HaXml-1.13.3 and HaXml-1.19.2 were available but rss had been built against the older HaXml-1.13.3. So by default we're still picking the latest HaXml version but now we warn that we got inconsistent versions.

In this example it would be possible to avoid the inconsistency by picking HaXml-1.13.3. That is the next step.