cabal
cabal copied to clipboard
Provide statically-linked `cabal-install` releases
Current binary releases of cabal-install
are not statically linked, thus depending on glibc
, which makes them unusable on musl
-based distros like Alpine Linux. It'd be nice if statically-linked binary releases (at least for x64 Linux) can be provided for cabal-install-2.0.0.1
and future versions.
Yep, makes sense. I'll try to do that for the next release. Can you point me to some resources on how to build statically-linked Haskell binaries? I know of https://www.fpcomplete.com/blog/2016/10/static-compilation-with-stack.
@23Skidoo I built a static cabal
for my own project, simply by adding a ld-options: -static
line to cabal-install.cabal
and building it in an Alpine image. No extra flags/hacks is needed.
For your convenience, you may use docker pull terrorjack/meikyu:ghc-8.2.2
to get the image I use myself, it has ghc
, stack
and cabal
pre-installed. Or take a look at the master
branch of https://github.com/TerrorJack/meikyu for the relatively simple build script for the image.
@TerrorJack Is there a similar 32-bit image?
@23Skidoo Nope. The hard lifting is done by @mitchty who provides ghc
packages on Alpine (which are used to bootstrap later ghc
releases), yet there's only x86_64
and armhf
versions available as of now.
Same as @TerrorJack, I use this dockerfile https://github.com/erebe/wstunnel/blob/master/Dockerfile based from stock alpine images to build static binary. (thanks to @mitchty)
The blog post from fpcomplete is outdated, as @TerrorJack said only adding ld-options: -static in the cabal file of the project do the tricks.
I was planning to do a blog post to explain how to do it properly in order to avoid the hack explained in the fpcomplete blog post, but I was hoping for this issue https://github.com/haskell/cabal/issues/4925 to be resolved before doing it
@TerrorJack @erebe @mitchty Is it possible to use a 32-bit binary GHC distribution from https://www.haskell.org/ghc/download_ghc_8_0_2.html#linux_i386 with a 32-bit Alpine Docker image or do I need to build GHC myself?
@23Skidoo You need to build it yourself, and since there's no ghc binary package for i386, you need to cross-compile it in a glibc based distro.
:-(
I have it on my list to finish getting ghc ported/cross-compiled to the rest of alpine's archictectures, i386 would probably be the easiest of them.
What kind of timeframe were you looking at?
@mitchty That's great to hear! Thank you for working on this. I think that the next major release of cabal-install
will be out at the end of January.
@23Skidoo okie dokie, i'll poke around at the cross compiling again, cross compiling ghc is... not the most intuitive thing to do to be honest. And getting x86 as an arch has been asked by at least a few people, but just wasn't a priority for the initial port.
But compared to arm it shouldn't be too crazy. If I get it up and running I should be able to build alpine linux ghc bindists that you could use until apk packages are ready/built (or after for that matter).
@mitchty Thanks a lot!
We could probably cross compile for musl via nix very shortly.
CC @bgamari @dtzwill @kmicklas @taktoa
@mitchty Any updates? The 2.2 cabal-install release will be out in ~2 weeks, would be cool to have statically-linked 32-bit binaries for it as well.
Musl cross landed (on staging) in nixpkgs. I can look into this now.
@Ericson2314 Are you still interested in this? Would be nice if you (or someone) could produce static cabal-install
Linux binaries for 2.2.0.0.
Yeah I'm still interested. It depends on https://github.com/NixOS/nixpkgs/pull/37598 being resolved, but I can assist with that.
Great.
Nix now makes it possible to build fully statically linked cabal-install
builds.
This is based upon, among others, @Ericson2314's work mentioned just above.
I have completed such a build here
Quick note: It's not enough to naively think one can build statically linked executables and things will just work, as library routines like gethostbyname(3)
and friends will not pick up the system wide name resolution configuration and/or NSS plugins and all that jazz. It's doable to make statically linked executables of cabal
but it requires a bit more work to do it properly.
We can mark statically-linked cabal-install
binaries "experimental" initially, maybe someone will then come up with a patch to fix the gethostbyname
issue and other statically-linked-only problems.
@23Skidoo offering statically linked cabal-install binaries with a "use at your own risk" disclaimer pointing out the potential problems sounds good to me.
gethostbyname(3)
and friends will not pick up the system wide name resolution configuration
@hvr What do you mean by that? musl
libc reads resolv.conf
, like anything else does.
Correspondingly I'm also not quite sure what
a patch to fix the
gethostbyname
issue
would look like in @23Skidoo's comment.
and/or NSS plugins and all that jazz
Yes, NSS is a glibc specific feature. Probably not relevant unless somebody wants to resolve resolve .local
domains with cabal, and doens't use localhost dnsmasq (most Linux distributions seem to do that these days).
Based on some discussion in haskell/ghcup#68 it sounds like this should be closed, given that http://downloads.haskell.org/cabal/cabal-install-2.4.1.0/cabal-install-2.4.1.0-x86_64-alpine-linux-musl.tar.xz is now available.
that http://downloads.haskell.org/cabal/cabal-install-2.4.1.0/cabal-install-2.4.1.0-x86_64-alpine-linux-musl.tar.xz is now available.
That executable is not statically linked:
% file cabal
tmp/cabal: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped
% ldd cabal
linux-vdso.so.1 => (0x00007ffc4edda000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc80b0da000)
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fc80ae5a000)
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007fc80ac52000)
libc.musl-x86_64.so.1 => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc80a888000)
/lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007fc80b2f4000)
@nh2 I see some steady improvements in static-haskell-nix. I understand that it should in theory be possible now to build a statically-linked cabal-install. Are there any guidelines / blog posts describing how a Haskell software can benefit from static-haskell-nix? In particular, Cabal is using GitLab CI for making releases this day (see .gitlab-ci.yml
in this repo). Would it be hard to integrate static binaries into this workflow? (The workflow is a bit involved, though, as per this wiki page.)
IIRC, the Alpine binaries on gitlab are statically linked, but they are not totally static. IIRC, they require pthreads that makes HEAD GHC fail on my ancient Ubuntu (cabal probably uses an older version of the pthreads so it doesn't fail). Unless I'm misdiagnosing why the binaries from HEAD GHC snapshots fail for me.
At least,
❯ wget https://downloads.haskell.org/~cabal/cabal-install-3.8.1.0/cabal-install-3.8.1.0-x86_64-linux-alpine.tar.xz
...
❯ tar -xf cabal-install-3.8.1.0-x86_64-linux-alpine.tar.xz
...
❯ ldd cabal
not a dynamic executable
ldd
was used above (https://github.com/haskell/cabal/issues/4941#issuecomment-463253348) to show that it's not static. So, that argument no longer applies. I propose we close this as completed and wait for a more detailed account of what's wrong with the curent alpine binary (if anything).
Yeah, I hope alpine is fine for most users. Thank you for the gardening. :) Closing.