Hello Gambit-List,
I have compiled a dynamically-loadable library as per the Gambit Manual, and when I try to load it:
,----Error! | > (load "genxic.o") | *** ERROR IN "genxic.o"@1.5 -- Illegal character: #\x01 | 1> `----
I have tried all sorts of things, and it doesn't seem to depend on the options I use or which files I"m compiling.
Where should I turn next? Any suggestions?
Joel
Afficher les réponses par date
Joel,
On Fri, Jun 27, 2008 at 1:23 PM, Joel J. Adamson adamsonj@email.unc.edu wrote:
I have compiled a dynamically-loadable library as per the Gambit Manual, and when I try to load it:
Try (load "genxic.o1") or even better, (load "genxic").
--Jeff
"Jeff Read" bitwize@gmail.com writes:
Joel,
On Fri, Jun 27, 2008 at 1:23 PM, Joel J. Adamson adamsonj@email.unc.edu wrote:
I have compiled a dynamically-loadable library as per the Gambit Manual, and when I try to load it:
Thanks for checking in.
Try (load "genxic.o1") or even better, (load "genxic").
Why would that work any better when the file is called "genxic.o," not "genxic.o1?" Does the loader know something I don't know? ;)
,---- | Gambit v4.2.8 | | > (current-directory "/home/joel/lisp/scm/genxic/scm") | > (load "genxic") | *** ERROR IN (stdin)@2.1 -- No such file or directory | (load "genxic") | 1> ,t | > (load "genxic.o") | *** ERROR IN "genxic.o"@1.5 -- Illegal character: #\x01 | 1> ,t | > (load "genxic.o1") | *** ERROR IN (stdin)@6.1 -- /home/joel/lisp/scm/genxic/scm/genxic.o1: | cannot open shared object file: No such file or directory (load | "genxic.o1") | 1> `----
It definitely tries to load; it appears there's something wrong with the file.
Joel
Joel,
On Sat, Jun 28, 2008 at 8:00 PM, Joel J. Adamson adamsonj@email.unc.edu wrote:
It definitely tries to load; it appears there's something wrong with the file.
I'll say. It doesn't look like you're even producing a dynamic shared library.
What procedure did you use to compile this?
--Jeff
"Jeff Read" bitwize@gmail.com writes:
Joel,
On Sat, Jun 28, 2008 at 8:00 PM, Joel J. Adamson adamsonj@email.unc.edu wrote:
It definitely tries to load; it appears there's something wrong with the file.
I'll say. It doesn't look like you're even producing a dynamic shared library.
What procedure did you use to compile this?
It's as close to what's in the info file as I could get and include the relevant linking information. Here's the Makefile:
# a rudimentary Makefile for Gambit targets GSC=/usr/local/Gambit-C/current/bin/gsc LDOPTS=-g -L/usr/lib/gsl -lgslcblas -lgsl -lgambc GAMBINC=-L../lib CCOPTS=-I/usr/include GAMBC=-I../include GSCOPTS=-debug -track-scheme -warnings #-expansion LINK=-link -flat SRCS= srfi.scm gsl-genx.scm f64matrix.scm life-table.scm COUT := $(SRCS:.scm=.c)
# make a loadable library loadable: gsc $(LINK) -ld-options "$(LDOPTS)" $(GSCOPTS) -o genxic.o.c $(SRCS) gcc -shared -D___DYNAMIC $(GAMBC) $(GAMBINC) $(COUT) genxic.o.c -o genxic.o
Joel
Joel,
On Sun, Jun 29, 2008 at 7:23 PM, Joel J. Adamson adamsonj@email.unc.edu wrote:
It's as close to what's in the info file as I could get and include the relevant linking information. Here's the Makefile:
Okay, instead of calling it "genxic.o" you're going to want to call it "genxic.o1" or some other number for the 1.
The Gambit loader checks the file extension to see if it's a dynamic library, and it appears to only recognize extensions which match the regex /.o[1-9][0-9]*/ as such. Otherwise it attempts to load the file as a source file. That's why you're getting that funny error; it's treating your binary file as a .scm file. :)
Beyond that, you don't want to give a dynamic library the .o extension; that's reserved for object files which haven't gone through the link phase yet.
--Jeff
"Jeff Read" bitwize@gmail.com writes:
Joel,
On Sun, Jun 29, 2008 at 7:23 PM, Joel J. Adamson adamsonj@email.unc.edu wrote:
It's as close to what's in the info file as I could get and include the relevant linking information. Here's the Makefile:
Okay, instead of calling it "genxic.o" you're going to want to call it "genxic.o1" or some other number for the 1.
The Gambit loader checks the file extension to see if it's a dynamic library, and it appears to only recognize extensions which match the regex /.o[1-9][0-9]*/ as such. Otherwise it attempts to load the file as a source file. That's why you're getting that funny error; it's treating your binary file as a .scm file. :)
Beyond that, you don't want to give a dynamic library the .o extension; that's reserved for object files which haven't gone through the link phase yet.
Thanks! EVerything you're saying makes sense...
Except that I originally called it "genxic.o1" and I got the same error ;)
I've tried it again and it works; on to the next error ;)
Did you notice anything else amiss with my compilation commands?
Thanks again, Joel
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). Alternately, you can
% gsc
(compile-file "file1") (load "file1")
...
And if you're using gcc your CCOPTS (a) don't include " -fwrapv -fno- strict-aliasing", which are needed for correctness and (b) have no optimization options ("-O1" and a few others are best, not -O2 or - O3) and no -D___SINGLE_HOST.
All these things are taken care of automatically when use use the "compile-file" gambit command, or just
% gsc all
or % gsc file1 % gsc file2 ...
I've seen a number of posts to this mail list where people don't want to use this built-in machinery for building dynamically loadable files, but I don't understand why.
Brad
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.
And if you're using gcc your CCOPTS (a) don't include " -fwrapv -fno- strict-aliasing", which are needed for correctness and (b) have no optimization options ("-O1" and a few others are best, not -O2 or - O3) and no -D___SINGLE_HOST.
Hmmm...good to know. I thought those would only be needed (because I haven't studied gcc enough!) when I was compiling an executable ;)
I've seen a number of posts to this mail list where people don't want to use this built-in machinery for building dynamically loadable files, but I don't understand why.
Would it be practical to just compile the foreign-interfacing files with gcc and use compile-file with the rest of them?
Thanks, Joel
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
adamsonj@email.unc.edu (Joel J. Adamson) writes:
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
[...]
And if you're using gcc your CCOPTS (a) don't include " -fwrapv -fno- strict-aliasing", which are needed for correctness and (b) have no optimization options ("-O1" and a few others are best, not -O2 or - O3) and no -D___SINGLE_HOST.
Hmmm...good to know. I thought those would only be needed (because I haven't studied gcc enough!) when I was compiling an executable ;)
I've seen a number of posts to this mail list where people don't want to use this built-in machinery for building dynamically loadable files, but I don't understand why.
Well, I discovered one possible reason: using optimization and all the options you suggested, compilation takes upwards of five minutes, if it completes at all, it slows down my entire machine, and half the time I get a segfault when I load the library. Removing -O1 and -D___SINGLE_HOST solves that problem: compilation takes about 30 seconds with no interruption in responsiveness on my machine.
Joel