Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving a compiled Haskell program

Tags:

linux

haskell

ghc

I want to compile a Haskell program on one Linux box, and then run it on another Linux box. However, this doesn't seem to work at all. I get errors about missing libraries.

Presumably when I install GHC, the package manager also installs all the libraries and stuff that it needs. [I note with some irritation that at least one packaging system fails to install GCC, which GHC apparently can't function without...] But of course, the target system does not have these dependencies installed. So if I copy the compiled binary to the target system, it just fails to run.

Is there some way around this problem? I'm used to working with Windows, where if you compile something, it just works on all Windows systems. (At least, it does until you actually try to use non-standard facilities like database access or something...) I compiled Hello World in Haskell, copied it to another Linux box, and it complained about libgmp.so.10 missing or some cryptic mumbo-jumbo like that.

Just to make things interesting: I only have FTP access to the target machine, not shell access. I'm not even completely sure what OS it's running. So I can change my build machine any way I want, but I can't do anything to the target machine other than copy files to it.

like image 355
MathematicalOrchid Avatar asked Jul 19 '12 18:07

MathematicalOrchid


1 Answers

Linux behaves just like Windows in this regard. If you compile a Haskell executable on Linux, it will run on any Linux distribution with the right libraries. The problem is that in Windows, the Haskell executables aren't compiled with a dynamic version of libgmp; they are compiled with a static version (so that the library is compiled into the executable) exactly because it can be so difficult to handle dlls on Windows when distributing executables. It is comparably easy to handle the installation of new libraries on Linux.

What you can do is to copy the libgmp.so.10 (which might be a symbolic link to a different file) out of /usr/lib into the same directory as your executable. You can then set the LD_LIBRARY_PATH environment variable to ".", meaning the current directory, before launching your executable. This will make Linux look for libraries in the same directory as executables that it launches, making it find the library. This can be done with a launcher script:

#!/bin/sh
export LD_LIBRARY_PATH=.
`dirname "$0"`/myexecutable "$@"

Saving this script and marking it as executable with chmod +x myscript will make your executable work.

You can use the ldd command to check what other libraries your executable might need and that aren't on the target system.

like image 131
dflemstr Avatar answered Sep 18 '22 05:09

dflemstr