Commit d80caca1 authored by Edward Z. Yang's avatar Edward Z. Yang Committed by Ben Gamari
Browse files

Error early when you register with too old a version of Cabal.



On the GHC 8.0 RCs, multiple users reported a very strange error
whereby GHC would complain that the symbols names recorded in interface
files did not match the expected name.  The reason for this is
that they were using an old version of Cabal which chose symbol
names differently from the installed package ID ('id' field) which
the package was to be installed with; GHC 8.0 now mandates that
these coincides.

This change adds a test to ghc-pkg to make sure that 'id' and 'key'
(which is how Cabal previously reported what the symbol name
was supposed to be) match; if they don't match or key is missing,
we assume that the Cabal was too old.

Bikeshed points:

    - Should we offer more information about how to upgrade
      Cabal correctly (i.e. specify a version?)

    - Should we allow for a missing 'key'?  If we allow for
      'key' to be missing, we lose the ability to detect
      Cabal from GHC 7.8 or earlier being used.  If we
      require it to be specified, then it will not be possible
      for Cabal to deprecate the (unused) field and remove it
      without having BC for 8.0.
Signed-off-by: default avatarEdward Z. Yang <ezyang@cs.stanford.edu>

Test Plan: validate

Reviewers: austin, bgamari, hvr

Reviewed By: hvr

Subscribers: bergmark, thomie

Differential Revision: https://phabricator.haskell.org/D1892

GHC Trac Issues: #11558
parent 93e2c8ff
name: T1750A name: T1750A
version: 1 version: 1
id: T1750A-1-XXX id: T1750A-1-XXX
key: T1750A-1-XXX
depends: T1750B-1-XXX depends: T1750B-1-XXX
name: T1750B name: T1750B
version: 1 version: 1
id: T1750B-1-XXX id: T1750B-1-XXX
key: T1750B-1-XXX
depends: T1750A-1-XXX depends: T1750A-1-XXX
...@@ -64,7 +64,7 @@ ghcilink004 : ...@@ -64,7 +64,7 @@ ghcilink004 :
echo 'name: test' >>$(PKG004) echo 'name: test' >>$(PKG004)
echo 'version: 1.0' >>$(PKG004) echo 'version: 1.0' >>$(PKG004)
echo 'id: test-XXX' >>$(PKG004) echo 'id: test-XXX' >>$(PKG004)
echo 'key: test-1.0' >>$(PKG004) echo 'key: test-XXX' >>$(PKG004)
echo 'library-dirs: $${pkgroot}' >>$(PKG004) echo 'library-dirs: $${pkgroot}' >>$(PKG004)
echo 'extra-libraries: foo' >>$(PKG004) echo 'extra-libraries: foo' >>$(PKG004)
'$(GHC_PKG)' init $(LOCAL_PKGCONF004) '$(GHC_PKG)' init $(LOCAL_PKGCONF004)
...@@ -92,7 +92,7 @@ ghcilink005 : ...@@ -92,7 +92,7 @@ ghcilink005 :
echo 'name: test' >>$(PKG005) echo 'name: test' >>$(PKG005)
echo 'version: 1.0' >>$(PKG005) echo 'version: 1.0' >>$(PKG005)
echo 'id: test-XXX' >>$(PKG005) echo 'id: test-XXX' >>$(PKG005)
echo 'key: test-1.0' >>$(PKG005) echo 'key: test-XXX' >>$(PKG005)
echo 'library-dirs: $${pkgroot}' >>$(PKG005) echo 'library-dirs: $${pkgroot}' >>$(PKG005)
echo 'extra-libraries: foo' >>$(PKG005) echo 'extra-libraries: foo' >>$(PKG005)
'$(GHC_PKG)' init $(LOCAL_PKGCONF005) '$(GHC_PKG)' init $(LOCAL_PKGCONF005)
...@@ -117,7 +117,7 @@ ghcilink006 : ...@@ -117,7 +117,7 @@ ghcilink006 :
echo "name: test" >>$(PKG006) echo "name: test" >>$(PKG006)
echo "version: 1.0" >>$(PKG006) echo "version: 1.0" >>$(PKG006)
echo "id: test-XXX" >>$(PKG006) echo "id: test-XXX" >>$(PKG006)
echo "key: test-1.0" >>$(PKG006) echo "key: test-XXX" >>$(PKG006)
ifeq "$(WINDOWS)" "YES" ifeq "$(WINDOWS)" "YES"
echo "extra-libraries: stdc++-6" >>$(PKG006) echo "extra-libraries: stdc++-6" >>$(PKG006)
else else
......
...@@ -1626,6 +1626,9 @@ checkUnitId :: InstalledPackageInfo -> PackageDBStack -> Bool ...@@ -1626,6 +1626,9 @@ checkUnitId :: InstalledPackageInfo -> PackageDBStack -> Bool
checkUnitId ipi db_stack update = do checkUnitId ipi db_stack update = do
let uid = installedUnitId ipi let uid = installedUnitId ipi
when (null (display uid)) $ verror CannotForce "missing id field" when (null (display uid)) $ verror CannotForce "missing id field"
when (display uid /= compatPackageKey ipi) $
verror CannotForce $ "installed package info from too old version of Cabal "
++ "(key field does not match id field)"
let dups = [ p | p <- allPackagesInStack db_stack, let dups = [ p | p <- allPackagesInStack db_stack,
installedUnitId p == uid ] installedUnitId p == uid ]
when (not update && not (null dups)) $ when (not update && not (null dups)) $
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment