[gambit-list] Example of compiling scheme file into dynamically loadable module that itself loads external dynamic library (was Re: Illegal character)
Bradley Lucier
lucier at math.purdue.edu
Tue Jul 1 16:15:16 EDT 2008
On Jul 1, 2008, at 1:48 PM, Joel J. Adamson wrote:
>
> Bradley Lucier <lucier at math.purdue.edu> writes:
>
>> On Jun 30, 2008, at 4:08 PM, Joel J. Adamson wrote:
>>
>>> Did you notice anything else amiss with my compilation commands?
>>
>> If you just want to make a dynamically loadable library, it seems
>> somewhat perverse to ignore the built-in support for building
>> dynamically loadable libraries in gsc and not to define a file
>> "all.scm" that contains simply
>>
>> (include "file1.scm")
>> (include "file2.scm")
>> ...
>>
>> and then
>>
>> % gsc
>>> (compile-file "all")
>>> (load "all")
>>
>> unless you have a special reason (i.e., you need to link an external
>> library).
>
> I'm using the GNU Scientific Library: there's actually quite a bit of
> foreign code in these modules.
>
> Your approach makes a lot of sense, but the files I'm compiling are
> "headers" that include the conceptually linked parts of the
> program: all
> the gsl-interfacing code is (include)d in "gsl_genx.scm," all the
> srfis
> are in "srfi.scm" and so on.
From the gambit documentation:
> The `-ld-options-prelude' and `-ld-options' options are only
> meaningful when a dynamically loadable object file is being
> generated (neither the `-c' or `-link' options are used). The `-ld-
> options-prelude' and `-ld-options' options add the specified
> options to the command that invokes the C linker (the options in ld-
> options-prelude are passed to the C linker before the input file
> and the options in ld-options are passed after). The main use of
> this option is to specify additional object files or libraries that
> need to be linked, or any C linker option that is different from
> the default (such as the library search path and flags to select
> between static and dynamic linking). For example:
>
>
> $ gsc -ld-options "-L/usr/X11R6/lib -lX11 -dynamic" bench.scm
Well, in fact, these options do nothing of the sort, but they give
the right idea. (Marc, the gsc-cc-o.bat command on my linux box is
> gcc -Wall -W -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -
> fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer
> -fPIC -fno-common -mieee-fp -rdynamic -shared -I"$
> {GSC_CC_O_GAMBCDIR}include" -D___DYNAMIC -D___SINGLE_HOST -o "$
> {GSC_CC_O_OBJ_FILENAME}" ${GSC_CC_O_CC_OPTIONS} $
> {GSC_CC_O_LD_OPTIONS_PRELUDE} "${GSC_CC_O_C_FILENAME_BASE}" $
> {GSC_CC_O_LD_OPTIONS}
The GSC_CC_O_LD_OPTIONS_PRELUDE and GSC_CC_O_LD_OPTIONS are just
passed to gcc, if gcc doesn't pass them along to ld, then they're not
passed along to ld. In particular, you just concatenate $
{GSC_CC_O_CC_OPTIONS} and ${GSC_CC_O_LD_OPTIONS_PRELUDE}. The
documentation is way misleading.)
Here's an example of how to build a dynamically-loadable scheme
module that itself loads a dynamic library.
For this example I built fftw-2.1.5 (because I had a program around
that used the version 2 API, not the version 3 API), after
configuring with
> 171 15:12 ./configure --enable-shared --prefix=/export/users/
> lucier//local/fftw-2.1.5
You need to have a shared library, hence the --enable-shared. I also
just put it in my home directory, hence the --prefix=/export/users/
lucier//local/fftw-2.1.5
Here's fftbasic.scm:
> ;;; start fftbasic.scm
>
> (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;
> "))
>
> ;;; end fftbasic.scm
and here's the command to compile fftbasic.scm to fftbasic.o1; when
fftbasic.o1 is loaded into gsc, it will dynamically load libfftw.so.2:
> euler-315% 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
> 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
> 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)
The -Lpath command tells where ld is to find the libfftw at link
time, the -rpath command (which uses "-Wl," to *really* pass it to
the linker) tells the loader where to find libfftw at load time, the -
I command says where to find fftw.h at compile time.
Brad
More information about the Gambit-list
mailing list