2012-11-01 6 views
7

Es scheint unmöglich, Yesod zusammen mit der Darcs-Bibliothek aufgrund eines Linker-Problems zu verwenden. Ich habe das Problem aufgespürt und brauche Hinweise von Leuten, die mit Darcs Interna vertraut sind.Wie umgehen Sie doppelte Symbol Fehler bei der Verwendung von Jessod und Darcs-Bibliothek?

Bei Verwendung der darcs library in einer Yesod Anwendung, bekomme ich folgende Fehlermeldung:

GHCi runtime linker: fatal error: I found a duplicate definition for symbol 
    sha256_init 
whilst processing object file 
    /home/sebfisch/.cabal/lib/darcs-2.9.5/ghc-7.4.2/libHSdarcs-2.9.5.a 
This could be caused by: 
    * Loading two different object files which export the same symbol 
    * Specifying the same object file twice on the GHCi command line 
    * An incorrect `package.conf' entry, causing some object to be 
    loaded twice. 
GHCi cannot safely continue in this situation. Exiting now. Sorry. 

Es erscheint das gleiche Symbol, wie die Suche durch die entsprechenden Objektdateien Belichtung durch die darcs und cryptohash Bibliotheken verursacht werden enthüllt :

# for file in `find ~/.cabal/lib/ -name "*.a"`; do (readelf -s $file | grep -i sha256_init) && (echo $file; echo); done 
    293: 0000000000000000  0 NOTYPE GLOBAL DEFAULT UND sha256_init 
    17: 0000000000000690 94 FUNC GLOBAL DEFAULT 1 sha256_init 
~/.cabal/lib/cryptohash-0.7.5/ghc-7.4.2/libHScryptohash-0.7.5.a 

    10: 0000000000000290 45 FUNC GLOBAL DEFAULT 1 sha256_init 
~/.cabal/lib/darcs-2.8.2/ghc-7.4.2/libHSdarcs-2.8.2.a 

ich schrieb ein Testprogramm, um zu bestätigen, dass die darcs und cryptohash Bibliotheken sind in Konflikt:

Es scheitert mit einem ähnlichen Fehler zu kompilieren:

/home/sebfisch/.cabal/lib/cryptohash-0.7.5/ghc-7.4.2/libHScryptohash-0.7.5.a(sha256.o): In function `sha256_update': sha256.c:(.text+0x4b0): multiple definition of `sha256_update' 
/home/sebfisch/.cabal/lib/darcs-2.8.2/ghc-7.4.2/libHSdarcs-2.8.2.a(sha2.o):sha2.c:(.text+0xf90): first defined here 
/home/sebfisch/.cabal/lib/cryptohash-0.7.5/ghc-7.4.2/libHScryptohash-0.7.5.a(sha256.o): In function `sha224_update': sha256.c:(.text+0x640): multiple definition of `sha224_update' 
/home/sebfisch/.cabal/lib/darcs-2.8.2/ghc-7.4.2/libHSdarcs-2.8.2.a(sha2.o):sha2.c:(.text+0xbb0): first defined here 
/home/sebfisch/.cabal/lib/cryptohash-0.7.5/ghc-7.4.2/libHScryptohash-0.7.5.a(sha256.o): In function `sha256_init': sha256.c:(.text+0x690): multiple definition of `sha256_init' 
/home/sebfisch/.cabal/lib/darcs-2.8.2/ghc-7.4.2/libHSdarcs-2.8.2.a(sha2.o):sha2.c (.text+0x290): first defined here 
/home/sebfisch/.cabal/lib/cryptohash-0.7.5/ghc-7.4.2/libHScryptohash-0.7.5.a(sha256.o): In function `sha224_init': sha256.c:(.text+0x6f0): multiple definition of `sha224_init' 
/home/sebfisch/.cabal/lib/darcs-2.8.2/ghc-7.4.2/libHSdarcs-2.8.2.a(sha2.o):sha2.c (.text+0x620): first defined here 
collect2: ld returned 1 exit status 

Die cryptohash Bibliothek von yesod-static erforderlich ist und nicht leicht vermieden werden kann, wenn eine Yesod Anwendung zu schreiben. Wie kann ich Yesod und Darcs (als Bibliothek) in derselben Anwendung verwenden?

Wäre es hilfreich, die doppelten Symbole aus einer Bibliothek zu löschen? Beide Pakete greifen auf Hashfunktionen über FFI zu, verwenden jedoch unterschiedliche Dateien.

Von darcs/Crypt.SHA256:

foreign import ccall unsafe "sha2.h sha256" c_sha256 
    :: Ptr CChar -> CSize -> Ptr Word8 -> IO() 

Von cryptohash/Crypto.Hash.SHA256:

foreign import ccall unsafe "sha256.h sha256_init" 
    c_sha256_init :: Ptr Ctx -> IO() 

foreign import ccall "sha256.h sha256_update" 
    c_sha256_update :: Ptr Ctx -> CString -> Word32 -> IO() 

foreign import ccall unsafe "sha256.h sha256_finalize" 
    c_sha256_finalize :: Ptr Ctx -> CString -> IO() 

Eine weitere Idee ist Darcs zu umschreiben nicht seine eigene Hash-Funktion zu verwenden. Wie kann ich das Modul SHA256 von Darcs für die Verwendung von Cryptohash re-implementieren? Die beiden Anweisungen in der main-Funktion meines Testprogramms geben nicht die gleiche Ausgabe (getestet durch Auskommentieren der anderen Anweisung), so dass die Verwendung von Cryptohash in Darcs nicht ganz einfach erscheint.

+0

Können Sie nicht einfach die Darcs-Version dieser Funktion in etwas wie 'darcs_sha256_init' umbenennen? –

+1

Wenn ich richtig verstanden habe, ist das Problem, dass das Symbol in zwei verschiedenen C-Dateien definiert ist, die über FFI verwendet werden, also würde die Umbenennung der Haskell-Funktion nicht helfen, richtig? –

+0

Das Umbenennen der C-Funktion hilft jedoch. Siehe meine überarbeitete Antwort. –

Antwort

4

Die DARCS-Hash-Ausgabe ist nur die Base16-kodierte Version der Cryptohash-Ausgabe. Sieht aus wie base16-bytestring ist eine Möglichkeit, diese Lücke zu überbrücken. Ich versuchte es und Crypt.SHA256 wird so einfach wie:

module Crypt.SHA256 (sha256sum) where 

import Crypto.Hash.SHA256 (hash) 
import Data.ByteString (ByteString) 
import Data.ByteString.Base16 (encode) 
import Data.ByteString.Char8 (unpack) 

sha256sum :: ByteString -> String 
sha256sum = unpack . encode . hash 

In der Tat das hashed-storage Paket auch eine Kopie sha2.c hat und das Problem behoben, indem Sie die Symbole umbenennen. So ist die einfachste schnelle Lösung für darcs 2.8 ist sha2.h und sha2.c aus gehasht-Speicher zu kopieren, ersetzen hashed_storage_ mit darcs_ in beiden Dateien, und die FFI Import ändern in src/Crypt/SHA256.hs in darcs zu:

foreign import ccall unsafe "sha2.h darcs_sha256" c_sha256 
    :: Ptr CChar -> CSize -> Ptr Word8 -> IO() 

Ich würde glücklich sein, dass du 2.8.3 mit dieser Änderung veröffentlichen würdest, wenn es dir helfen würde. Für 2.10 werde ich zu Cryptohash wie oben wechseln, da ich keinen Grund sehe, weiterhin die lokale C-Version zu verwenden, und generell versuchen wir in Darcs private Implementierungen von gemeinsamem Code loszuwerden.

EDIT: Ich dachte ursprünglich hashed-Speicher hätte das gleiche Problem, aber ich war falsch (im Rückblick ist es offensichtlich, dass es mit Darcs selbst kollidiert wäre, wenn nicht für die Umbenennung).

+0

Ich stimme zu, dass die Verwendung von Cryptohash auf lange Sicht vorzuziehen ist, aber für den Moment mit der einfacheren Lösung leben kann, wenn Sie es für 2,8 bevorzugen. Ein Upload zu Hackage wäre großartig, damit ich eine veröffentlichte Version verwenden kann. Vielen Dank! –

+1

Jetzt hochgeladen: http://hackage.haskell.org/package/darcs-2.8.3 –

Verwandte Themen