创建一个静态Haskell Linux可执行文件

时间:2011-05-10 16:23:56

标签: linux haskell libraries static-linking ld

通常情况下,我喜爱的两件事情并不是很让我烦恼(除了我的孩子)。我在工作中编写了一个Haskell程序,它使用文本,xml-enumerator,attoparsec-text等库。我在工作的Windows机器上正常工作,我的Ubuntu虚拟机在工作(32位),我的Ubuntu桌面(再次32位)和运行Ubuntu(64位)的EC2实例。

我们的客户端正在运行CentOS 5.3,64位。我不能为我的生活让这个可执行文件正常运行。我尝试使用以下方法创建静态可执行文件:

ghc --make myprog.hs -optl-static -optl-pthread

但是当我尝试在CentOS服务器上运行该可执行文件时,我收到一条错误消息:

openFile: invalid argument (Invalid argument)

我假设这与the bug described here有关。我尝试从32位和64位Ubuntu编译,尝试静态和共享版本,没有任何作用(虽然我偶尔会得到段错误而不是上面的错误消息)。我可以尝试下载CentOS 5.3并为它创建一个虚拟机,但下载需要一段时间,而且我不确定哪个版本的GHC可以使用它(我尝试在他们的服务器上安装GHC 7,但我跑了进入libc问题)。

此时,我想出了一些可能的方法,但我想尽可能避免这些:

  • 用另一种语言重写(在Java中这样做的想法让我感到不安,尽管这可能是尝试Cal / OpenQuark的好时机。)
  • 也许尝试一下替代编译器,比如jhc。但是我不太确定如何开始在jhc中安装该程序的所有依赖项;如果人们有经验并且知道jhc中的text / attoparsec / etc工作,我很乐意听到。
  • 所有黑客攻击:构建Windows可执行文件,在其服务器上安装wine并以此方式运行。

总而言之,这些是我真的希望我们拥有GHC的JVM后端的情况。我想我也可以试用LambdaVM。但我很想听听社区对这里做什么的建议。

3 个答案:

答案 0 :(得分:30)

这个简单的例子“对我有用”:

$ cat A.hs
main = print "yes"

$ ghc -O2 --make -static -optc-static -optl-static A.hs -fvia-C -optl-pthread

$ ldd A
    not a dynamic executable
$ ./A
"yes"

(我在过去几年中通过.cabal使用此流程为客户提供可执行文件。)

我认为最好的办法就是提交错误,并让它发挥作用。 IHG也可以资助这样的工作,但我相当肯定GHC团队会认为这是一个高优先级,如果你想要运送产品。

答案 1 :(得分:8)

它与CentOS中的旧glibc库有关。您必须使用与CentOS上安装的相同版本的glibc进行编译。

我有完全相同的问题。在arch(或ubuntu)上编译的Haskell可执行文件不能在CentOS上运行。在我的情况下,虽然我很幸运,因为我们的管理员刚刚删除了CentOS并为应用服务器安装了Arch。

答案 2 :(得分:5)

我发现了问题。似乎Biohaskell页面的链接是准确的:这是一个加载iconv的问题。调用openFile时会发生这种情况,但在调用openBinaryFile。由于xml-enumerator使用后者,因此效果很好。切换其余代码以使用openBinaryFile代替(通过Data.Enumerator.Binary.enumFile),一切正常。

对于我的用例,这是一个很好的解决方法,但错误仍然存​​在。