Home » Linux » Create a static Haskell Linux executable

Create a static Haskell Linux executable

Posted by: admin November 30, 2017 Leave a comment

Questions:

It’s not often two things I love so much come together to cause me so much annoyance (besides my kids). I’ve written a Haskell program at work that uses libraries like text, xml-enumerator, attoparsec-text, etc. I have it working properly on my Windows machine at work, my Ubuntu virtual machine at work (32-bit), my Ubuntu desktop (32-bit again) and an EC2 instance running Ubuntu (64-bit).

Our client is running CentOS 5.3, 64-bit. I can’t for the life of me get this executable to run properly. I tried creating a static executable using:

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

But when I try to run that executable on the CentOS server, I get an error message:

openFile: invalid argument (Invalid argument)

I’m assuming this is related to the bug described here. I’ve tried compiling from both 32 and 64 bit Ubuntu, tried static and shared builds, nothing works (though I occasionally get segfaults instead of the above error message). I can try downloading CentOS 5.3 and creating a virtual machine for it, but it will take a while to download, and I’m not sure which version of GHC will work on it (I tried getting GHC 7 on their server, but I ran into a libc issue).

At this point, I’ve come up with a few possible approaches, but I’d like to avoid these if at all possible:

  • Rewrite in a different language (the thought of doing this in Java makes me queasy, though it could be a nice time to try out Cal/OpenQuark).
  • Maybe try out an alternate compiler, like jhc. But I’m not quite certain how to get started installing all the dependencies for this program in jhc; if people have experience and know that text/attoparsec/etc work in jhc, I’d love to hear it.
  • Hack of all hacks: build a Windows executable, install wine on their server and run it that way.

As a total aside, these are the situations where I really wish we had a JVM backend for GHC. I suppose I could try out LambdaVM as well. But I’d love to hear community advice on what to do here.

Answers:

This simple example “works for me”:

$ 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"

(and I’ve used this process, via .cabal, to ship executables for clients in the past couple of years).

I think the best bet is to file bugs, and get this working. The IHG can also fund work like this, but I’m fairly sure the GHC team would consider this a high priority, if you’re trying to ship products.

Questions:
Answers:

It is related to the old glibc library in CentOS. You have to compile with the same version of glibc as installed on CentOS.

I had exactly the same problem. Haskell executable compiled on arch (or ubuntu) won’t run on CentOS. In my case though i was lucky, because our admin just removed CentOS and installed Arch for application server.

Questions:
Answers:

I found out the problem. It seems that the link to the Biohaskell page is accurate: this is a problem loading iconv. This occurs when calling openFile, but not when calling openBinaryFile. Since xml-enumerator uses the latter, it worked just fine. Switching over the rest of the code to use openBinaryFile instead (via Data.Enumerator.Binary.enumFile) got everything to work.

This is a good workaround for my use case, but the bug still exists.