Porting GHC to Alpine

I wanted to port the Glasgow Haskell Compiler to Alpine, and to do that, you need to start with some already-compiled GHC binary. So that means cross-compiling from some system where the binaries were already available.
After this is done once for each of Alpine's target architectures, other users can use those existing Alpine binaries to compile newer versions of GHC directly on Alpine, much more easily than is detailed below. (It does still take a long time.) But I am recording the steps necessary to port to Alpine in the first place, so that others can verify or reproduce my work. This may also help others porting GHC to other systems.
I assume anyone following these directions has already setup a cross-compiler targeting Alpine inside a chroot holding an existing Linux system where GHC binaries are available. These pages explain how to do that:
* Installing ArchLinux inside an Alpine chroot
* Cross-Compiler targeting Alpine
So here's how we use Arch's GHC to cross-compile a version of GHC we can run on Alpine:
<OL>
<LI>
In your outside Alpine system, do this. I assume that $ARCH_ROOT contains the absolute path on your Alpine system of the Arch chroot's . I assume also that $ARCH_HOME contains the absolute path on your Arch system of the home directory of the non-root Arch user you'll be using to build GHC. (On the other hand, the plain $ARCH variable we set below indicates your machine architecture---nothing to do with ArchLinux.)
<LI>
Inside the Arch chroot, as the non-root user, do this:
You can give the ssh key a passphrase, but it's not necessary.
<LI>
Back in the outside Alpine system, do this:
<LI>
Returning again to the Arch chroot, do:
and unlock your ssh key if you gave it a passphrase. Now from this Arch session, we can do a password-less ssh or scp to the outside Alpine system.
<LI>
Still inside the Arch chroot, do:
The two alien scripts assume that you're working with the same username on both the Alpine and Arch systems; if that's incorrect, then replace $USER with the relevant Alpine username. The alien-ghc script also assumes that you won't be working underneath any directories whose names need escaping for the shell.
<LI>
Still inside the Arch chroot, do this:
The GHC wiki page on cross-compiling seems to suggest that you should omit the --host=..., but if you compare the 7.6 and (at this point, pre-release) 7.7 GHC build system sources, you'll see that this is true (if at all) only post-7.6.
Continue with:
<LI>
The build will eventually fail with this error message:
".../buildroot-x86_64/host/usr/bin/x86_64-buildroot-linux-uclibc-gcc" -fno-stack-protector libraries/integer-gmp/cbits/mkGmpDerivedConstants.c -o libraries/integer-gmp/cbits/mkGmpDerivedConstants
libraries/integer-gmp/cbits/mkGmpDerivedConstants > libraries/integer-gmp/cbits/GmpDerivedConstants.h
/bin/sh: libraries/integer-gmp/cbits/mkGmpDerivedConstants: No such file or directory
make[1]: *** [libraries/integer-gmp/cbits/GmpDerivedConstants.h] Error 127
make[1]: *** Deleting file `libraries/integer-gmp/cbits/GmpDerivedConstants.h'
make: *** [all] Error 2
Type this to continue:
<LI>
A bit later, the build will again fail with this error message:
 HC [stage 1] libraries/base/dist-install/build/Foreign/C/Types.o
libraries/base/Foreign/C/Types.hs:162:25:
 Not in scope: type constructor or class `HTYPE_FLOAT'
libraries/base/Foreign/C/Types.hs:162:215:
 Not in scope: type constructor or class `HTYPE_FLOAT'
libraries/base/Foreign/C/Types.hs:162:290:
 Not in scope: type constructor or class `HTYPE_FLOAT'
libraries/base/Foreign/C/Types.hs:162:398:
 Not in scope: type constructor or class `HTYPE_FLOAT'
libraries/base/Foreign/C/Types.hs:162:470:
 Not in scope: type constructor or class `HTYPE_FLOAT'
libraries/base/Foreign/C/Types.hs:162:548:
 Not in scope: type constructor or class `HTYPE_FLOAT'
libraries/base/Foreign/C/Types.hs:164:27:
 Not in scope: type constructor or class `HTYPE_DOUBLE'
libraries/base/Foreign/C/Types.hs:164:219:
 Not in scope: type constructor or class `HTYPE_DOUBLE'
libraries/base/Foreign/C/Types.hs:164:295:
 Not in scope: type constructor or class `HTYPE_DOUBLE'
libraries/base/Foreign/C/Types.hs:164:405:
 Not in scope: type constructor or class `HTYPE_DOUBLE'
libraries/base/Foreign/C/Types.hs:164:478:
 Not in scope: type constructor or class `HTYPE_DOUBLE'
libraries/base/Foreign/C/Types.hs:164:557:
 Not in scope: type constructor or class `HTYPE_DOUBLE'
make[1]: *** [libraries/base/dist-install/build/Foreign/C/Types.o] Error 1
make: *** [all] Error 2
Type this to continue:
The file is only generated during the build, so you can't make this change ahead
of time; you have to wait for the build to fail, make the change, and then reissue make.
<LI>
Finally, the build will fail a third time with this error:
 HC [stage 2] utils/ghctags/dist-install/build/Main.o
inplace/bin/ghc-stage2: line 7: .../ghc-7.6.3/inplace/lib/ghc-stage2: No such file or directory
make[1]: *** [utils/ghctags/dist-install/build/Main.o] Error 127
make: *** [all] Error 2
Type this to continue:
<LI>
After this, the build should complete. We still have to do a bit of work to get it to install properly, though. Do this:
Once the installation finishes, clean up with:
<LI>
Now switch back to your outside Alpine system and do this:
Now everything in your Alpine system is cleaned up, and you've got a working GHC installation in , which the Alpine APKBUILD for ghc will recognize and use. You can delete the folder inside your Arch chroot now, and close that session.
</OL>
(I will prepare an Alpine APKBUILD for ghc, and arrange with the dev team how to make the initial binaries available, soon.)
Category:Development