将musl与ghc静态连接

时间:2014-04-05 12:04:45

标签: haskell ghc

我尝试使用GHC构建一个静态二进制文件,用于在Haskell中编写的基于CGI的Web应用程序,以部署在共享服务器上。

我想使用musl提到的this answer

不幸的是,这不是一件容易的事:

$ ghc -static -optl-static -pgmc musl-gcc -pgml musl-gcc -L/usr/local/lib app.hs
[1 of 1] Compiling Main             ( app.hs, app.o )
Linking app...
/usr/lib/ghc-7.6.3/libHSrts.a(Itimer.o): In function `exitTicker':
(.text+0x1af): undefined reference to `__sysv_signal'
collect2: error: ld returned 1 exit status

我做错了什么? (完全免责声明:我是Haskell新手(:)

我使用的是Arch Linux,GHC 7.6.3和Network.CGI。

1 个答案:

答案 0 :(得分:5)

看起来你的Haskell运行时是针对glibc编译的,但是你正试图针对musl编译你的Haskell源代码。通常,您不能在同一程序中混合使用两个C库。

这里你的具体问题是glibc支持signal函数的几个不同的冲突语义集,以匹配UNIX提供的不同历史版本。它根据C代码定义的功能测试宏选择使用哪个版本。并且要实际在它们之间切换,它使用C预处理器来替换程序对signal的引用,并引用函数版本,并使用您请求的任何语义(在您的情况下,您的Haskell运行时具有参考__sysv_signal)。

问题是,musl不会做同样轻微的手。它公开了单个版本的signal,它与POSIX标准定义的语义相匹配,并以名称signal公开它。

修复此问题的正确方法是根据musl的标头重新编译Haskell运行时。我不知道是否有人真的尝试过这样做,所以YMMV。

请注意,应避免将库安装在同一系统目录中,而是针对不同的C库进行编译。这样做可能会破坏事物,因为任何试图使用针对冲突的C库编译的多个库的软件都会遇到您现在遇到的确切问题的变体。您通常应该将musl编译并安装到自己的前缀中,然后针对musl编译其他库(例如,您的Haskell运行时)并安装到相同的前缀中。通过这种方式,您的musl和glibc库可以完全分开。