Linux deployment requirements for GHC-produced binaries

We received a complaint from one of our customers that the Linux executable for one of our products - compiled using GHC - does not run because of libgmp not being installed on their server. This binary was compiled using GHC 7.4.2 (HP 2012.4.0.0). We hope to be migrating soon to GHC 7.6.3 (HP 2013.2.0.0.). Do GHC-compiled binaries have a dynamic dependence on libgmp? If so, what are the exact requirements we need to communicate to our customers? Does this limit what versions of Linux we can claim that our product supports? Are there similar requirements and limitations regarding GNU Readline? Thanks, Yitz

On Thu, Oct 3, 2013 at 7:22 AM, Yitzchak Gale
Do GHC-compiled binaries have a dynamic dependence on libgmp? If so, what are the exact requirements we need to communicate to our customers? Does this limit what versions of Linux we can claim that our product supports?
Are there similar requirements and limitations regarding GNU Readline?
GHC uses static libraries for Haskell libraries, but the default (usually dynamic) system libraries for everything else (gmp, glibc, readline, zlib, etc.) unless you force static linking for everything. But on Linux, static linking means an exact glibc version dependency for anything involving plugins: mostly name service lookups (gethostbyname, user/group lookup, etc.). And even bundling glibc and its plugins to avoid this can run into conflicts with kernel APIs (often revealed as the program crashing immediately with a itimer error). glibc should almost always be dynamic. Ideally you would use `ldd` on binaries to determine other dynamic dependencies that must be communicated or provided; if necessary, you can arrange for only static versions of those libraries to be available at link time, but if the library uses plugins it will have the same issues that static linking glibc does. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Hi Brandon, Thanks for your response and explanation. I wrote:
[For] GHC-compiled binaries... what are the exact requirements we need to communicate to our customers?
You wrote:
Ideally you would use `ldd` on binaries to determine other dynamic dependencies that must be communicated
ldd just says "not a dynamic executable". When run against ghc itself, ldd gives a list of 11 dynamic libraries, and for each of them the specific binary version of the library that it linked against on my own particular machine. Does the machine on which we run the GHC-compiled binary need every single one of these libraries in order to run? Here is the list of libraries - identical for both GHC 7.4.2 and GHC 7.6.3: linux-vdso.so.1 libncursesw.so.5 librt.so.1 libutil.so.1 libdl.so.2 libgmp.so.3 libm.so.6 libpthread.so.0 libc.so.6 libtinfo.so.5 /lib64/ld-linux-x86-64.so.2 Thanks, Yitz

On Thu, Oct 3, 2013 at 1:10 PM, Yitzchak Gale
I wrote:
[For] GHC-compiled binaries... what are the exact requirements we need to communicate to our customers?
You wrote:
Ideally you would use `ldd` on binaries to determine other dynamic dependencies that must be communicated
ldd just says "not a dynamic executable".
o.O I don't think the ghc runtime uses dlopen() to get at gmp (and I'm not sure that would even work in a static binary). You may need to resort to strace to find out what's trying to pull in libgmp.so.whatever. Unless this program is like xmonad and requires ghc behind the scenes to build something, in which case you would indeed need everything that ghc requires (and, of course, ghc itself). -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Brandon Allbery wrote:
On Thu, Oct 3, 2013 at 1:10 PM, Yitzchak Gale
wrote: ldd just says "not a dynamic executable".
o.O I don't think the ghc runtime uses dlopen() to get at gmp (and I'm not sure that would even work in a static binary). You may need to resort to strace to find out what's trying to pull in libgmp.so.whatever. Unless this program is like xmonad and requires ghc behind the scenes to build something, in which case you would indeed need everything that ghc requires (and, of course, ghc itself).
I suspect the OP's exectuable is aleady being compiled static. For the webapp I'm currently working on I get: > ldd test-webapp linux-vdso.so.1 (0x00007fffcdd91000) libpq.so.5 => /usr/lib/libpq.so.5 (0x00007f973e0a8000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f973de90000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f973dc87000) libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f973da84000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f973d880000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f973d663000) libldap_r-2.4.so.2 => /usr/lib/x86_64-linux-gnu/libldap_r-2.4.so.2 (0x00007f973d412000) liblber-2.4.so.2 => /usr/lib/x86_64-linux-gnu/liblber-2.4.so.2 (0x00007f973d203000) libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f973cf8a000) libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f973cd82000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f973ca84000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f973c6d7000) libssl.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f973c479000) libcrypto.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f973c087000) libkrb5.so.3 => /usr/lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007f973bdb2000) libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f973bbae000) libgssapi_krb5.so.2 => /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007f973b96f000) /lib64/ld-linux-x86-64.so.2 (0x00007f973e2f9000) libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f973b757000) libsasl2.so.2 => /usr/lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007f973b53c000) libgnutls.so.26 => /usr/lib/x86_64-linux-gnu/libgnutls.so.26 (0x00007f973b27c000) libgcrypt.so.11 => /lib/x86_64-linux-gnu/libgcrypt.so.11 (0x00007f973affc000) libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f973add3000) libkrb5support.so.0 => /usr/lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007f973abc9000) libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f973a9c5000) libtasn1.so.3 => /usr/lib/x86_64-linux-gnu/libtasn1.so.3 (0x00007f973a7b3000) libp11-kit.so.0 => /usr/lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007f973a593000) libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f973a38e000) and libgmp is clearly listed in that. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

On Thu, Oct 3, 2013 at 3:43 PM, Erik de Castro Lopo
Brandon Allbery wrote:
On Thu, Oct 3, 2013 at 1:10 PM, Yitzchak Gale
wrote: ldd just says "not a dynamic executable".
o.O I don't think the ghc runtime uses dlopen() to get at gmp (and I'm not sure that would even work in a static binary). You may need to resort to
I suspect the OP's exectuable is aleady being compiled static.
Yes; which leaves the question of why it requires libgmp.so, and if it's static the only things I can think of are (a) it's using dlopen(), or (b) it's running something else that is not static and requires libgmp.so. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

I suspect the OP's exectuable is already being compiled static.
Yes; which leaves the question of why it requires libgmp.so, and if it's static the only things I can think of are (a) it's using dlopen(), or (b) it's running something else that is not static and requires libgmp.so.
You built ghc yourself? And ran ldd on $bindir/ghc or $libdir/ghc-version ? Jens

You may need to resort to strace to find out what's trying to pull in libgmp.so.whatever.
I don't know how to do that. And anyway, I don't have access to the machine on which the customer is reporting this. I do believe the report - there is no compilation going on here, they are only running our GHC-compiled binary. They know nothing about GHC (not even that we are using it). I was hoping that there would be some general knowledge about this so I could just pass it on to our customers. But I see everyone else is as surprised as I am about a supposedly static GHC-compiled binary requiring a libgmp.so to run.
Unless this program is like xmonad and requires ghc behind the scenes to build something, in which case you would indeed need everything that ghc requires (and, of course, ghc itself).
No definitely not. Erik de Castro Lopo wrote:
I suspect the OP's exectuable is already being compiled static.
I compiled it static. Brandon Allbery wrote:
Yes; which leaves the question of why it requires libgmp.so, and if it's static the only things I can think of are (a) it's using dlopen(), or (b) it's running something else that is not static and requires libgmp.so.
Right. Could a dependent library be causing this? For example, this program depends on direct-sqlite, which in turn links to sqlite via FFI. It also depends on wai, which pulls in quite a few indirect dependencies. If so - how would I investigate this and get a complete list of the system libraries that customers are required to install as prerequisites? Jens Petersen wrote:
You built ghc yourself?
No. It is the generic Linux binary tarball from GHC HQ.
And ran ldd on $bindir/ghc or $libdir/ghc-version ?
No, in $bindir that's just a shell script. It's in $libdir. The executable is ghc; ghc-version is a directory containing object files compiled from libraries. Thanks, Yitz

I remember Tim Dysinger telling me some incantations needed to statically link Gmp into the static binary before deployment. I'll pester him to re remember what's needed, but the point is there's a way. On Wednesday, October 9, 2013, Yitzchak Gale wrote:
You may need to resort to strace to find out what's trying to pull in libgmp.so.whatever.
I don't know how to do that. And anyway, I don't have access to the machine on which the customer is reporting this. I do believe the report - there is no compilation going on here, they are only running our GHC-compiled binary. They know nothing about GHC (not even that we are using it).
I was hoping that there would be some general knowledge about this so I could just pass it on to our customers. But I see everyone else is as surprised as I am about a supposedly static GHC-compiled binary requiring a libgmp.so to run.
Unless this program is like xmonad and requires ghc behind the scenes to build something, in which case you would indeed need everything that ghc requires (and, of course, ghc itself).
No definitely not.
Erik de Castro Lopo wrote:
I suspect the OP's exectuable is already being compiled static.
I compiled it static.
Brandon Allbery wrote:
Yes; which leaves the question of why it requires libgmp.so, and if it's static the only things I can think of are (a) it's using dlopen(), or (b) it's running something else that is not static and requires libgmp.so.
Right.
Could a dependent library be causing this? For example, this program depends on direct-sqlite, which in turn links to sqlite via FFI. It also depends on wai, which pulls in quite a few indirect dependencies.
If so - how would I investigate this and get a complete list of the system libraries that customers are required to install as prerequisites?
Jens Petersen wrote:
You built ghc yourself?
No. It is the generic Linux binary tarball from GHC HQ.
And ran ldd on $bindir/ghc or $libdir/ghc-version ?
No, in $bindir that's just a shell script. It's in $libdir. The executable is ghc; ghc-version is a directory containing object files compiled from libraries.
Thanks, Yitz _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org javascript:; http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

there seem to be two main approaches (which both require some testing)
1) build ghc with integer-simple
2) do some static linking tricks on your side, such as those described in
http://stackoverflow.com/questions/809794/use-both-static-and-dynamically-li...,
this might entail that you need to know the precise OS / Distro a client is
using before you give them a binary, but might make the process much
simpler overall (despite its relative hackiness)
On Wed, Oct 9, 2013 at 2:22 PM, Carter Schonwald wrote: I remember Tim Dysinger telling me some incantations needed to statically
link Gmp into the static binary before deployment. I'll pester him to re
remember what's needed, but the point is there's a way. On Wednesday, October 9, 2013, Yitzchak Gale wrote: You may need to resort to
strace to find out what's trying to pull in libgmp.so.whatever. I don't know how to do that. And anyway, I don't have access to
the machine on which the customer is reporting this. I do believe
the report - there is no compilation going on here, they are
only running our GHC-compiled binary. They know nothing
about GHC (not even that we are using it). I was hoping that there would be some general knowledge about
this so I could just pass it on to our customers. But I see everyone
else is as surprised as I am about a supposedly static GHC-compiled
binary requiring a libgmp.so to run. Unless this
program is like xmonad and requires ghc behind the scenes to build
something, in which case you would indeed need everything that ghc
requires
(and, of course, ghc itself). No definitely not. Erik de Castro Lopo wrote: I suspect the OP's exectuable is already being compiled static. I compiled it static. Brandon Allbery wrote: Yes; which leaves the question of why it requires libgmp.so, and if
it's
static the only things I can think of are (a) it's using dlopen(), or
(b)
it's running something else that is not static and requires libgmp.so. Right. Could a dependent library be causing this? For example, this
program depends on direct-sqlite, which in turn links to
sqlite via FFI. It also depends on wai, which pulls in quite a few
indirect dependencies. If so - how would I investigate this and get a complete list of
the system libraries that customers are required to install
as prerequisites? Jens Petersen wrote: You built ghc yourself? No. It is the generic Linux binary tarball from GHC HQ. And ran ldd on $bindir/ghc or $libdir/ghc-version ? No, in $bindir that's just a shell script. It's in $libdir.
The executable is ghc; ghc-version is a directory containing
object files compiled from libraries. Thanks,
Yitz
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

NB: I'm told that building ghc with integer-simple doesn't work on linux?!
(though the person who told me this may not have filed a ticket about this
on trac, so i'm not sure if its still an issue with ghc head or not )
On Wed, Oct 9, 2013 at 2:47 PM, Carter Schonwald wrote: there seem to be two main approaches (which both require some testing) 1) build ghc with integer-simple 2) do some static linking tricks on your side, such as those described in
http://stackoverflow.com/questions/809794/use-both-static-and-dynamically-li...,
this might entail that you need to know the precise OS / Distro a client is
using before you give them a binary, but might make the process much
simpler overall (despite its relative hackiness) On Wed, Oct 9, 2013 at 2:22 PM, Carter Schonwald <
carter.schonwald@gmail.com> wrote: I remember Tim Dysinger telling me some incantations needed to
statically link Gmp into the static binary before deployment. I'll pester
him to re remember what's needed, but the point is there's a way. On Wednesday, October 9, 2013, Yitzchak Gale wrote: You may need to resort to
strace to find out what's trying to pull in libgmp.so.whatever. I don't know how to do that. And anyway, I don't have access to
the machine on which the customer is reporting this. I do believe
the report - there is no compilation going on here, they are
only running our GHC-compiled binary. They know nothing
about GHC (not even that we are using it). I was hoping that there would be some general knowledge about
this so I could just pass it on to our customers. But I see everyone
else is as surprised as I am about a supposedly static GHC-compiled
binary requiring a libgmp.so to run. Unless this
program is like xmonad and requires ghc behind the scenes to build
something, in which case you would indeed need everything that ghc
requires
(and, of course, ghc itself). No definitely not. Erik de Castro Lopo wrote: I suspect the OP's exectuable is already being compiled static. I compiled it static. Brandon Allbery wrote: Yes; which leaves the question of why it requires libgmp.so, and if
it's
static the only things I can think of are (a) it's using dlopen(), or
(b)
it's running something else that is not static and requires libgmp.so. Right. Could a dependent library be causing this? For example, this
program depends on direct-sqlite, which in turn links to
sqlite via FFI. It also depends on wai, which pulls in quite a few
indirect dependencies. If so - how would I investigate this and get a complete list of
the system libraries that customers are required to install
as prerequisites? Jens Petersen wrote: You built ghc yourself? No. It is the generic Linux binary tarball from GHC HQ. And ran ldd on $bindir/ghc or $libdir/ghc-version ? No, in $bindir that's just a shell script. It's in $libdir.
The executable is ghc; ghc-version is a directory containing
object files compiled from libraries. Thanks,
Yitz
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
participants (5)
-
Brandon Allbery
-
Carter Schonwald
-
Erik de Castro Lopo
-
Jens Petersen
-
Yitzchak Gale