cross-compiler nhc98: it (almost) works

Hi, ( I am not sure if my first mail was correctly sent. I send it again with the patch in the body ) I intend to use Haskell on embedded systems (ARM and MIPS), where porting and even installing a compiler is not an option. So I definitively need a cross-compiler, and to my dismay I have find out that there is by now no Haskell compiler distribution with this capacity. I have tried to modify the source of nhc98 to make it supports being configured as a cross-compiler. The result is in the attached patch. In the current state it makes an error during the compilation ( cabal-parse is probably not compiled with the correct compiler ) but the result of "make install" is able to cross-compile correctly the program: main = print("hello world") . So I send the patch as it in the hope that others will have a look at it and even finish it (hint, hint). I have somewhat the feeling we are very close to get a fully working cross-compiler SHORTCOMINGS: This patch is ugly. Please consider it as something experimental rather as a true proposal. * The name of the cross-compiler is hard coded in nhc98.inst, so if you want to test it, you must adapt that. * it uses the presence of a environment variable (TARGET) to know if a cross-compiler is wished. It should be a "--target" flag to ./configure, but I was not sure how to implement it at best ( by the way, would it not be better to use the GNU autotools for that ? ) * As I said, the compilation doesn't even complete * I had to remove the -m32 flag because it was not supported by the version of the ARM GCC cross-compiler I have installed. HOW TO TEST $ patch -p 1 < ../nhc98-1.20-with-cross -compilation.patch1 $ CC=/usr/local/uclibc-0.9.28-3/arm/bin/arm-linux-gcc TARGET=arm-linux ./configure --prefix=/home/sylvain/bin/nhc98-1.20-arm-linux $ TARGET=arm-linux make basic $ TARGET=arm-linux make install As a result: sylvain@portable:/tmp$ TARGET=arm-linux /home/sylvain/bin/nhc98-1.20-arm-linux/bin/nhc98 -v /tmp/toto.hs -o /tmp/toto /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/nhc98comp +RTS -RTS -P/home/sylvain/bin/nhc98-1.20-arm-linux/include/nhc98/packages/base -I. -P/home/sylvain/bin/nhc98-1.20-arm-linux/include/nhc98 /tmp/toto.hs /tmp/toto.hs /tmp/toto.11658.hi /tmp/toto.11658.hc rm /tmp/toto.11658.hi /usr/local/uclibc-0.9.28-3/arm/bin/arm-linux-gcc -D__NHC__=120 -x c -S -DLOW_BYTE_FIRST -I/home/sylvain/bin/nhc98-1.20-arm-linux/include/nhc98/ /tmp/toto.11658.hc -o /tmp/toto.11658.s rm /tmp/toto.11658.hc /usr/local/uclibc-0.9.28-3/arm/bin/arm-linux-gcc -D__NHC__=120 -c -o /tmp/toto.o /tmp/toto.11658.s rm /tmp/toto.11658.s /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/nhc98heap | /usr/local/uclibc-0.9.28-3/arm/bin/arm-linux-gcc -D__NHC__=120 -x c -c -o /tmp/nhc11658.o - /usr/local/uclibc-0.9.28-3/arm/bin/arm-linux-gcc -D__NHC__=120 -o /tmp/toto /tmp/toto.o /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/main.o /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/mutlib.o /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/mutator.o /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/Prelude.a /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/Runtime.a /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/Prelude.a /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/Runtime.a /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/Prelude.a /home/sylvain/bin/nhc98-1.20-arm-linux/lib/nhc98/arm-linux/Runtime.a /tmp/nhc11658.o -lm rm -f /tmp/nhc11658.o /tmp/nhc11658.c on my ARM system ( running on a Qemu image downloaded from the Qemu site ): $./toto hello world nice :) I hope this patch will wake some interest in the developers of nhc98. Having the ability to work as cross-compiler would be a bonus for a compiler, and more generally for the use of the Haskell language in embedded systems. I personnaly do think this is a must have. Greetings, Sylvain PS: the patch is against the distribution nhc98-1.20. The head of the darcs repository seems unable to build for now. BEGIN OF PATCH diff -Naur nhc98-1.20-orig/configure nhc98-1.20/configure --- nhc98-1.20-orig/configure 2007-11-22 14:05:24.000000000 +0100 +++ nhc98-1.20/configure 2008-04-02 20:36:56.000000000 +0200 @@ -36,11 +36,30 @@ INSTALLDIR=/usr/local USER=${USER-`whoami 2>/dev/null`} + +if [ "$TARGET" != "" ] +then +MACHINE=`script/harch` +case $MACHINE in + powerpc-Darwin[56]) CCC=${CC-cc}; STRIP=${STRIP-strip};; + *) CCC=${CC-gcc}; STRIP=${STRIP-strip};; +esac +# in case of building a cross-compiler, CCC is the cross-compiler CC +# and HOST the local C compliler +HOSTCCC=gcc +HOSTSTRIP=strip + +else MACHINE=`script/harch` + case $MACHINE in - powerpc-Darwin[56]) CCC=${CC-cc};; - *) CCC=${CC-gcc};; + powerpc-Darwin[56]) CCC=${CC-cc}; STRIP=${STRIP-strip} ;; + *) CCC=${CC-gcc};STRIP=${STRIP-strip} ;; esac +HOSTCCC=${CCC} +HOSTSTRIP=${STRIP} +fi + PWD=`pwd` case $OS in CYGWIN*) PWD=`cygpath -w "$PWD" | tr '\\\\' '/'` @@ -334,7 +353,7 @@ } } !!! - $CCC -m32 $COPTS -o endian endian.c + $HOSTCCC -m32 $COPTS -o endian endian.c ENDIAN=`./endian` rm -f endian$EXE endian.c echo -n "$ENDIAN " @@ -416,9 +435,9 @@ cp src/prelude/DErrNo.p.c src/prelude/$MACHINE/NHC cp src/prelude/DErrNo.z.c src/prelude/$MACHINE/NHC fi - $CCC $COPTS -o config-errno script/config-errno.c && \ + $HOSTCCC $COPTS -o config-errno script/config-errno.c && \ ./config-errno >targets/$MACHINE/Errno.hs && rm -f ./config-errno$EXE - $CCC $COPTS -o errnogen script/errnogen.c && \ + $HOSTCCC $COPTS -o errnogen script/errnogen.c && \ ./errnogen >DErrNo.hs && rm -f ./errnogen$EXE if diff DErrNo.hs src/prelude/$MACHINE/NHC/DErrNo.hs >/dev/null then @@ -544,6 +563,9 @@ echo "CURSES=\"$CURSES\""; echo "EXE=$EXE"; echo "CC=$CCC"; + echo "HOSTCC=$HOSTCCC"; + echo "STRIP=$STRIP" ; + echo "HOSTSTRIP=$HOSTSTRIP" ; echo "COPTS=\"$COPTS\""; echo "GHCSYM=`cat targets/$MACHINE/ghcsym || true`"; echo "TRUE=$TRUE"; @@ -823,6 +845,9 @@ echo "BUILDDIR=$BUILDDIR" ; echo "RTSFLAG=$RTSFLAG" ; echo "CC=$CCC" ; + echo "HOSTCC=$HOSTCCC" ; + echo "STRIP=$STRIP" ; + echo "HOSTSTRIP=$HOSTSTRIP" ; echo "COPTS=\"$COPTS\""; echo "ENDIAN=$ENDIAN" ; echo "HEAP=$HEAP" ; diff -Naur nhc98-1.20-orig/Makefile.inc nhc98-1.20/Makefile.inc --- nhc98-1.20-orig/Makefile.inc 2007-11-22 14:05:04.000000000 +0100 +++ nhc98-1.20/Makefile.inc 2008-04-02 17:30:59.000000000 +0200 @@ -1,7 +1,8 @@ ### Configurable variables: OPT = -O3 -ARCH = -m32 +#ARCH = -m32 +ARCH = # CC = actually sourced from LIBDIR/MACHINE/config INSTALL = cp diff -Naur nhc98-1.20-orig/script/harch nhc98-1.20/script/harch --- nhc98-1.20-orig/script/harch 2007-11-22 11:32:51.000000000 +0100 +++ nhc98-1.20/script/harch 2008-04-02 17:31:35.000000000 +0200 @@ -8,6 +8,12 @@ OS= REL= +if [ "$TARGET" != "" ] +then + echo $TARGET + exit 0 +fi + # Unfortunately, there are a variety of incompatible # ways of detecting architecture, so try them all! diff -Naur nhc98-1.20-orig/script/nhc98.inst nhc98-1.20/script/nhc98.inst --- nhc98-1.20-orig/script/nhc98.inst 2007-11-22 12:22:16.000000000 +0100 +++ nhc98-1.20/script/nhc98.inst 2008-04-02 23:59:08.000000000 +0200 @@ -70,7 +70,13 @@ MAINROUTINE=$NHC98LIBDIR/$MACHINE/main +if [ "$TARGET" != "" ] +then +CC="/usr/local/uclibc-0.9.28-3/arm/bin/arm-linux-gcc -D__NHC__=$VERSIONNUM" +else CC=${CC-gcc}" -m32 -D__NHC__=$VERSIONNUM" +fi + CPPHS="$NHC98LIBDIR/$MACHINE/cpphs" if test $USINGRTS -eq 0 ; then CPPHS="$CPPHS -" diff -Naur nhc98-1.20-orig/src/compiler98/Makefile.hat nhc98-1.20/src/compiler98/Makefile.hat --- nhc98-1.20-orig/src/compiler98/Makefile.hat 2007-11-22 11:34:28.000000000 +0100 +++ nhc98-1.20/src/compiler98/Makefile.hat 2008-04-02 20:23:20.000000000 +0200 @@ -43,7 +43,7 @@ $(TARGET): ${OBJDIR} $(OBJDIR)/$(HC) $(SRCS) hmake -$(HC) $(HMAKEFLAGS) -d $(OBJDIR) HatTrans mv $(OBJDIR)/HatTrans$(EXE) $(TARGET) - strip $(TARGET) + $(STRIP) $(TARGET) ${OBJDIR}: mkdir -p ${OBJDIR} $(OBJDIR)/$(HC): diff -Naur nhc98-1.20-orig/src/runtime/Integer/Makefile nhc98-1.20/src/runtime/Integer/Makefile --- nhc98-1.20-orig/src/runtime/Integer/Makefile 2007-11-22 11:32:51.000000000 +0100 +++ nhc98-1.20/src/runtime/Integer/Makefile 2008-04-02 17:36:38.000000000 +0200 @@ -51,7 +51,7 @@ $(OBJDIR)/cre-mparam > tmp-$@ mv tmp-$@ $@ $(OBJDIR)/cre-mparam: cre-mparam.c gmp.h haskell2c.h - $(CC) $(CFLAGS) `if [ x$(firstword $^) = x ]; \ + $(HOSTCC) $(CFLAGS) `if [ x$(firstword $^) = x ]; \ then echo cre-mparam.c; \ else echo $(firstword $^); fi` -o $@ diff -Naur nhc98-1.20-orig/src/runtime/Makefile nhc98-1.20/src/runtime/Makefile --- nhc98-1.20-orig/src/runtime/Makefile 2007-11-22 11:32:51.000000000 +0100 +++ nhc98-1.20/src/runtime/Makefile 2008-04-02 17:38:23.000000000 +0200 @@ -66,6 +66,6 @@ cd Mk; $(MAKE) objdir $(DST)/nhc98heap$(EXE): nhc98heap.c - $(CC) $(ARCH) $(shell echo ${COPTS}) -o $@ $< + $(HOSTCC) $(ARCH) $(shell echo ${COPTS}) -o $@ $< $(STRIP) $@ END OF PATCH
participants (1)
-
sylvain nahas