One of my goals with this project is to produce code that can run with no external dependencies across as much of our Unix estate as possible. That is several thousand machines, tho’ I am only interested in a few hundred of those. This would be a complete non-issue on a grown-up platform like SPARC but unfortunately we have jumped aboard the Linux bandwagon, so it is not entirely straightforward.
Consider just about the simplest possible Haskell program:
debian$ cat Hello.hs module Main where main = putStrLn "Hello, world!" debian$ ghc --make Hello.hs debian$ ./Hello Hello, world!
All well and good on my 32-bit Debian PC, but the same binary on 32-bit CentOS:
centos$ ./Hello Hello: timer_create: Invalid argument
Hmm. Some research reveals that perhaps this can be addressed with different compilation options:
debian$ ghc --make Hello.hs -threaded centos$ ./Hello Hello, world!
Jolly good. But on 64-bit Redhat, which is the main target environment:
redhat64$ ./Hello ./Hello: error while loading shared libraries: libffi.so.5: cannot open shared object file: No such file or directory
Hmm some more. Now the sensible thing to do would just be to either convince the sysadmins to install FFI everywhere or just deploy my own build (for each target?!) along with my binaries. Or indeed to just install GHC! But the strategy is to minimize dependencies, even on LD_LIBRARY_PATH, so let’s try:
debian$ ghc --make Hello.hs -optl-static -optl-pthread debian$ ./Hello Hello, world!
redhat64$ ./Hello Hello, world!
Perfect! But unfortunately:
centos$ ./Hello FATAL: kernel too old Segmentation fault
Erm, lol? I’m with jwz. But since Debian is my development environment and RHEL is my target, I can live with it.