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.
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.
Nie możesz zmienić nazwy wersji tej funkcji na coś podobnego do 'darcs_sha256_init'? –
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? –
Jednak zmiana nazwy funkcji C pomaga. Zobacz moją poprawioną odpowiedź. –