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.
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.
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'? –
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? –
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. –