Using Gambit with External Libraries

From Gambit wiki

Revision as of 14:08, 2 July 2008 by Bjlucier (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Using gsc to compile and link a dynamically loadable object file that uses external libraries

Here is an example of building a dynamically loadable Gambit object file that uses FFTW. This example is on Red Hat Enterprise Linux 4.2 on x86-64.

The program uses the FFTW version 2 API, so we downloaded fftw-2.1.5.tar.gz, untarred it and configured it with

./configure --enable-shared --prefix=/export/users/lucier/local/fftw-2.1.5

You need the --enable-shared option because shared Gambit modules must be linked to shared external libraries. I set the --prefix to install the final FFTW libraries and header files in my home directory.

The file fftbasics.scm provides the basic interface between the Scheme code and FFTW; it is as follows:

(c-declare
"
#include \"fftw.h\"

fftwnd_plan p;

")

(define fftw2d_create_plan_backward
  (c-lambda ()
            void
            "p = fftw2d_create_plan(64,
                                    64,
                                    FFTW_BACKWARD,
                                    FFTW_ESTIMATE | FFTW_IN_PLACE);
            "))

(define fftw2d_create_plan_forward
  (c-lambda ()
            void
            "p = fftw2d_create_plan(64,
                                    64,
                                    FFTW_FORWARD,
                                    FFTW_ESTIMATE | FFTW_IN_PLACE);
            "))

;;; Both forward and backward ffts, depends on which way the plan was created.

(define fftwc
  (c-lambda (scheme-object)
            void
            "
int j; double *fp = (double *)((___WORD)___BODY_AS(___arg1,___tSUBTYPED));
  fftwnd_one(p,
             (fftw_complex *)(fp),
             NULL);
  for (j = 0; j < 64 * 64 * 2; j++)
    fp[j] *= .015625;
"))

We need to pass special options to gsc to compile this file, namely

gsc -cc-options "-I/export/users/lucier/local/fftw-2.1.5/include" -ld-options "-L/export/users/lucier/local/fftw-2.1.5/lib/ -Wl,-rpath,/export/users/lucier/local/fftw-2.1.5/lib/ -lfftw" fftbasic.scm

The first option (-I/export/users/lucier/local/fftw-2.1.5/include) tells gcc where to find the header file fftw.h at compile time. The second option (-L/export/users/lucier/local/fftw-2.1.5/lib/) tells the linker where to find the FFTW library (-lfftw) at link time (i.e., when building the file fftwbasic.o1 from fftwbasic.o), and the third option (-Wl,-rpath,/export/users/lucier/local/fftw-2.1.5/lib/) tells the dynamic loader ldd where to find the FFTW library when fftwbasic.o1 is loaded into gsc.

Then we can do

euler-316% gsc
Gambit v4.2.8

> (load "fftbasic")
"/export/users/lucier/programs/gambc-v4_2_8/test-load-options/fftbasic.o1"
> fftwc
#<procedure #2 fftwc>
>
*** EOF again to exit

We can check that fftbasic.o1 links to the right libraries:

euler-317% ldd fftbasic.o1
        libfftw.so.2 => /export/users/lucier/local/fftw-2.1.5/lib/libfftw.so.2 (0x0000002a9565a000)
        libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a957aa000)
        libm.so.6 => /lib64/tls/libm.so.6 (0x0000002a959df000)
        /lib64/ld-linux-x86-64.so.2 (0x000000552aaaa000)
Personal tools
documentation