cabal icon indicating copy to clipboard operation
cabal copied to clipboard

Provide statically-linked `cabal-install` releases

Open TerrorJack opened this issue 6 years ago • 27 comments

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.

TerrorJack avatar Dec 08 '17 08:12 TerrorJack

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 avatar Dec 08 '17 09:12 23Skidoo

@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 avatar Dec 08 '17 09:12 TerrorJack

@TerrorJack Is there a similar 32-bit image?

23Skidoo avatar Dec 08 '17 09:12 23Skidoo

@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.

TerrorJack avatar Dec 08 '17 10:12 TerrorJack

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

erebe avatar Dec 08 '17 11:12 erebe

@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 avatar Dec 08 '17 11:12 23Skidoo

@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.

TerrorJack avatar Dec 08 '17 11:12 TerrorJack

:-(

23Skidoo avatar Dec 08 '17 12:12 23Skidoo

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 avatar Dec 08 '17 17:12 mitchty

@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 avatar Dec 09 '17 00:12 23Skidoo

@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 avatar Dec 10 '17 19:12 mitchty

@mitchty Thanks a lot!

23Skidoo avatar Dec 10 '17 19:12 23Skidoo

We could probably cross compile for musl via nix very shortly.

CC @bgamari @dtzwill @kmicklas @taktoa

Ericson2314 avatar Jan 27 '18 02:01 Ericson2314

@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.

23Skidoo avatar Feb 14 '18 22:02 23Skidoo

Musl cross landed (on staging) in nixpkgs. I can look into this now.

Ericson2314 avatar Feb 17 '18 03:02 Ericson2314

@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.

23Skidoo avatar Mar 28 '18 15:03 23Skidoo

Yeah I'm still interested. It depends on https://github.com/NixOS/nixpkgs/pull/37598 being resolved, but I can assist with that.

Ericson2314 avatar Mar 28 '18 17:03 Ericson2314

Great.

23Skidoo avatar Mar 28 '18 19:03 23Skidoo

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

nh2 avatar Jul 19 '18 01:07 nh2

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.

hvr avatar Oct 02 '18 07:10 hvr

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 avatar Oct 02 '18 12:10 23Skidoo

@23Skidoo offering statically linked cabal-install binaries with a "use at your own risk" disclaimer pointing out the potential problems sounds good to me.

hvr avatar Oct 03 '18 14:10 hvr

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).

nh2 avatar Oct 03 '18 23:10 nh2

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.

jkachmar avatar Feb 13 '19 14:02 jkachmar

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 avatar Feb 13 '19 15:02 nh2

@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.)

ulysses4ever avatar Aug 13 '22 20:08 ulysses4ever

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.

Mikolaj avatar Aug 15 '22 06:08 Mikolaj

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).

ulysses4ever avatar Aug 16 '22 13:08 ulysses4ever

Yeah, I hope alpine is fine for most users. Thank you for the gardening. :) Closing.

Mikolaj avatar Aug 16 '22 14:08 Mikolaj