gpt4 book ai didi

haskell - 使用 Yesod 和 Darcs 库时如何解决重复符号错误?

转载 作者:行者123 更新时间:2023-12-02 12:06:57 24 4
gpt4 key购买 nike

由于链接器问题,似乎无法将 Yesod 与 Darcs 库一起使用。我找到了这个问题,并需要熟悉 Darcs 内部结构的人提供解决该问题的提示。

使用 darcs library 时在 Yesod应用程序时,我收到以下错误:

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.

这似乎是由 darcs 和 cryptohash 引起的公开相同符号的库,通过搜索相应的目标文件显示:

# 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

我编写了一个测试程序来确认darcs和cryptohash库是否存在冲突:

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

编译失败并出现类似错误:

/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

yesod-static 需要 cryptohash 库在编写 Yesod 应用程序时无法轻易避免。如何在同一应用程序中使用 Yesod 和 Darcs(作为库)?

从一个库中删除重复的符号会有帮助吗?这两个包都通过 FFI 访问哈希函数,但使用不同的文件。

来自darcs/Crypt.SHA256 :

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

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

另一个想法是重写 Darcs,使其不使用它自己的哈希函数。如何重新实现 Darcs 的 SHA256 模块以使用 cryptohash?我的测试程序的 main 函数中的两个语句没有给出相同的输出(通过注释掉另一个语句进行测试),因此在 Darcs 中使用 cryptohash 似乎并不完全简单。

最佳答案

darcs 哈希输出只是 cryptohash 输出的 base16 编码版本。看起来像base16-bytestring是弥补这一差距的一种方法。我尝试了一下,Crypt.SHA256 变得如此简单:

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

事实上hashed-storage软件包还有 sha2.c 的副本,并通过重命名符号修复了问题。因此,darcs 2.8 最简单的快速修复方法是复制 sha2.hsha2.c从 hashed-storage 中,将两个文件中的 hashed_storage_ 替换为 darcs_,并将 darcs 中 src/Crypt/SHA256.hs 中的 FFI 导入更改为:

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

如果对您有帮助,我很乐意发布带有此更改的darcs 2.8.3。对于 2.10,我将改用上面的 cryptohash,因为我看不出有任何理由继续使用本地 C 版本,而且一般来说,在 darcs 中,我们正在尝试摆脱公共(public)代码的私有(private)实现。

编辑:我最初认为散列存储也会有同样的问题,但我错了(回想起来,如果不重命名,它显然会与 darcs 本身发生冲突)。

关于haskell - 使用 Yesod 和 Darcs 库时如何解决重复符号错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13186428/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com