GHC 找不到适用于 mingw gcc(但不是 mingw-w64)的外部库(libjack.lib)

Posted

技术标签:

【中文标题】GHC 找不到适用于 mingw gcc(但不是 mingw-w64)的外部库(libjack.lib)【英文标题】:GHC can't find foreign library (libjack.lib) that works with mingw gcc (but not mingw-w64) 【发布时间】:2020-09-08 06:29:46 【问题描述】:

目标:

我正在 Windows 10 上使用堆栈和 jack 的绑定从 hackage 编写一个 haskell 程序。 Jack 已安装,其 lib/include 路径已提供给 ghc。我的目标是使用堆栈构建程序。

问题:

当我运行stack build 时,我看到了:

Building all executables for 'hsjack' once  ...
Glasgow Haskell Compiler, Version 8.6.5, stage 2 booted by GHC version 8.6.2
Cabal-simple_Z6RU0evB_2.4.0.1_ghc-8.6.5.exe: Missing dependencies on foreign
libraries:
* Missing (or bad) C libraries: jack64, jack64 ...
While building package hsjack-0.1.0.0 using:
     C:\sr\setup-exe-cache\x86_64-windows\Cabal-simple_Z6RU0evB_2.4.0.1_ghc-8.6.5.exe ... 
        --extra-include-dirs=C:\Users\jvall\Tools\jackpackage\includes ...  
        --extra-lib-dirs=C:\Users\jvall\Tools\jackpackage\lib...
    Process exited with code: ExitFailure 1

我遗漏了一些无趣的部分(用“...”表示)。可以看到库和包含文件的路径都包含在内,我确信库(libjack.lib、libjack64.lib)和头文件都在这些目录中。我尝试在 package.yaml 中的 extra-libraries: 下同时指定 - jack- jack64 没有区别。当然extra-include-dirsextra-lib-dirs是在stack.yaml中指定的。

程序版本和其他上下文:

Windows 10

> jackd --version jackdmp 1.9.11 我安装了 jack website 上可用的 JACK2 64 位二进制文​​件。 C:/.../jackpackage/includes/jack:的内容 jack.h,其他 *.h 文件 C:/../lib:的内容 libjack.def、libjack.lib、libjack64.def、libjack64.lib。 (加上无关的 libjackserver 文件。没有 .dll)

> 堆栈 --version 版本 2.3.1,Git 修订版 de2a7b694f07de7e6cf17f8c92338c16286b2878(8103 次提交)x86_64 hpack-0.33.0

> stack exec -- ghc --version Glorious Glasgow Haskell 编译系统,8.6.5 版

> stack exec -- gcc --version realgcc.exe (Rev1, Built by MSYS2 project) 7.2.0

使用 mingw 时 > gcc --版本 gcc.exe (MinGW.org GCC Build-20200227-1) 9.2.0

使用 mingw-w64 时 > gcc --版本 gcc.exe (x86_64-posix-seh-rev0, 由 MinGW-W64 项目构建) 8.1.0

可能的重复:

有很多类似的 SO 帖子,但我发现没有一个可以为我的案例提供解决方案。绝大多数只是缺少适当的库或程序(1、2、3、4)。我的问题似乎是由 *.lib 文件与 gcc 的 mingw-w64 和 MSYS2 版本之间的不兼容引起的。

调试尝试:

为了验证 .lib 文件是否可以正常工作,我编写了一个简单的 c 程序来使用它们。程序在使用mingw提供的gcc时可以正常编译运行,但是在使用mingw-w64 gcc或者stack exec gcc时却不能运行。使用 stack exec 的示例输出(高度缩写):

stack exec -- gcc .\test.c -o .\test -I C:\...\includes -L C:\...\lib -ljack64

Target: x86_64-w64-mingw32  
Thread model: posix  
gcc version 7.2.0 (Rev1, Built by MSYS2 project)  
...  
path-to-stack//stack//x86_64-windows//ghc-8.8.3//mingw//bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/collect2.exe  ....  -LC:\\Users\\jvall\\Tools\\jackpackage\\lib ....  
path-to-stack//stack//x86_64-windows//ghc-8.6.5//mingw//bin/ld.exe: cannot find -ljack64  
collect2.exe: error: ld returned 1 exit status

mingw-w64 和stack exec gcc 都以同样的方式失败。一切看起来都很好,直到他们找不到图书馆。使用 -m64/-m32 和 -ljack/-ljack64 不会改变任何东西。我知道 Jack2 库是用 C++ 编写的,并且读过 MSVC C++ 库与 mingw 不兼容,但这并不能解释 mingw 如何在 mingw-w64 不兼容时成功编译。这些是否相关,或者我应该关注这个问题的 haskell/stack 方面吗?

有什么想法吗?如何使用 stack 来编译使用 jack 绑定的 haskell 程序?我试图做到彻底,但如果我遗漏了什么,请告诉我。我有最小的例子来重现这个问题,但问题已经很长了。

【问题讨论】:

【参考方案1】:

你的 binutils 是旧的。 GHC 附带的 8.6.5 错过了此修复 https://sourceware.org/bugzilla/show_bug.cgi?id=22948 。没有它 -ljack64 将找不到 libjack64.lib-llibjack64 会。

【讨论】:

这修复了它!非常感谢,我已经追了差不多一个星期了。我求助于从源代码构建图书馆!你帮了我很大的忙。【参考方案2】:

编辑:此解决方案允许它编译,但在运行时会导致问题并且不能解决根本问题。查看接受的答案以获得真正的解决方案。

更新:我找到了解决方案!一时兴起,我从 jack /lib/ 目录中的 .def 文件手动创建了 .dll 文件。最后它找到库并编译没有问题。这适用于 mingw-w64 甚至 stack build。我运行的命令是

dlltool -d .\libjack64.def -l .\libjack64.dll

谁能解释一下为什么 mingw 愉快地与 libjack.lib 链接,但是用 MSYS2 构建的 mingw-w64 和 gcc 却找不到 libjack64.lib?以及如何让 libjack64.dll 解决这个问题?

【讨论】:

以上是关于GHC 找不到适用于 mingw gcc(但不是 mingw-w64)的外部库(libjack.lib)的主要内容,如果未能解决你的问题,请参考以下文章

GCC (MingW-w64) 找不到基础构造函数 (!?)

代码可以用 VS 编译,但不能用 MinGW

ld.exe:找不到 -lstrmbase

mingw中的时间函数

gcc+mingw 下的 C++ segfault 但不是 gcc+linux

使用 Eclipse + CDT + MinGW32 开发 C++ Socket 程序找不到库文件和头文件