2012-11-01 15 views
7

Dường như không thể sử dụng Yesod cùng với thư viện Darcs do vấn đề liên kết. Tôi theo dõi vấn đề và cần gợi ý để làm việc xung quanh nó bởi những người quen thuộc với internals Darcs.Làm thế nào để làm việc xung quanh lỗi biểu tượng trùng lặp khi sử dụng thư viện Yesod và Darcs?

Khi sử dụng darcs library trong một ứng dụng Yesod, tôi nhận được lỗi sau:

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. 

Nó dường như được gây ra bởi darcs và cryptohash thư viện phơi bày cùng một biểu tượng, như tìm kiếm thông qua các tập tin đối tượng tương ứng tiết lộ :

# 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 

tôi đã viết một chương trình thử nghiệm để xác nhận rằng darcs và thư viện cryptohash mâu thuẫn:

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 

Nó không biên dịch với một lỗi tương tự:

/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 

Thư viện cryptohash là yêu cầu của yesod-static và không thể dễ dàng tránh khi viết một ứng dụng Yesod. Làm thế nào tôi có thể sử dụng Yesod và Darcs (như một thư viện) trong cùng một ứng dụng?

Bạn có thể xóa các biểu tượng trùng lặp khỏi một thư viện không? Cả hai gói truy cập chức năng băm thông qua FFI nhưng sử dụng các tệp khác nhau.

Từ darcs/Crypt.SHA256:

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

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

ý tưởng khác là để viết lại darcs không sử dụng hàm băm riêng của mình. Làm thế nào tôi có thể reimplement mô-đun SHA256 của Darcs để sử dụng cryptohash? Hai câu lệnh trong hàm main của chương trình thử nghiệm của tôi không cung cấp cho cùng một đầu ra (được kiểm tra bằng cách đưa ra câu lệnh khác), vì vậy việc sử dụng cryptohash trong Darcs dường như không hoàn toàn đơn giản.

+0

Bạn không thể đổi tên phiên bản Darcs của hàm này thành một cái gì đó như 'darcs_sha256_init'? –

+1

Nếu tôi hiểu chính xác, vấn đề là biểu tượng được định nghĩa trong hai tệp C khác nhau được sử dụng thông qua FFI, vì vậy việc đổi tên hàm Haskell sẽ không hữu ích, phải không? –

+0

Tuy nhiên việc đổi tên hàm C sẽ giúp ích. Xem câu trả lời đã sửa đổi của tôi. –

Trả lời

4

Đầu ra băm darcs chỉ là phiên bản mã hóa base16 của đầu ra cryptohash. Hình như base16-bytestring là một cách để thu hẹp khoảng cách đó. Tôi đã thử nó và Crypt.SHA256 trở nên đơn giản như:

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 

Trong thực tế, gói hashed-storage cũng có một bản sao của sha2.c và cố định các vấn đề bằng cách đổi tên các biểu tượng. Vì vậy, việc sửa chữa nhanh chóng đơn giản nhất để darcs 2.8 là để sao chép sha2.hsha2.c từ băm-lưu trữ, thay thế hashed_storage_ với darcs_ trong cả hai tập tin, và thay đổi khẩu FFI trong src/Crypt/SHA256.hs trong darcs tới:

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

Tôi rất vui khi phát hành darcs 2.8.3 với thay đổi này nếu nó sẽ giúp bạn. Đối với 2,10 tôi sẽ chuyển sang sử dụng cryptohash như trên vì tôi không thấy bất kỳ lý do nào để tiếp tục sử dụng phiên bản C cục bộ và nói chung trong các darcs, chúng tôi đang cố gắng loại bỏ các cài đặt riêng của mã phổ biến.

EDIT: Ban đầu tôi nghĩ rằng lưu trữ băm sẽ có cùng một vấn đề, nhưng tôi đã sai (nhìn lại rõ ràng là nó sẽ đụng độ với chính darcs nếu không đổi tên).

+0

Tôi đồng ý rằng việc sử dụng cryptohash là thích hợp hơn cho thời gian dài nhưng có thể sống với bản sửa lỗi đơn giản hơn cho thời điểm này nếu bạn thích nó cho 2.8. Tải lên Hackage sẽ tuyệt vời để tôi có thể sử dụng phiên bản đã phát hành. Cảm ơn! –

+1

Bây giờ đã tải lên: http://hackage.haskell.org/package/darcs-2.8.3 –

Các vấn đề liên quan