Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support musl-based Linux distributions like Alpine Linux #2387

Closed
borsboom opened this issue Jul 18, 2016 · 71 comments
Closed

Support musl-based Linux distributions like Alpine Linux #2387

borsboom opened this issue Jul 18, 2016 · 71 comments
Assignees
Milestone

Comments

@borsboom
Copy link
Contributor

@dysinger has had success building Stack on Alpine using GHC 8.0.1 from here: https://github.com/mitchty/alpine-linux-ghc-bootstrap. Once there is a Stackage LTS release that uses GHC 8, we can consider adding official support for Alpine Linux.

@borsboom borsboom added this to the P3: Optional milestone Jul 18, 2016
@borsboom borsboom modified the milestones: P2: Should, P3: Optional Jul 18, 2016
@borsboom borsboom self-assigned this Jul 18, 2016
@borsboom
Copy link
Contributor Author

For Alpine support, we need GHC bindists. I'm putting out a call to the community for help in creating those: can anyone out there provide GHC 8.0.1 bindists for x86_64 and x86 (32-bit) at a minimum? Would also be nice to have GHC 7.10.3 bindists, and bindists for the armhf platform, but that's less important. This looks like a good starting point: https://github.com/mitchty/alpine-linux-ghc-bootstrap

@borsboom
Copy link
Contributor Author

borsboom commented Aug 7, 2017

Possibly relevant: musl bindists of ghc 8.2.1. I have not tried them; anyone available to do so? (ping @mitchty)

@mitchty
Copy link
Contributor

mitchty commented Aug 7, 2017

They may work post 8.0.2, but the last time I tried gentoo musl produced bindists they included TEXT relocations in shared libraries which means you can't link anything you build with them. Alpine Linux has hardening on that will prevent such things from linking.

If thats the case they probably won't work at all. Worth a shot to try. You could test with the alpine/latest docker image if you want.

@mitchty
Copy link
Contributor

mitchty commented Aug 26, 2017

Managed to get some time last night to get Jenkins up and running and doing builds. While it takes forever and an age to build ghc on armhf (like an entire day), I can get bindists generated now.

Still need to brain on how I want to do this going forward but in essence my strategy is: patch the APKBUILD in aports to also build bindists, then snag those bindists out of the build directory.

For 32bit ghc however I still need to get the cross compile to work sanely and get a build vm setup that I can hook Jenkins up to test things. But I need to do that to validate things in alpine linux proper anyway.

But in about a week or so I should have some strategy for bindists. How do/should they get generated/updated? My thoughts are follow the standard APKBUILD, for each release update the bindist and have say a -latest link to point to the latest bindist release for each specific major version. Keeping the last... N releases.

Thoughts?

@borsboom
Copy link
Contributor Author

borsboom commented Sep 5, 2017

I know nothing about how Alpine packages work, so I don't really have an opinion TBH. For the purposes of Stack, the only thing that matters is having a working working bindist for each released GHC version (it's OK if that's just starting with the latest GHC version, although having versions going back to 7.10.3 would be nice).

@decentral1se
Copy link
Member

Any progress @mitchty!? This'd be really cool to get done.

@decentral1se
Copy link
Member

decentral1se commented Sep 12, 2017

Whoever ends up closing this, I think it also closes #2717.

Just scanning through, but looks to be the case.

@mitchty
Copy link
Contributor

mitchty commented Sep 13, 2017

Work is a bit hectic so this is a bit on the back burner. But what I have partially is the ability to generate apks similar to hvr's ppa putting things in /opt/ghc/$version.

While that builds I hacked into the apkbuild process the ability to build bindists as well. This isn't too onerous with x86_64 but armhf takes forever and a day, actually 3 days to build stuff.

it needs some cleanup but shouldn't be too hard to finish up. Once I can focus back on it a bit I'll finish it off.

@mitchty
Copy link
Contributor

mitchty commented Sep 17, 2017

Heh, well I got it working, only to find a bug in the llvm3.7 package too. It needs to get recompiled for alpine linux 3.6. As it is you see this on make install:

Installing library in /usr/local/lib/ghc-8.0.2/ghci-8.0.2
"utils/ghc-cabal/dist-install/build/tmp/ghc-cabal-bindist" copy compiler stage2 ":" '' '/usr/local' '/usr/local/lib/ghc-8.0.2' '/usr/local/share/doc/ghc-8.0.2/html/libraries' 'v p dyn'
Installing library in /usr/local/lib/ghc-8.0.2/ghc-8.0.2
"/tmp/ghc-8.0.2/utils/ghc-pkg/dist/build/tmp/ghc-pkg" --force --global-package-db "/usr/local/lib/ghc-8.0.2/package.conf.d" update rts/dist/package.conf.install
/bin/sh: /tmp/ghc-8.0.2/utils/ghc-pkg/dist/build/tmp/ghc-pkg: not found
make[1]: *** [ghc.mk:985: install_packages] Error 127
make: *** [Makefile:51: install] Error 2

That is all due to missing symbols in libc++ that the older llvm3.7 was linked against that alpine linux 3.6 doesn't have. I swear I am a magnet for finding unrelated bugs in things.

@mitchty
Copy link
Contributor

mitchty commented Sep 18, 2017

Good news everyone! I was wrong in the last comment. I think I got it working. You as a user need to:

Add the community apk repository to your alpine system (if necessary). Example here is for alpine linux 3.6.

echo "http://dl-cdn.alpinelinux.org/alpine/v3.6/community" >> /etc/apk/repositories
apk update
apk add alpine-sdk llvm3.7 perl binutils gmp-dev clang gcc libffi-dev

Then try this out:
https://mitchty.net/ghc/8.0.2/ghc-8.0.2-x86_64-alpine-linux.tar.xz

It seems to work for me but i just did MINIMAL testing, aka compile hello world, ./configure --prefix=/tmp/ghc example:

/tmp/ghc-8.0.2 # echo 'main = putStrLn "hi"' > /tmp/hi.hs
/tmp/ghc-8.0.2 # /tmp/ghc/bin/ghc --make /tmp/hi.hs
Linking /tmp/hi ...
/tmp/ghc-8.0.2 # /tmp/hi
hi

I have 8.2.1 working as well but only for x86_64. It'll take a while to get that going but test away.

@mbj
Copy link
Contributor

mbj commented Dec 20, 2017

I'd prefer we use APK as primary way to package GHC for alpine.

@mitchty Some of your patches where merged upstream already. Can you publish your 8.2.1 apkbuild somewhere, I'd try to adapt it to 8.2.2 and publish my findings here.

@mitchty
Copy link
Contributor

mitchty commented Dec 20, 2017

Its already been done, the issue is building on armhf segfaults in the stage2 builder. Thats the only reason there isn't an update for ghc in alpine linux right now, generally frowned on to remove a platform from the supported arches list. Debugging this is... trying as I need to negate out llvm, musl patches, ghc, the rts, etc...

Apkbuild is here:
alpinelinux/aports@master...mitchty:jenkins-8.2.2

@mitchty
Copy link
Contributor

mitchty commented Dec 20, 2017

Note, that has the binary distribution stuff in it as well, you might want to rip that out if you don't want to build the binary distribution tar.xz files.

Essentially this is my jenkins branch that I use to test release candidates and to build the above binary distribution files. But for 8.2.2, I have 8.2.1 and 8.0.2 as well for x86_64, example:

https://mitchty.net/ghc/8.2.2/ghc-8.2.2-x86_64-alpine-linux.tar.xz

If anyone wants I can resurrect my apk signing keys and plop up the apks I build out of jenkins into that web server until I can fully debug the armhf segfault issue.

@mbj
Copy link
Contributor

mbj commented Dec 20, 2017

@mitchty Would alpine accept your apk if its not supporting armhf? And thx for the pointer. I can temporarily unblock myself now.

@mbj
Copy link
Contributor

mbj commented Dec 20, 2017

If anyone wants I can resurrect my apk signing keys and plop up the apks I build out of jenkins into that web server until I can fully debug the armhf segfault issue.

for now I'll build / package it by myself, but thanks for the offer. I think your time is better spend in getting the changes upstream ;) I do not want to reduce the chance of this happening soon.

@ketzacoatl
Copy link
Contributor

In case this detail is helpful.. As of right now, running the static linux executable for stack, in an alpine 3.7 container, GHC build blows up with errors about cabal:

#  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts" = directory to install to
#
# The .dll case calls STRIP_CMD explicitly, instead of `install -s`, because
# on Win64, "install -s" calls a strip that doesn't understand 64bit binaries.
# For some reason, this means the DLLs end up non-executable, which means
# executables that use them just segfault.
/usr/bin/install -c -m 755 -d  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts"
for i in  rts/dist/build/libHSrts.a rts/dist/build/libHSrts_p.a rts/dist/build/libHSrts-ghc8.2.2.so rts/dist/build/libHSrts_l.a rts/dist/build/libHSrts_debug.a rts/dist/build/libHSrts_thr.a rts/dist/build/libHSrts_thr_debug.a rts/dist/build/libHSrts_thr_l.a rts/dist/build/libHSrts_thr_p.a rts/dist/build/libHSrts_debug-ghc8.2.2.so rts/dist/build/libHSrts_thr-ghc8.2.2.so rts/dist/build/libHSrts_thr_debug-ghc8.2.2.so rts/dist/build/libHSrts_l-ghc8.2.2.so rts/dist/build/libHSrts_thr_l-ghc8.2.2.so rts/dist/build/libffi.so rts/dist/build/libffi.so.6 rts/dist/build/libffi.so.6.0.4 rts/dist/build/libCffi.a rts/dist/build/libCffi_p.a rts/dist/build/libCffi_l.a rts/dist/build/libCffi_debug.a rts/dist/build/libCffi_thr.a rts/dist/build/libCffi_thr_debug.a rts/dist/build/libCffi_thr_l.a rts/dist/build/libCffi_thr_p.a; do case $i in *.a) /usr/bin/install -c -m 644  $i  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts"; true  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts"/`basename $i` ;; *.dll) /usr/bin/install -c -m 755  $i  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts" ; :  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts"/`basename $i` ;; *.so) /usr/bin/install -c -m 755  $i  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts" ;; *.dylib) /usr/bin/install -c -m 755  $i  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts";; *) /usr/bin/install -c -m 644  $i  "/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2/rts"; esac; done
"utils/ghc-cabal/dist-install/build/tmp/ghc-cabal-bindist" copy libraries/ghc-prim dist-install ":" '' '/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2' '/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/lib/ghc-8.2.2' '/root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/share/doc/ghc-8.2.2/html/libraries' 'v p dyn'  

utils/ghc-cabal/dist-install/build/tmp/ghc-cabal-bindist: exec: line 3: utils/ghc-cabal/dist-install/build/tmp/ghc-cabal: not found
make[1]: *** [ghc.mk:991: install_packages] Error 127
make: *** [Makefile:51: install] Error 2

                  
Error: Error encountered while installing GHC with
         make install
         run in /root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2.temp/ghc-8.2.2/
       
       The following directories may now contain files, but won't be used by stack:
         - /root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2.temp/
         - /root/.stack/programs/x86_64-linux/ghc-ncurses6-nopie-8.2.2/
``

@borsboom
Copy link
Contributor Author

@ketzacoatl Did you add setup-info configuration pointing to @mitchty's bindist for the linux64-ncurses6-nopie OS key? If not, Stack will try to install a standard glibc bindist, since it doesn't know about Alpine specifically.

I've not tried the bindist above on Alpine myself, so I'd be very interested in the results.

@ketzacoatl
Copy link
Contributor

I have added the following to my stack.yaml:

resolver: lts-10.2

setup-info:
  ghc:
    linux64-alpine:
      8.2.2:
        url: https://mitchty.net/ghc/8.2.2/ghc-8.2.2-x86_64-alpine-linux.tar.xz

ghc-build: alpine

and then I run into the LLVM bug mitchty noted in a previous comment, even with the updates he noted. For example, this build is run in a docker image that has the packages installed as noted in mitchty's instructions, but fails with:


/bin/sh: /builds/web/haskell-data-sink-demo/.stack-root/programs/x86_64-linux/ghc-alpine-8.2.2.temp/ghc-8.2.2/utils/ghc-pkg/dist/build/tmp/ghc-pkg: not found
make[1]: *** [ghc.mk:992: install_packages] Error 127
make: *** [Makefile:51: install] Error 2


Error: Error encountered while installing GHC with
         make install
         run in /builds/web/haskell-data-sink-demo/.stack-root/programs/x86_64-linux/ghc-alpine-8.2.2.temp/ghc-8.2.2/
       
       The following directories may now contain files, but won't be used by stack:
         - /builds/web/haskell-data-sink-demo/.stack-root/programs/x86_64-linux/ghc-alpine-8.2.2.temp/
         - /builds/web/haskell-data-sink-demo/.stack-root/programs/x86_64-linux/ghc-alpine-8.2.2/
       
ERROR: Job failed: exit code 1

ketzacoatl added a commit to ketzacoatl/default-build-image that referenced this issue Jan 16, 2018
@nh2
Copy link
Collaborator

nh2 commented Sep 17, 2018

I have also now uploaded a prerelease static musl build for stack-1.9.0.1 on https://github.com/nh2/stack/releases/tag/v1.6.5 and would appreciate testing.

@hasufell
Copy link
Contributor

As far as I remember, system-ghc picks it from PATH, so you could do PATH=/path/to/desired/ghc/bin:$PATH stack build

I don't understand what that means. I'm talking about the alpine ghc packages, see https://pkgs.alpinelinux.org/packages?name=ghc&branch=edge

Also, I think you can use stack's feature to configure custom compilers, so these might be two workarounds for now.

There is no custom compiler to install that works under alpine. GHC upstream doesn't provide one, stack doesn't and the distro only provides one arbitrary version, as already explained.

@nh2
Copy link
Collaborator

nh2 commented Sep 20, 2018

@hasufell I know that there's currently no ghc available on Alpine, I was just referring to

system-ghc you can have, not multiple at the same time

which sounded like "if there were multiple compilers available, it would be difficult to switch them using system-ghc". But perhaps I misunderstood what you meant to say with that, and you meant something else?

@hasufell
Copy link
Contributor

I wasn't talking about the command system-ghc.

@rhizoome
Copy link

@nh2 Of course there is ghc on Alpine: https://pkgs.alpinelinux.org/packages?name=ghc&branch=v3.8

I use it every day, but since stack cannot bootstrap on Alpine you have to use "system-ghc", which is the ghc version above. That's not like stack is meant to be used, so at the moment I rather use: cabal new-*

@ketzacoatl
Copy link
Contributor

@mitchty (or anyone else watching this thread), I'd like to build bindists for alpine, where do I get started?

@borsboom
Copy link
Contributor Author

borsboom commented Jun 9, 2019

It looks like @redneb is building musl-based GHC bindists for recent GHC releases, and people seem to be able to install them on Alpine Linux using the standard ./configure --prefix=… && make install that stack setup uses. In theory, this may be all Stack needs to fully support Alpine Linux (plus a bit of logic to detect when running on a musl-based distro and choose a different bindist to download).

Any interested Alpine user out there who can give this a try? You'd use the setup-info configuration to point stack setup to the right bindist.

edit: I see I linked to these a couple of years ago, but it doesn't look like anybody actually tried them (perhaps due to the following comment).

@borsboom
Copy link
Contributor Author

borsboom commented Jun 9, 2019

Update: I decided to try this myself. I added the following to my ~/.stack/config.yaml:

setup-info:                                                                                                                                    
  ghc:                                                                                                                                         
    linux64-ncurses6:                                                                                                                          
      8.6.5:                                                                                                                                   
        url: "https://github.com/redneb/ghc-alt-libc/releases/download/ghc-8.6.5-musl/ghc-8.6.5-x86_64-unknown-linux-musl.tar.xz"              

And then ran stack setup, which worked (once I apk added the right prerequisites). I've been able to build a "hello world" program both as a dynamically linked and as a statically linked binary (using stack build --ghc-options='-optl-static -optl-pthread'), and it seems to work. Next up: trying out building stack itself statically linked.

@borsboom
Copy link
Contributor Author

borsboom commented Jun 9, 2019

Note for whomever implements detection of musl-based distributions: this node package appears to have decent libc detection logic that we could use as inspiration: https://github.com/lovell/detect-libc/blob/master/lib/detect-libc.js

@borsboom
Copy link
Contributor Author

borsboom commented Jun 9, 2019

Next up: trying out building stack itself statically linked.

This seems to have worked as well.

However, there is a problem that's exposed when I try to use the bindist with the upcoming stack-2.1 which does some extra sanity checking (I had been using stack-1.9.3 before): it fails to install a haddock binary.

Downloaded ghc-ncurses6-8.6.5.               
[…]
Installed GHC.
Found an invalid compiler at "/root/.stack/programs/x86_64-linux/ghc-ncurses6-8.6.5/bin/ghc-8.6.5": Control.Exception.Safe.throwString called with:

Could not find any of: ["/root/.stack/programs/x86_64-linux/ghc-ncurses6-8.6.5/bin/haddock-8.6.5","/root/.stack/programs/x86_64-linux/ghc-ncurses6-8.6.5/bin/haddock-ghc-8.6.5","/root/.stack/programs/x86_64-linux/ghc-ncurses6-8.6.5/bin/haddock","/root/.stack/programs/x86_64-linux/ghc-ncurses6-8.6.5/bin/haddock-ghc"]

Opened an issue on ghc-alt-libc for this here: redneb/ghc-alt-libc#5

@borsboom
Copy link
Contributor Author

@redneb has very kindly, and quickly, uploaded new ghc 8.6.5 bindists that fix the haddock issue. I've tested them with stack-2.1 and they seem to work great (including stack haddock). I've gone ahead and added stack setup metadata for them in commercialhaskell/stackage-content@f6eb573 with a new -musl OS key suffix.

Now what's left is adding logic to stack setup to detect when running on a musl-based distro and use the new -musl OS key suffix to choose the bindist.

@redneb
Copy link

redneb commented Jun 11, 2019

I have two remarks about this:

  • It would be better to install ghc using ./configure --disable-ld-override --prefix=… && make install. Without the --disable-ld-override option, ghc will try to use ld.gold as its linker, which in my tests causes it to segfault. This might not be needed for alpine because its binutils package does not install ld.gold, but it might cause problems in other musl based environments such as gentoo musl (which includes ld.gold by default).
  • I produce my ghc binaries in a gentoo musl system. This could potentially cause issues in the future, if the sonames for libgmp and libncursesw do not match between gentoo and alpine. Of course this is a more general problem, even with glibc based builds.

@nh2
Copy link
Collaborator

nh2 commented Jun 11, 2019

  • ghc will try to use ld.gold as its linker, which in my tests causes it to segfault

@redneb Is that filed somewhere? GHC should not segfault when using gold.

@redneb
Copy link

redneb commented Jun 11, 2019

@redneb Is that filed somewhere? GHC should not segfault when using gold.

No I have not filed any bug for that, but I am not sure if this an issue with ghc. I am not sure if ld.gold is officially supposed to work under musl; in the past I even had issues with the gcc + ld.gold combination under musl, although admittedly, not any anymore.

@nh2
Copy link
Collaborator

nh2 commented Jun 11, 2019

@redneb I remember hearing/reading about some musl+gold problems, but I am quite sure that their respective authors want that these work well together.

So even if there's a segfault in gold itself, it would be very useful to post it somewhere.

Is it perhaps https://sourceware.org/bugzilla/show_bug.cgi?id=23856 (which I filed from NixOS/nixpkgs#49071 (comment))?

@redneb
Copy link

redneb commented Jun 11, 2019

Is it perhaps https://sourceware.org/bugzilla/show_bug.cgi?id=23856 (which I filed from NixOS/nixpkgs#49071 (comment))?

This sounds awfully a lot like the issue I was seeing: the binaries I get from ghc+ld.gold segfault immediately when I run them. I created redneb/ghc-alt-libc#6 to track this issue.

(apologies to everyone for the off topic spam)

@borsboom
Copy link
Contributor Author

(apologies to everyone for the off topic spam)

I'm actually tempted to rename this issue to "Support musl-based Linux distributions" rather than Alpine Linux specifically, so it's not off topic in that case :)

Until GHC release team is releasing battle-tested musl-based bindists officially, I don't think we can "officially" support Alpine Linux anyway in Stack, so I'm not sure that part of the issue title should be a hold up either. But decent experimental support for musl-based distributions would be a huge step forward (in particular, being able to use it with an Alpine-based docker image that works with --docker would make building statically linked Linux binaries really easy).

Anyone have any objections to me renaming the issue to "Support musl-based Linux distributions like Alpine Linux"?

@nh2
Copy link
Collaborator

nh2 commented Mar 10, 2020

Anyone have any objections to me renaming the issue to "Support musl-based Linux distributions like Alpine Linux"?

@borsboom Doesn't seem so, let's do it.

@borsboom borsboom changed the title Official support for Alpine Linux Support musl-based Linux distributions like Alpine Linux Mar 11, 2020
@dellelce
Copy link

Hi, just wanted to confirm that this is still current exactly 4 years after ticket was initially opened.

I am having the same issue attempting to use "stack" for building "postgrest" on alpine 3.12 with currently available ghc on alpine.

@hasufell
Copy link
Contributor

alpine musl GHCs are already part of the official bindists: https://downloads.haskell.org/~ghc/8.10.1/

@mpilgrem
Copy link
Member

I am closing this issue given the passage of time and because Stack 2.15.3 does support Alpine Linux/x86_64 (tested via WSL).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests