将musl与ghc静态连接

gio*_*ioi 2 haskell ghc

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

我想用musl,就像这个答案所说的那样.

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

$ 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
Run Code Online (Sandbox Code Playgroud)

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

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

小智 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库就会保持干净利落.