porting to uClibc-based 686 Linux
Dubiousjim
lists+haskell-glasgow at jimpryor.net
Mon Apr 1 19:11:20 CEST 2013
My preferred system is a 686 Linux distro based on uClibc. No ghc
binaries available yet there. I'd like to remedy that.
I have ghc 7.4.2 running on an 686 Linux distro based on glibc (and also
on two different versions of Mac OS X, but they seem more distant and so
less likely to be helpful). In fact, ghc 7.6.2 binaries are also
available for that system, but I'd like to keep in synch with the last
released Haskell platform (which is what I've got on the Macs). That's
supposed to be updated in May, so if it's only possible to port ghg >=
7.6.x to my target system, that won't be so terrible. I'm hoping though
to be able to port a ghc < 7.8.x, because I don't expect to see that
version in any soon-to-be-released Haskell platform. (I mention this
because
http://hackage.haskell.org/trac/ghc/wiki/CrossCompilation says:
"Support for cross-compilation works reasonably well in 7.8.1. Previous
versions had various issues which are usually work-aroundable.")
Ok, so I'm getting stuck trying to build a version of ghc that will run
on the target, uClibc-based system. I have a working cross-compiler. (In
fact, I have two, one built using crosstools-NG, the other built using
buildroot.) My target identifier is "i686-buildroot-linux-uclibc".
I've tried the method for cross-compiling ghc posted here:
http://hackage.haskell.org/trac/ghc/wiki/Building/CrossCompiling
I had to tweak the configure script to not complain about the
"buildroot" vendor id. Here is the content of my mk/build.mk file:
BuildFlavour = unreg
...
ifeq "$(BuildFlavour)" "unreg"
GhcUnregisterised = YES
GhcWithNativeCodeGen = NO
# SRC_HC_OPTS = -O -H64m
# GhcStage1HcOpts = -O
# GhcStage2HcOpts = -O2
# GhcLibHcOpts = -O2
SRC_HC_OPTS = -O -H64m -fasm
GhcStage1HcOpts = -O -fasm
GhcStage2HcOpts = -O2 -fasm
GhcHcOpts = -Rghc-timing
GhcLibHcOpts = -O2 -fasm
SplitObjs = NO
HADDOCK_DOCS = NO
BUILD_DOCBOOK_HTML = NO
BUILD_DOCBOOK_PS = NO
BUILD_DOCBOOK_PDF = NO
endif
Using the following commands:
$ export PATH=${PATH}:/path/to/my/cross/compiler
$ make clean
$ ./configure --target=i686-buildroot-linux-uclibc
$ make
will successfully build ghc. However, the inplace/lib/ghc-stage2 it
generates won't run on the target system. (Neither will the
utils/ghc-pkg/dist/build/ghc-pkg, this will be relevant later.) Checking
these with
ldd says "not a dynamic executable." Checking them with objdump -p gives
NEEDED lines like this:
...
NEEDED libc.so.6
...
which indicates that they're linking against the glibc on my host,
rather
than the uClibc of my cross-compiler toolchain.
Perhaps I'm doing something wrong, or perhaps the build system
distributed with ghc 7.4.2 just doesn't yet properly support
cross-compiling. It's strange though that the build completes without
any errors. grepping the Makefiles doesn't show any evidence that it's
using my cross-compiler. Do I need to make links using the target
identifier "i386-unknown-linux-..." to my actual tools
"i686-buildroot-linux-uclibc-..."?
The web instructions say:
If you need to specify the tools explicitly, then you can say
$ ./configure --target=<target> --with-gcc=<gcc> \
--with-ld=<ld> --with-nm=<nm> --with-objdump=<objdump>
However, if I specify my cross-compiler tools in this way, the build
breaks already at the configure step, because the binaries generated
won't run on the host.
Alright, that isn't working. I also tried instead to use the older
instructions at
http://hackage.haskell.org/trac/ghc/wiki/Building/Porting
This requires some tweaking, then at a certain point in this process I
also get stuck.
What I had to tweak:
* The instructions say to copy an executable pwd to
utils/ghc-pwd/ghc-pwd on the target, then run:
$ perl boot
$ ./configure --enable-hc-boot --build=<plat> \
--host=<plat> --target=<plat>
However, the configure process still tries to build ghc-pwd
and of course fails, since there's no ghc on the target to build
it with. I comment out the line in the configure script which
tries to build ghc-pwd and make sure that GHC_PWD points to
my replacement pwd (which can't be at the location
the configure script tries to make GHC_PWD point to, since that
keeps getting clobbered).
* Ok, so we get past the ghc-pwd issue and the configure continues.
But then I get stuck with ghc-pkg:
$ ./configure --enable-hc-boot --build=i386-unknown-linux \
--host=i386-unknown-linux --target=i386-unknown-linux
...
checking for ghc... no
checking build system type... i386-unknown-linux-gnu
checking host system type... i386-unknown-linux-gnu
checking target system type... i386-unknown-linux-gnu
GHC build : i386-unknown-linux
GHC host : i386-unknown-linux
GHC target : i386-unknown-linux
configure: Building in-tree ghc-pwd
checking for path to top of build tree... /home/jim/ghc-7.4.2
checking for gcc... /usr/bin/gcc
...
checking for i386-unknown-linux-gcc... /usr/bin/gcc
checking whether the C compiler works... yes
...
checking whether we are cross compiling... no
...
checking version of gcc... 4.7.2
...
checking for ghc-pkg matching ... configure: error: Cannot find
matching ghc-pkg
Well of course there's no ghc-pkg, because I'm trying to port ghc to
this system!
I checked the ghc-pkg I (tried to) build with the cross-compiler
toolchain, earlier, but this (contrary to my intention) links against
the libc on its host, and so won't run on the target either.
* Ok, so let's hack the configure script to skip building ghc-pkg too.
Then configure completes successfully on the target. The next step
is to:
$ cd libraries/integer-gmp
$ ./configure
$ cd ..
$ make bootstrapping-files
However, this fails at the following point:
"" -fno-stack-protector -DNO_REGS -DUSE_MINIINTERPRETER
-D__GLASGOW_HASKELL__=704 -Iincludes -DNO_REGS
-DUSE_MINIINTERPRETER
-Iincludes -Iincludes/dist-derivedconstants/header
-Iincludes/dist-ghcconstants/header -Irts -DNOSMP -c
includes/mkDerivedConstants.c -o
includes/dist-derivedconstants/build/mkDerivedConstants.o
/bin/sh: : Permission denied
make[1]: ***
[includes/dist-derivedconstants/build/mkDerivedConstants.o]
Error 127
make: *** [bootstrapping-files] Error 2
I don't know if it's a variable that's supposed to point to $CC that's
coming up "", or one that's supposed to point to ghc. I'm guessing the
latter. I can't proceed with the porting instructions at this point
because includes/dist-derivedconstants is empty (just an empty build
dir), and includes/dist-ghcconstants doesn't exist yet.
Any advice on how to proceed further using either of the strategies I
described (cross-compiling, or bootstrapping using using unregisterised
intermediate C files), would be welcomed.
--
Dubiousjim
dubiousjim at gmail.com
--
dubiousjim at gmail.com
More information about the Glasgow-haskell-users
mailing list