[MLton] MLton and shared libraries

Jens Axel SÝgaard jensaxel@soegaard.net
Wed, 13 Apr 2005 10:27:21 +0200

Hello all,

I have experimented a little with exporting functions from MLton
using the C FFI. The goal is to call MLton compiled functions
from within PLT Scheme.

The new FFI in PLT Scheme works by using dlopen to pull the needed
functions from an .so-file. The idea is that you don't need to
write glue functions in C.

Since there is no -generate-shared-library in MLton I
chose the C backend and fiddled a little with gcc and ld
options. I have succeed in generating a so-file that
dlopen can open, but I run into core dump later on.
Right now I am trying to figure out what causes this.
Being new to shared objects, I am not completely sure
that the options used are correct.

What switches is normally used to generate shared libraries
with MLton?

Here is what I tried on FreeBSD (I'll try Linux later this week):

I give gcc the -shared option and ld --export-dynamic and -shared.

bash-2.05b# mlton -default-ann 'allowExport true' -codegen c -cc-opt -shared
-verbose 1 -keep g -link-opt --export-dynamic -link-opt -shared test.sml

MLton 20041109 (built Tue Nov 09 19:11:54 2004 on freebsd521.sweeks.com)
MLton starting
    Compile SML starting
       pre codegen starting
       pre codegen finished in 2.75 + 2.25 (45% GC)
       C code gen starting
       C code gen finished in 0.03 + 0.00 (0% GC)
    Compile SML finished in 2.78 + 2.25 (45% GC)
    Compile C and Assemble starting
       gcc -c -I/lib/mlton/include -O1 -fno-strict-aliasing \
           -fomit-frame-pointer -w -fno-strength-reduce -fschedule-insns \
           -fschedule-insns2 -malign-functions=5 -malign-jumps=2 \
           -malign-loops=2 -mcpu=pentiumpro -shared -o /tmp/filewvNhdZ.o \
       gcc -c -I/lib/mlton/include -O1 -fno-strict-aliasing \
           -fomit-frame-pointer -w -fno-strength-reduce -fschedule-insns \
           -fschedule-insns2 -malign-functions=5 -malign-jumps=2 \
           -malign-loops=2 -mcpu=pentiumpro -shared -o /tmp/file82E8cw.o \
    Compile C and Assemble finished in 1.98 + 0.00 (0% GC)
    Link starting
       gcc -o test /tmp/filewvNhdZ.o /tmp/file82E8cw.o -L/lib/mlton/self \
           -lmlton -L/usr/local/lib/ -lgmp -lgdtoa -lm --export-dynamic -shared
    Link finished in 0.03 + 0.00 (0% GC)
MLton finished in 4.83 + 2.54 (34% GC)

Then I copy test to test.so.

The file test.sml contains a single function f:

   bash-2.05b# cat test.sml
   val e = _export "f": int -> int;
   val _ = e (fn (i) => 42);

In the file test.h one can read the C types of the exported function:

   typedef unsigned long Word32;
   Word32 f (Word32 x0);

For testing I do the following:

   bash-2.05b# mzscheme
   Welcome to MzScheme version 299.102, Copyright (c) 2004-2005 PLT Scheme, Inc.
   > (require (lib "foreign.ss"))
   > (unsafe!)
   > (define lib (ffi-lib "/usr/soegaard/ml/test"))
   > (define f (get-ffi-obj "f" lib (_fun _ulong -> _ulong)))
   > (f 1)
   Segmentation fault (core dumped)

Is there other ("more traditional") ways of testing a shared library?

/Jens Axel