FFI testers wanted

Alastair Reid reid@reid-consulting-uk.ltd.uk
06 Jul 2002 18:08:35 +0100


Over the last month or so I've been rewriting Hugs' support for the
Foreign Function Interface Extension to bring it into line with
the current specification (release candidate 4):

  http://www.cse.unsw.edu.au/~chak/haskell/ffi/

The bulk of that code I could write and test myself (with some help
from Sigbjorn Finne and Johan Nordlander) but to port it to other
platforms and test it on other platforms I need some help.


I have put a snapshot of the CVS repository at 

  http://www.reid-consulting-uk.ltd.uk/downloads/hugs98-ffi-06072002-src.tar.gz

I'm looking for volunteers on Unix-like platforms to download this
file (832 kB) and try to configure, build and test Hugs according to
the attached script.

I'm hoping to get many reports of success and failure (with
information about the platform and C compiler used).  This should take
about 5-10 minutes for people with a fast internet connection.

I'm also hoping that a few Brave Souls will mail me minor fixes for
problems turned up in the process and that a few Heroes will find the
time and cunningness to port the ffi to whole new architectures
(i.e., not x86 or PowerPC).

Please mail reports to hugs-bugs as a convenient way of keeping others
informed about your progress.


-- 
Alastair Reid                 alastair@reid-consulting-uk.ltd.uk  
Reid Consulting (UK) Limited  http://www.reid-consulting-uk.ltd.uk/alastair/


ps This snapshot is for testing the ffi only.  Other parts of Hugs
are in a state of flux and probably work but may not.  Unless you
routinely track Hugs' CVS commits, I'd recommend deleting this
snapshot once you've tested the ffi.


Here's how to test this version of Hugs on Unix-like platforms.  

The instructions are in 4 stages and take the form of a series of Unix
shell commands so the simplest thing to do is to cut and paste the
commands for each stage into a shell window and check things work ok.


# first download hugs98-ffi-06072002-src.tar.gz to /tmp

cd /tmp
tar zxvf hugs98-ffi-06072002-src.tar.gz

echo << EOF
*******************************************************************
Stage 1: Checking platform and compiler - for use in any reports of
success/ failure.
*******************************************************************
EOF
uname -a
cc -v
echo << EOF
On my machine this generates output like this:
  Linux bbb 2.4.19-pre10 #4 Mon Jun 10 22:20:35 BST 2002 i686 unknown
  Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.4/specs
  gcc version 2.95.4 20011002 (Debian prerelease)
EOF

echo << EOF
*******************************************************************
Stage 2: Configuring Hugs
*******************************************************************
EOF
cd hugs98/src/unix
./configure --prefix=/tmp/test
echo << EOF
The last 20 lines or so of output should contain something like this.

...
checking if '/LD' builds loadable libraries...
checking if '-shared' builds loadable libraries... -shared
checking if '-bundle' builds loadable libraries... (cached) -shared
checking if '-bundle -lc' builds loadable libraries... (cached) -shared
checking if '-shared -nostdlib' builds loadable libraries... (cached) -shared
checking if '-r' builds loadable libraries... (cached) -shared
checking if '-rdynamic' builds loadable libraries... (cached) -shared
checking if '-G' builds loadable libraries... (cached) -shared
checking if '-Aa +z' builds loadable libraries... (cached) -shared
...

This shows that configure successfully found a way to build
dynamically loadable files using the -shared flag.  We can check what
effect this had on configuration by examining hugs98/src/config.h:
EOF
grep DLL ../config.h
grep UNDERSCORE ../config.h
echo << EOF
On my machine this produces: 
  #define MKDLL_CMD "gcc -shared"
  /* #undef LEADING_UNDERSCORE */
EOF

echo << EOF
*******************************************************************
Stage 3: Building Hugs
*******************************************************************
EOF
cd ..
make install_ffi

echo << EOF
*******************************************************************
Stage 4: Testing Hugs
*******************************************************************
EOF
cd ../tests
sh testScript ffi
echo << EOF
This should generate output like this:
----------------------------------------------------------------
-- Testing foreign function interface.
----------------------------------------------------------------
-- !!! Testing marshalling of all the basic types
-- !!! Testing all the different forms of foreign import
-- !!! Testing static, dynamic and wrapped import of trig function
-- !!! Testing static, dynamic and wrapped import of trig function
-- !!! Testing marshalling of strings
-- !!! Testing marshalling of strings
-- !!! Testing system calls
-- !!! Testing system calls
----------------------------------------------------------------
EOF


The most likely problems are during configuration since this code has
only been very lightly tested.  If it fails at this point, those with
a little time on their hands and some mild hacking skills could try
one of the following:

1) If you have GNU autoconf on your machine, and you know how to
   build shared libraries on your machine, try adding an appropriate
   test to hugs98/src/configure.in, rerun autoconf and rerun
   from 'configure' onwards.

   The part of configure.in to change is around like 599 and reads:

     dnl Try the MS Visual C flags
     HUGS_TRY_DYNLINK("/LD")                
     
     dnl Try the gcc flags
     HUGS_TRY_DYNLINK("-shared")            
     
     dnl Try the MacOS X flags
     HUGS_TRY_DYNLINK("-bundle")        
     
     dnl Try the MacOS X flags
     HUGS_TRY_DYNLINK("-bundle -lc")        
     
     dnl Try the gcc flags
     HUGS_TRY_DYNLINK("-shared -nostdlib")  
     
     dnl Some other gcc flags
     HUGS_TRY_DYNLINK("-r")                 
     
     dnl Some other gcc flags
     HUGS_TRY_DYNLINK("-rdynamic")          
     
     dnl Try the SunOS flags
     HUGS_TRY_DYNLINK("-G")                 
     
     dnl Try the HPUX flags
     HUGS_TRY_DYNLINK("-Aa +z")             

   Each of the HUGS_TRY_DYNLINK lines tests whether passing those flags to
   the C compiler will successfully compile and link a file built with the
   dynamic loading/linking mechanism on that platform.

2) If you know how to build shared libraries on your machine, try
   modifying the settings of DLL_FLAGS and LEADING_UNDERSCORE in
   hugs98/src/config.h and rerun from 'make install_ffi' onwards.


The other likely source of problems is in the implementation of
foreign import wrappers which are currently only implemented for the
x86 and PowerPC architectures.  This may fail in three ways:

1) You have an x86 or PowerPC but Hugs fails to recognize this.

   Those with some mild porting skills could fix this by improving
   the current #ifdef tests in mkThunk (hugs98/src/builtin.c line 2266)
   which are:

    #if defined(__i386__)
    ...
    #elif defined(__ppc__) && defined(__GNUC__)
    ...
    #endif

2) You have some other architecture.

   The following is not for the timid.

   Those with assembly language and machine code skills could read

   - the implementation of mkThunk (hugs98/src/builtin.c lines
     2206-2334)

   - the bottom half of hugs98/doc/ffi-notes.txt

   - the code used by GHC (fptools/ghc/rts/Adjustor.c)

        http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/rts/Adjustor.c?rev=1.19&content-type=text/x-cvsweb-markup

   and extend the implementation of mkThunk in Hugs appropriately.

   Although the amount of code required is quite small, the amount of
   trickery required is quite high so it would be best to coordinate
   any effort.


   If your platform is not a 32-bit platform, there will probably be
   problems with the marshalling libraries (Storable in particular)
   as well.  The configuration script contains some tests to determine
   the size and alignment of various types but this information is not
   currently used in the compiler or in the libraries.