2012-02-15 10 views
15

Dopo aver eliminato tutti i miei cabal install pacchetti ED, ho fatto questa sessione seguente:Haskell Cabal: "pacchetto dipende indirettamente su più versioni dello stesso pacchetto"

$ cabal update 
Downloading the latest package list from hackage.haskell.org 
[email protected]:~/.cabal/packages$ cabal install cabal-dev 
Resolving dependencies... 
Downloading cabal-dev-0.9.1... 
[1 of 1] Compiling Main    (/tmp/cabal-dev-0.9.124882/cabal-dev-0.9.1/Setup.hs, /tmp/cabal-dev-0.9.124882/cabal-dev-0.9.1/dist/setup/Main.o) 
Linking /tmp/cabal-dev-0.9.124882/cabal-dev-0.9.1/dist/setup/setup ... 
Configuring cabal-dev-0.9.1... 
Warning: This package indirectly depends on multiple versions of the same 
package. This is highly likely to cause a compile failure. 
package containers-0.4.2.1 requires array-0.4.0.0 
package Cabal-1.14.0 requires array-0.4.0.0 
package text-0.11.1.13 requires array-0.4.0.0 
package deepseq-1.3.0.0 requires array-0.4.0.0 
package containers-0.4.2.1 requires array-0.4.0.0 
package HTTP-4000.2.2 requires array-0.4.0.0 
package cabal-dev-0.9.1 requires containers-0.4.2.1 
package Cabal-1.14.0 requires containers-0.4.2.1 
package template-haskell-2.7.0.0 requires containers-0.4.2.1 
Building cabal-dev-0.9.1... 
Preprocessing executable 'ghc-pkg-6_8-compat' for cabal-dev-0.9.1... 
<command line>: cannot satisfy -package-id Cabal-1.14.0-4af45d3c8d10dc27db38ae0e7e5a952b: 
    Cabal-1.14.0-4af45d3c8d10dc27db38ae0e7e5a952b is unusable due to missing or recursive dependencies: 
     array-0.4.0.0-46f61f5fd9543ebf309552ef84dccc86 containers-0.4.2.1-98f9aa15f9c08b13673dc9d89385f449 
    (use -v for more information) 
cabal: Error: some packages failed to install: 
cabal-dev-0.9.1 failed during the building phase. The exception was: 
ExitFailure 1 
$ 

Quindi la ragione non posso installare cabal-dev è apparentemente che

  • "dipende indirettamente da più versioni dello stesso pacchetto." Tuttavia, cabal non assegna un nome al pacchetto che afferma che cabal-dev richiede più versioni di.
  • Cabal-1.14.0 ha "dipendenze mancanti o ricorsive", in particolare in qualche modo coinvolge array-0.4.0.0 e containers-0.4.2.1.

Un grafico delle dipendenze che elenca conferma che nessuna di queste affermazioni sono vere (o le dipendenze vengono elencati sono false o incomplete):

claimed dependency graph of cabal-dev-0.9.1

Quindi: che cosa mi manca? Chi o cosa non è corretto: me, cabal o uno o più pacchetti?

Sono in esecuzione:

$ cabal --version 
cabal-install version 0.10.2 
using version 1.10.1.0 of the Cabal library 
$ ghc --version 
The Glorious Glasgow Haskell Compilation System, version 7.4.1 
$ 
+0

Sembra come se qualcosa fosse una matrice e contenitori ricostruiti. Quali sono gli hash per la descrizione di 'ghc-pkg describe'? –

+1

@eegg come hai generato quel grafico? – jberryman

risposta

10

Il problema sorge quando abbiamo pacchetto B e C già installato, ma costruito contro le diverse versioni di D e poi cerchiamo di usare entrambi i pacchetti B e C insieme nel pacchetto A : Problema di dipendenza dal diamante Questo può funzionare correttamente, ma solo se i pacchetti B e C non espongono i tipi definiti in D nelle loro interfacce. Se lo fanno allora il pacchetto A non sarà in grado di utilizzare le funzioni di B e C insieme perché non funzioneranno con lo stesso tipo. Questo è che otterrai un errore di tipo.

Per scegliere un esempio concreto, si supponga che il pacchetto D sia sottotesto e che siano installati sia bytestring-0.9.0.1 che 0.9.0.4. Diciamo che B è utf8-string e C è regex-base. Diciamo che il pacchetto A è il programma editor di Yi. Quindi il punto è che, in qualche punto del codice di Yi, vogliamo passare un test scritto come risultato della decodifica UTF-8 come input per una delle funzioni regex. Ma questo non funziona perché le funzioni nel pacchetto utf8 string usano il tipo ByteString da bytestring-0.9.0.1 mentre le funzioni regex nel pacchetto regex usano il tipo ByteString da bytestring-0.9.0.4. Così otteniamo un errore di tipo quando cerchiamo di compilare Yi:

Potrebbe non corrispondono attesi tipo bytestring-0.9.0.4:Data.ByteString.ByteString' against inferred type bytestring-0.9.0.1: Data.ByteString.ByteString'

Per quanto sa GHC, questi due tipi sono totalmente estraneo!

Questo è ovviamente estremamente fastidioso. Non c'è anche una soluzione facile. In questo esempio si presuppone che i pacchetti B e C siano già stati creati, quindi non c'è davvero modo di utilizzare i due pacchetti in modo ragionevole senza ricostruirli su una versione diversa del pacchetto D. In questo caso la soluzione ovvia è ricostruire B per usare D-1.1 piuttosto che D-1.0. Il problema con la ricostruzione di un pacchetto, ovviamente, è la rottura di tutti gli altri pacchetti che sono già stati creati contro di esso. Non è chiaro se si desidera che un gestore di pacchetti ricominci automaticamente molti pacchetti apparentemente non correlati.

A più lungo termine la soluzione migliore sembra essere quella di fare ciò che Nix fa.Nell'esempio sopra, invece di sostituire il pacchetto B costruito contro D-1.0 con B costruito contro D-1.1, Nix aggiungerebbe un'altra istanza di B costruita contro D-1.1. Quindi l'istanza originale di B rimarrebbe invariata e nulla si spezzerebbe. È l'approccio funzionale: non modifichiamo mai i valori (pacchetti installati), ne creiamo solo di nuovi e li raccogliamo vecchi quando non sono più necessari.

In pratica significa che dobbiamo identificare i pacchetti installati utilizzando alcuni hash del pacchetto e gli hash di tutti i pacchetti dipendenti. jhc lo fa già e ci sono mosse in atto per fare qualcosa di simile per GHC, anche se mirava più a tenere traccia delle modifiche API/ABI. Per una sana gestione dei pacchetti basata su sorgenti, penso che sia la giusta direzione da prendere.

Devo notare che questo non è un nuovo problema. Siete stati in grado di costruire questo problema sin da quando ghc ha iniziato a consentire l'installazione di più versioni dello stesso pacchetto in una sola volta. Lo stiamo notando molto più spesso ora perché abbiamo diviso il pacchetto base e permesso l'aggiornamento di quei pacchetti split-out.

Lo stato attuale del gioco è che Cabal mette in guardia da questo problema ma in realtà non aiuta a risolverlo. Per l'esempio precedente otterremmo:

$ cabal configure 
Configuring A-1.0... 
Warning: This package indirectly depends on multiple versions of 
the same package. This is highly likely to cause a compile failure. 
package B-1.0 requires D-1.0 
package C-1.0 requires D-1.1 
Problemi correlati