Dear Gambit-List, I have the following problem:
I have a C header file that I use to include all the C files I need, and define a single function that transfers between C vectors and Scheme f64vectors. I have included this file in my "Scheme header" so I can compile a single file. Incidentally, I also include the C header (gsl_genx.h) in each Scheme module. Compilation with gsc goes just fine, but when I load the file with gsi, I get an error. Here are the files and the error:
************************************************** /home/joel/lisp/scm/genxic/gsl_genx> cat gsl_genx.h /* -*- mode:c -*- */ /* $Id$ */ /* */ /* gsl_genx.c */
#ifndef ___GSL_GENX #define ___GSL_GENX #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <gsl/gsl_vector.h> #include <gsl/gsl_matrix.h> #include <gsl/gsl_blas.h> #include <gsl/gsl_errno.h> /* C function for transferring vectors */ /* this could be better defined as a function-like macro */ int f64vector_length (___SCMOBJ); double f64vector_ref (___SCMOBJ, int); double * scm_vector_to_C (___SCMOBJ f64vec) { /* initialize the length of the vector */ int len = f64vector_length (f64vec); /* initializes the new vector */ double * newCvec = malloc (len*sizeof (double)); /* declare a counter */ int i; /* iterate over the length of the vector copying each object into the new vector */ for (i = 0; i<len; i++) { /* could be re-written using pointer arithmetic */ newCvec[i] = f64vector_ref (f64vec, i); } return newCvec; } #endif /home/joel/lisp/scm/genxic/gsl_genx> cat gsl_genx.scm ;; -*- mode:scheme -*- ;;$Id$ ;; ;; gsl_genx.scm
;; header file for GSL API (c-declare "#include "gsl_genx.h"") (include "gsl_structures.scm") (include "gsl_lalgebra.scm") (include "gsl_wrapper.scm") ;; end of gsl_genx.scm /home/joel/lisp/scm/genxic/gsl_genx> gsc gsl_genx.scm /home/joel/lisp/scm/genxic/gsl_genx> gsi gsl_genx *** ERROR IN ##main -- /home/joel/lisp/scm/genxic/gsl_genx/gsl_genx.o11: undefined symbol: gsl_matrix_get_row (load "gsl_genx") /home/joel/lisp/scm/genxic/gsl_genx> **************************************************
And the function with gsl_matrix_get_row (in gsl_structures.scm):
************************************************** (define gsl-row-vector ;; gets the row of matrix and sets it equal to a vector (c-lambda (gsl-vector* gsl-matrix* int) gsl-vector* "gsl_matrix_get_row (___arg1, ___arg2, ___arg3); ___result_voidstar = ___arg1;")) **************************************************
Now, the obvious problem is that the symbol *is* defined in gsl/gsl_matrix.h. If I comment the function that uses gsl_matrix_get_row, then the next one comes up with the same error. I've looked at the resulting C file (gsc -c gsl_genx.scm), and gsl_genx.h is included. What am I missing here?
An added note: i used a different (less logical) organizational scheme before, and I didn't have this problem.
I will again humbly point out that I know a lot more about Scheme than I know about C ;)
Thanks, Joel
Afficher les réponses par date
Joel J. Adamson wrote:
/home/joel/lisp/scm/genxic/gsl_genx> gsi gsl_genx *** ERROR IN ##main -- /home/joel/lisp/scm/genxic/gsl_genx/gsl_genx.o11: undefined symbol: gsl_matrix_get_row (load "gsl_genx")
...
Now, the obvious problem is that the symbol *is* defined in gsl/gsl_matrix.h. If I comment the function that uses gsl_matrix_get_row, then the next one comes up with the same error. I've looked at the resulting C file (gsc -c gsl_genx.scm), and gsl_genx.h is included. What am I missing here?
(Note/beware: the following is all from someone who just learnt how the unix/gnu toolchain works by need and example and not by detailed study.)
When load complains about an undefined symbol, it's really the dynamic linker. It is complaining about a C function/variable the object file is requiring, and which the dynamic linker is trying to resolve, but cannot find a match; this usually means that (a dependency of the object file is not loaded already and) that the object file has been compiled without giving gcc -l flags so that it integrates the relevant info for loading the dependencies automatically. I think you are missing some flag along the lines of "-ld-options -lgsl" to your gsc invocation.
Be aware that these symbols are different from the ones in the header files: the header files only exist at compile time, they are telling the C compiler about types and some additional info (extern, volatile etc. flags). After the object file has been built, resolving symbols is a task for the (dynamic or static) linker, not the compiler. In short: you're not getting a compiler error, but a linker error (loading an object file into Gambit is (an extended form of) dynamic linking).
Christian.
Christian Jaeger christian@pflanze.mine.nu writes:
Joel J. Adamson wrote:
/home/joel/lisp/scm/genxic/gsl_genx> gsi gsl_genx *** ERROR IN ##main -- /home/joel/lisp/scm/genxic/gsl_genx/gsl_genx.o11: undefined symbol: gsl_matrix_get_row (load "gsl_genx")
...
Now, the obvious problem is that the symbol *is* defined in gsl/gsl_matrix.h. If I comment the function that uses gsl_matrix_get_row, then the next one comes up with the same error. I've looked at the resulting C file (gsc -c gsl_genx.scm), and gsl_genx.h is included. What am I missing here?
When load complains about an undefined symbol, it's really the dynamic linker. It is complaining about a C function/variable the object file is requiring, and which the dynamic linker is trying to resolve, but cannot find a match; this usually means that (a dependency of the object file is not loaded already and) that the object file has been compiled without giving gcc -l flags so that it integrates the relevant info for loading the dependencies automatically. I think you are missing some flag along the lines of "-ld-options -lgsl" to your gsc invocation.
Bingo!
I now remember that I had those options before (when it worked). I needed "-lgsl -lgslcblas". Now it works.
Thanks Joel