The problem
I have an IRC bot that I build on my local machine, and I want to run it on my server. I'm running arch linux at home, which has the latest glibc (2.29 at the time of writing), but my server running debian ships with 2.28. I used to build the binary inside a docker container with the same versions as my server, but I'm currently on holiday, with a laptop with barely enough disk space for that.
Statically linked binary − a dead end
So at first, I tried to build a static binary that I could run on my server. To do so, I added a couple of things
to the cabal
file:
cc-options: -static
ld-options: -static -pthread
ghc-options: -optl-static -optl-pthread -static
Then rebuild the whole thing stack build --force-dirty
, copy the binary somewhere convenient: stack install --local-bin-path .
and check it's really statically linked: ldd exec-name
. You should get something like:
ldd exec-name
not a dynamic executable
But during compilation, I got a lot of warning like:
warning: Using 'endservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
I could run the application just fine on my server with the static binary, until I tried to make an http request, and then, it crashed with a segfault
. /o\
Dynamically linked binary with custom glibc
So I ended up with this solution, which requires to build the correct version of glibc on the server. Follow the instructions
to build the library. Don't forget to run make install
at the end. This will create a directory dist/lib
(or just lib
) in the folder you ran make build
. Let's say
the library end up at /home/lambda/glibc-build/lib/
.
Then, following this stackoverflow answer, you need to specify where to find the required libraries when starting the executable
/home/lambda/glibc-build/lib/ld-2.29.so \
--library-path "/home/lambda/glibc-build/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/" \
/home/lambda/executable
Besides libc
, a haskell application needs a couple of other shared object, like libz.so
and libgmp.so
. These should be on your system already.
And that's it. Finally I can run this crucial IRC bot without having to muck around with docker.