On Jul 1, 2008, at 1:48 PM, Joel J. Adamson wrote:
Bradley Lucier lucier@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