编译库所需的静态.lib文件是否也需要提供给库的使用者?

7
我一直在开发一个Haskell库包,它需要在Windows平台上使用自定义的.dll和.lib与一些操作系统API交互。.lib被链接到库中的extra-libraries字段中,而DLL被安装在Cabal软件包目录中的data-files字段中。
由于某种原因(我不是任何意义上的链接专家,但这似乎很奇怪),如果我创建一个测试可执行文件,该文件使用我的包(在build-depends字段中),它想要链接编译库时使用的同一个.lib——尽管它只是调用库函数,并没有使用.lib暴露的任何内容。显然它在运行时需要访问.dll,但这是可以预料的,需要.lib也很奇怪。
我希望当我的库被安装时,.lib已经被链接到Cabal/GHC生成的.a文件中。这是否是事实?如果是,有人能解释为什么会这样吗?
1个回答

1

看起来你想要部分链接(请参阅ld手册页中的--relocatable标志)。从源代码中可以看出,cabal仅使用为ghci编译的部分链接库。从Distribution.Simple.GHCbuildLib函数)中可以看出:

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

你会发现,对于普通和性能分析库,cabal 只是调用 ar 工具(请参见createArLibArchive)。对于ghci,它使用 -r 标志(这是 --relocatable 的缩写)调用 ld(请参见combineObjectFiles)。

因此,cabal 实际上不会为原始库进行任何链接操作,它只是组合对象文件。实际上,cabal 不知道最终应用程序是否会使用你的 extra-lib 中的任何符号,所以这种行为似乎是合理的。

有没有一种方法可以强制使用“ld -r”而不是“ar”来生成 vanilla 库?我尝试添加了“ld-options:-r”,但似乎没有任何作用(可能是因为没有使用“ld”?) - Tom Savage
@TomSavage 不,我认为这是不可能的。但我对 cabal 不是很熟悉。 - Yuras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接