2012-11-01 14 views
7

Bir linker problemi nedeniyle Yesod'u Darcs kütüphanesi ile birlikte kullanmak imkansız gibi görünüyor. Problemi takip ettim ve Darcs internals'ı tanıyan insanlar tarafından etrafta dolanmak için ipuçları lazım.Yesod ve Darcs kitaplığını kullanırken yinelenen sembol hatası nasıl çalışır?

bir Yesod uygulamada darcs library kullanarak, aşağıdaki hatayı alıyorum:

ilgili nesne dosyaları arasında arama yapma gibi, Darcs ve aynı sembolü açığa cryptohash kütüphaneler neden gibi görünmektedir
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. 

ortaya :

:
# 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 

Ben Darcs ve cryptohash kütüphaneler çatışma içinde olan onaylamak için bir test programı yazdım
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 

Benzer bir hata ile derlenmeyecektir:

/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 kütüphane yesod-static gereklidir ve bir Yesod'dan uygulaması yazarken kolaylıkla önüne geçilememektedir. Aynı uygulamada Yesod ve Darcs'i (kitaplık olarak) nasıl kullanabilirim?

Yinelenen sembolleri bir kitaplıktan silmek yardımcı olur mu? Her iki paket de FFI aracılığıyla karma işlevlere erişir ancak farklı dosyalar kullanır.

darcs/Crypt.SHA256 itibaren

:

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

cryptohash/Crypto.Hash.SHA256 Gönderen:

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

başka bir fikir kendi karma işlevi kullanmak değil Darcs yeniden etmektir. Darcs'in SHA256 modülünü kriptohash kullanmak için nasıl yeniden canlandırabilirim? Test programımın main işlevindeki iki deyim, aynı çıktısını vermez (diğer ifadeyi yorumlayarak test edilmiştir), bu nedenle Darcs'deki kriptohash kullanımı tamamen basit görünmez.

+0

Bu işlevin Darcs sürümünü "darcs_sha256_init" gibi bir şeye yeniden adlandıramıyor musunuz? –

+1

Eğer doğru anlıyorsam, sorun FFI ile kullanılan iki farklı C dosyasında sembol tanımlanmasıdır, bu nedenle Haskell işlevinin yeniden adlandırılması yardımcı olmaz, değil mi? –

+0

Ancak C işlevini yeniden adlandırma yardımcı olur. Benim revize edilmiş cevabımı görün. –

cevap

4

Darcs karma çıkışı sadece kriptoşanın çıkışının base16 kodlu sürümüdür. base16-bytestring'un bu açığı kapatmanın bir yolu olduğu anlaşılıyor. Denedim ve sıra Crypt.SHA256 kadar basit olur: hashed-storage Pakette ayrıca sha2.c bir kopyası vardır ve sembolleri yeniden adlandırarak sorun sabit Aslında

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 

.

foreign import ccall unsafe "sha2.h darcs_sha256" c_sha256 
    :: Ptr CChar -> CSize -> Ptr Word8 -> IO() 
: Yani Darcs 2.8 için en basit hızlı bir düzeltme, karma-depodan sha2.h ve sha2.c kopyalamak iki dosyada da darcs_ ile hashed_storage_ değiştirin ve Darcs src/Crypt/SHA256.hs içinde FFI ithalat değiştirmektir

Size yardımcı olacaksa, bu değişiklikle 2.8.3 darsayı bırakmaktan mutluluk duyarım. 2.10 için kriptohash kullanmaya geçeceğim çünkü yerel C versiyonunu kullanmaya devam etmek için herhangi bir sebep göremiyorum ve genel olarak darkada ortak kodların özel uygulamalarından kurtulmaya çalışıyoruz.

DÜZENLEME: Aslen karma depolamada aynı problemin olacağını düşünmüştüm ama yanılmışım (yeniden adlandırmak gerekirse, yeniden adlandırma için olmasa bile, darcs ile çatışacağı açıkça belliydi).

+0

Uzun vadede kriptofanın kullanılması tercih edilir, ancak 2.8 için tercih ederseniz an için daha basit bir düzeltme ile yaşayabilir. Hackage'a bir yükleme harika olurdu, böylece yayınlanmış bir sürümü kullanabilirim. Teşekkürler! –

+1

Şimdi yüklendi: http://hackage.haskell.org/package/darcs-2.8.3 –

İlgili konular