[nhc-users] cross-compiler nhc98: it (almost) works

sylvain nahas sylvain.nahas at googlemail.com
Wed Apr 2 18:54:48 EDT 2008


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 at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/nhc-users/attachments/20080403/0a644670/attachment-0001.htm


More information about the Nhc-users mailing list