【问题标题】:How to include a dependency C library in Haskell Stack如何在 Haskell Stack 中包含依赖 C 库
【发布时间】:2018-07-11 00:39:00
【问题描述】:

我想创建一个 Haskell Stack 包,其中包含另一个 Haskell Stack 包作为extra-dep。有问题的是,我试图包含的包是使用 Haskell 的 FFI 绑定到某些 C 代码的。

如果我只是 stack unpackstack build 那个包 (HasCacBDD) 它工作得很好,但是当我将它包含为 extra-dep Stack 抱怨缺少库。

查看该原始包的Setup.hs,我发现它基本上创建了一个名为libHasCacBDD.a 的静态库,并将其放在.stack-work 路径内的正确文件夹中以供链接。当我将它包含在我自己的项目中时,正是这个库给了我一个错误。

仔细查看我自己项目的.stack-work文件夹,发现上面提到的libHasCacBDD.a确实在某个地方隐藏的目录中。幸运的是,该库正在正确构建,但我的项目找不到它。

Haskell Stack 官方文档说明了在这种情况下该怎么做,但我认为它不够具体,无法给我一个满意的答案。

我需要做的是将libHasCacBDD.a 库存储为extra-lib-dirs 选项的路径。尽管如此,我不知道如何以独立于平台的方式做到这一点(如果我在我的计算机中硬编码路径,它只会在其中工作,在这种情况下做一个包的意义何在)。

我创建了一个issue on Github,其中包含有关详细信息的更多信息。

有什么建议吗?

【问题讨论】:

    标签: haskell haskell-stack


    【解决方案1】:

    我过去使用 Makefile 处理过这个问题,该 Makefile 可以找到本地目录,并使用参数包装我常用的堆栈命令以使用它。

    LIB_DIR :=$(shell dirname $(shell find $(shell stack path --local-install-root) -name libHasCacBDD.a))
    ARGS = --extra-lib-dirs ${LIB_DIR}
    
    test:
        stack ${ARGS} test --fast -j4
    

    丑陋,但它有效。

    预计到达时间: 第一行调用了 shell 三次:

    • stack path 了解软件包的安装位置
    • find 找到您需要的特定文件
    • dirname获取目录

    其余行将该目录作为额外的库目录传递给stack。每次调用 make 时都这样做可以避免将路径放在文件中,当编译器或包版本更改时需要更新它。

    【讨论】:

    • 非常感谢您的评论,这对于在构建文件后能够移动文件似乎很有用。我认为这个解决方案不能解决问题,因为我得到的错误是在构建项目时,它无论如何都不会构建,对吗?除非我在构建过程的某些操作之间调用它。我觉得我能够做到这一点的唯一方法是在Setup.hs 文件中,作为某个地方的钩子。不过,您提供给我的代码肯定很有用,我只需要在 Setup.hs 文件中调用它即可。
    • 我想你说libHasCacBDD.a 正在正确构建,并放在你的.stack-work 下的某个地方。添加到extra-lib-dirs 的路径是否有效?我提供的代码定位了该文件,以帮助解决您对平台可移植性的担忧。