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.
Können Sie nicht einfach die Darcs-Version dieser Funktion in etwas wie 'darcs_sha256_init' umbenennen? –
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? –
Das Umbenennen der C-Funktion hilft jedoch. Siehe meine überarbeitete Antwort. –