2012-11-01 9 views
7

Wydaje się niemożliwe użycie Yesod razem z biblioteką Darcs z powodu problemu z linkerem. Wyszukałem problem i potrzebowałem podpowiedzi do obejścia go przez osoby zaznajomione z wewnętrznymi elementami Darcs.Jak obejść duplikat błędu symbolu podczas korzystania z biblioteki Yesod i Darcs?

Podczas korzystania z darcs library w aplikacji Yesod, pojawia się następujący błąd:

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. 

Wydaje się być spowodowane przez darcs i cryptohash bibliotek wystawiając ten sam symbol, jak przeszukując odpowiednich plików obiektowych ujawnia :

# 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 

napisałem program testowy w celu potwierdzenia, że ​​darcs i biblioteki cryptohash są w konflikcie:

import   Crypt.SHA256   (sha256sum) 
import   Crypto.Hash.SHA256 (hash) 
import   Data.ByteString  (empty) 
import qualified Data.ByteString.Char8 as BS 

main :: IO() 
main = do 
    BS.putStrLn $ hash empty -- cryptohash 
    putStrLn $ sha256sum empty -- darcs 

To nie skompilować z podobnego błędu:

/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 

cryptohash biblioteka jest wymagane przez yesod-static i nie może być łatwo unikać podczas pisania aplikacji Yesod. Jak mogę używać Yesod i Darcs (jako biblioteki) w tej samej aplikacji?

Czy pomógłby usunąć powielone symbole z jednej biblioteki? Oba pakiety uzyskują dostęp do funkcji mieszających za pośrednictwem FFI, ale wykorzystują różne pliki.

Od darcs/Crypt.SHA256:

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

Od 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() 

Innym pomysłem jest, aby przepisać darcs nie używać własnego funkcję mieszającą. Jak mogę ponownie zainstalować moduł Darcsa SHA256, aby używać cryptohash? Dwie instrukcje funkcji main mojego programu testowego nie dają tego samego wyniku (testowanego przez komentowanie innego oświadczenia), więc używanie funkcji cryptohash w Darcs nie wydaje się całkiem proste.

+0

Nie możesz zmienić nazwy wersji tej funkcji na coś podobnego do 'darcs_sha256_init'? –

+1

Jeśli dobrze rozumiem, problem polega na tym, że symbol jest zdefiniowany w dwóch różnych plikach C używanych przez FFI, więc zmiana nazwy funkcji Haskell nie pomoże, prawda? –

+0

Jednak zmiana nazwy funkcji C pomaga. Zobacz moją poprawioną odpowiedź. –

Odpowiedz

4

Wyjście mieszania darcs jest po prostu zakodowaną wersją wyjścia cryptohash w wersji 16. Wygląda na to, że base16-bytestring jest jednym ze sposobów na pokonanie tej luki. Próbowałem go i Crypt.SHA256 staje się tak proste, jak:

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 

W rzeczywistości pakiet hashed-storage ma również kopię sha2.c i problem został rozwiązany przez zmianę nazwy symboli. Więc najprostszym szybkie ustalenie dla darcs 2,8 jest skopiowanie sha2.h i sha2.c z zaszyfrowaną-storage, wymienić hashed_storage_ z darcs_ w obu plikach, a także zmienić import FFI w src/Crypt/SHA256.hs w darcs do:

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

Z chęcią wydam polecenie darcs 2.8.3 z tą zmianą, jeśli to ci pomoże. W wersji 2.10 przełączam się na cryptohash jak wyżej, ponieważ nie widzę powodu, aby nadal używać lokalnej wersji C, a ogólnie w darcs, próbujemy pozbyć się prywatnych implementacji wspólnego kodu.

EDYCJA: Pierwotnie sądziłem, że hashed-storage będzie miał ten sam problem, ale myliłem się (z perspektywy czasu jest oczywiste, że sparowałoby się z samymi darcsami, gdyby nie zmiana nazwy).

+0

Zgadzam się, że używanie cryptohash jest preferowane na dłuższą metę, ale może żyć z prostszą poprawką na chwilę, jeśli wolisz ją w wersji 2.8. Przesyłanie do Hackage byłoby świetne, więc mogę użyć wydanej wersji. Dzięki! –

+1

Teraz przesłane: http://hackage.haskell.org/package/darcs-2.8.3 –

Powiązane problemy