porting to uClibc-based 686 Linux

Dubiousjim lists+haskell-glasgow at jimpryor.net
Tue Apr 2 15:11:49 CEST 2013


I've shifted my attempts to cross-compile to the 7.6.2 sources. Here
I'm having better success with the instructions at
http://hackage.haskell.org/trac/ghc/wiki/Building/CrossCompiling, though
it still takes some fiddling and in the end I am still getting stuck.

To refresh, I'm trying to bootstrap from a working ghc (now I have 7.6.2
installed on the host) on a typical Linux 686 host system, glibc-based,
to get a ghc that can be installed on a similar target system, differing
in that it uses uclibc instead of glibc.

I have a working cross-compiler, and seem to have everything else I need
to have installed on my host. I did have to make sure that my
cross-compiler tree had gmp and libiconv and ncurses installed in it.

I also had to edit the file /usr/lib/ghc-7.6.2/include/ghcautoconf.h
on my host system. This was #defining _FILE_OFFSET_BITS to 64, but the
uclibc on my target system wasn't compiled with large file support,
hence I thought the uclibc in my cross-compiler toolchain shouldn't be
either. But then that #define in the host's ghcautoconf.h was
conflicting. So I just commented it out for the time being.


Here's what I've done, on the host, from a clean detar of the ghc 7.6.2
sources.

I made this change at three locations in ghc's topmost
configure script, to get it to recognize my cross-compiler tag 
"i686-buildroot-linux-uclibc":

       case "$build_vendor" in
    -  pc|gentoo) # like i686-pc-linux-gnu and i686-gentoo-freebsd8
    +  pc|gentoo|buildroot) # like i686-pc-linux-gnu and
    i686-gentoo-freebsd8
         BuildVendor="unknown"
         ;;

(The other two locations are for $host_vendor and $target_vendor. Maybe
it's only necessary to do this for $target_vendor.)

Next, here is my mk/build.mk file:

    # Fast build with optimised libraries, no profiling (RECOMMENDED):
    BuildFlavour = quick
    ...
    # An unregisterised, optimised build of ghc, for porting:
    # BuildFlavour = unreg
    ...

The rest as in mk/build.mk.sample

Next, I had to make this patch to libraries/haskeline/cbits/h_wcwidth.c,
else I would get errors about types like size_t not being recognized. (I
forget the exact error.)

    @@ -59,6 +59,7 @@
      * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
      */
     
    +#include <stddef.h>
     #include <wchar.h>
     
     struct interval {


Next, the configure scripts for
libraries/{base,directory,integer-gmp,old-time,process,terminfo,time,unix}
would stall, complaining that the C compiler didn't generate
binaries they could execute. I fixed that by patching those configure
scripts like this---I don't know if this is correct, it may be the
source of my later troubles. On the other hand, I don't know how else
to get past the configure scripts failing. Adding switches like --host
and --host="" to my original configure, as an error message suggests,
seems to have no effect.

    @@ -2833,7 +2833,7 @@
       test $ac_status = 0; }; }; then
         cross_compiling=no
       else
    -    if test "$cross_compiling" = maybe; then
    +    if true || test "$cross_compiling" = maybe; then
     	cross_compiling=yes
         else
     	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in
     	\`$ac_pwd':" >&5


Here are the steps I'm using to configure and build:

    export PATH=${PATH}:/path/to/my/cross-compiler
    make distclean
    ./configure --target=i686-buildroot-linux-uclibc --disable-largefile
    make -k

There are two further tweaks I have to make, during the build. I have to
edit libraries/base/include/HsBaseConfig.h, and add the following lines:

    #define HTYPE_DOUBLE Double
    #define HTYPE_FLOAT Float

That's based on what I see in my host system. Without these lines, the
build won't complete.

Also, at a certain point the build tries to execute:

    libraries/integer-gmp/cbits/mkGmpDerivedConstants > \
    libraries/integer-gmp/cbits/GmpDerivedConstants.h

where the first is a binary it generated using the cross-compiler. This
won't run on the host system, so I have to manually run it on the target
system. (Easy to do because the host is running in a chroot on the
target.)

Ok, with all that, I do get a build that completes successfully.
However, there is no stage2 ghc. And if I do:

    make install DESTDIR=/somewhere

the ghc that gets installed is linked against the glibc on my host
system, rather that the uclibc I'm targetting.

Sigh.

Is there just some final step that I'm missing? Is my build.mk file
wrong? Are my patches to the library configure files messing things up?
If so, how else should I work around their failing when in vanilla
condition?

Sigh.



More information about the Glasgow-haskell-users mailing list