如何在 .cabal 中指定对外部 C 库的依赖?

Posted

技术标签:

【中文标题】如何在 .cabal 中指定对外部 C 库的依赖?【英文标题】:How to specify dependency on external C library in .cabal? 【发布时间】:2011-06-24 23:49:58 【问题描述】:

我在 Hackage 上维护了一个带有 FFI 绑定的库。所以我的 Haskell 库依赖于对应的 C 库及其头文件。现在我在.cabal 文件中指定外部依赖,如下所示:

PkgConfig-Depends:
      libfoo >= 1.2

它在 Linux 中对我很有效。但是,我有一个库用户报告说,在 Windows 上安装 pkg-config 相当麻烦,相反他更喜欢

Includes:
      foo.h
Extra-libraries:
      foo

我希望我的库尽可能易于构建,并且不想强制构建并非严格要求的依赖项。但是,我看到Cabal manual 建议使用PkgConfig-Depends

我的问题:

对于跨平台软件包,我应该更喜欢哪种方式? 是否可以编写.cabal 文件,使其可以与pkg-config 一起使用而无需pkg-config? 顺便问一下,pkg-config 是否包含在 Haskell 平台中(我现在没有要检查的 Windows 机器)?

【问题讨论】:

pkg-config 不包含在 Windows (2010.2.0.0) 平台中。 【参考方案1】:

pkg-config 方法更可取,因为 pkg-config 知道在哪里可以找到包含和库文件,这些文件可能位于某些系统上的非标准位置。

您可以编写 .cabal 文件来使用这两种方法。使用一个标志,如此处所示,如果默认失败,Cabal 将自动尝试另一个标志值。 (以下示例未经测试)

Flag UsePkgConfig
  Description: Use pkg-config to check for library dependences
  Default: True

Executable hax
  if flag(UsePkgConfig)
    PkgConfig-Depends: libfoo >= 1.2
  else
    Includes: foo.h
    Extra-libraries: foo

【讨论】:

谢谢。我选择了这种带有标志的方法,可惜我更喜欢NoPkgConfig 标志,因为cabal configure -fNoPkgConfigcabal configure -f-UsePkgConfig 更具可读性。这种方法在 Linux 上运行良好(无论是否安装了pkg-config)。稍后我会报告 Windows 用户的反馈。【参考方案2】:

pkg-config 不包含在 Haskell 平台中,我也无法想象它会包含。

如果它们相对简单,我通常会使用includes/Extra-libraries。但是对于可能包含大量库的复杂包,例如 gtk,在可用时使用 pkg-config 会更好。

可以编写一个可以使用和不使用特定字段的 .cabal 文件。试试这个:

if os(windows)
  Includes:
      foo.h
  Extra-libraries:
      foo
else
  PkgConfig-Depends:
      libfoo >= 1.2

另请注意,.cabal 可以运行配置脚本,这在某些情况下会有所帮助,但对 Windows 不太友好。

【讨论】:

谢谢。我考虑过做这样的事情,但@Heatsink 提出的解决方案可能更灵活。我先试试那个。 @jetxee - 确实,标志可以更灵活,但它们也可能导致问题。当使用一组不同的标志构建新包时,Cabal 似乎想要重新编译已安装的包,这可能会使您的包 db 处于不一致的状态。我可能有偏见,因为我只需要修复我的包 db。

以上是关于如何在 .cabal 中指定对外部 C 库的依赖?的主要内容,如果未能解决你的问题,请参考以下文章

Intellij IDEA 无法识别 Maven 依赖项中指定的类

Intellij IDEA 无法识别 Maven 依赖项中指定的类

如何在 aar 库中指定依赖项?

如何在 CodeNameOne 项目中指定 abiFilters?

如何在 build.gradle 中指定“pig-0.13.0-h2.jar”依赖?

如何调试 Gradle 为啥使用我在依赖子项目中指定的不同版本的库?