我一直在研究Haskell库包,它需要Windows上的自定义.dll和.lib来与某些OS API进行通信。 .lib链接到带有extra-libraries
字段的库中,DLL安装在带有data-files
的cabal包目录中。
出于某种原因(我不是以任何方式链接的专家,但这看起来很奇怪)如果我创建一个使用我的包的测试可执行文件(在build-depends
字段中),它想要链接用于编译库的.lib相同 - 即使它只是调用库函数,而不是.lib公开的任何东西。显然它需要在运行时访问.dll,但这是可以预料的。需要.lib似乎很奇怪。
我希望.lib已经链接到Cabal / GHC为我的库安装时生成的.a文件。这不是这种情况吗?如果是的话,有人可以解释为什么会这样吗?
答案 0 :(得分:1)
您希望部分链接(请参阅--relocatable
手册页中的ld
标记)。正如我从消息来源中看到的那样,cabal
仅使用部分链接库,为ghci
编译。来自Distribution.Simple.GHC(buildLib
函数):
whenVanillaLib False $ do
(arProg, _) <- requireProgram verbosity arProgram (withPrograms lbi)
Ar.createArLibArchive verbosity arProg
vanillaLibFilePath staticObjectFiles
whenProfLib $ do
(arProg, _) <- requireProgram verbosity arProgram (withPrograms lbi)
Ar.createArLibArchive verbosity arProg
profileLibFilePath profObjectFiles
whenGHCiLib $ do
(ldProg, _) <- requireProgram verbosity ldProgram (withPrograms lbi)
Ld.combineObjectFiles verbosity ldProg
ghciLibFilePath ghciObjFiles
whenSharedLib False $
runGhcProg ghcSharedLinkArgs
您可以看到,对于vanilla和profiling库,cabal
只调用ar
实用程序(请参阅createArLibArchive)。对于ghci
,它会使用ld
标记(-r
的快捷方式)调用--relocatable
(请参阅combineObjectFiles)。
因此,cabal
实际上并没有为vanilla库做任何链接,它只是组合了目标文件。实际上cabal
无法知道最终申请是否会使用extra-lib
中的任何符号,因此行为似乎是合理的。