3

I have a problem with the gsl library in Oneiric - after upgrade from Natty to Oneiric I cannot build a program anymore with my own makefile, despite the fact that in QT Creator everything works fine and the program compiles with no problems. The necessary flags for the gsl libraries are set in both makefiles and on Natty both ways of compiling the program worked well. The gsl library files are all installed.

EDIT: the original code I tried to compile is written in c++, which is the reason that I use g++ also with the test.c file

This is the error message:

user@user:~$ g++ -lgsl -lgslcblas -lm /home/user/test.c 
/home/user/test.c: In function ‘int main()’:
/home/user/test.c:92:24: warning: format ‘%d’ expects argument of type ‘int’, but 
argument 2 has type ‘size_t {aka long unsigned int}’ [-Wformat]
/tmp/ccOLKTZH.o: In function `my_f(gsl_vector const*, void*)':
test.c:(.text+0x25): undefined reference to `gsl_vector_get'
test.c:(.text+0x3b): undefined reference to `gsl_vector_get'
/tmp/ccOLKTZH.o: In function `my_df(gsl_vector const*, void*, gsl_vector*)':
test.c:(.text+0xf7): undefined reference to `gsl_vector_get'
test.c:(.text+0x10d): undefined reference to `gsl_vector_get'
test.c:(.text+0x14c): undefined reference to `gsl_vector_set'
test.c:(.text+0x18a): undefined reference to `gsl_vector_set'
/tmp/ccOLKTZH.o: In function `main':
test.c:(.text+0x26b): undefined reference to `gsl_vector_alloc'
test.c:(.text+0x288): undefined reference to `gsl_vector_set'
test.c:(.text+0x2a1): undefined reference to `gsl_vector_set'
test.c:(.text+0x2a8): undefined reference to `gsl_multimin_fdfminimizer_conjugate_fr'
test.c:(.text+0x2bd): undefined reference to `gsl_multimin_fdfminimizer_alloc'
test.c:(.text+0x2e8): undefined reference to `gsl_multimin_fdfminimizer_set'
test.c:(.text+0x2f9): undefined reference to `gsl_multimin_fdfminimizer_iterate'
test.c:(.text+0x31e): undefined reference to `gsl_multimin_test_gradient'
test.c:(.text+0x357): undefined reference to `gsl_vector_get'
test.c:(.text+0x374): undefined reference to `gsl_vector_get'
test.c:(.text+0x3ca): undefined reference to `gsl_multimin_fdfminimizer_free'
test.c:(.text+0x3d6): undefined reference to `gsl_vector_free'
collect2: ld returned 1 exit status

This is the file I used for testing purposes:

#include <gsl/gsl_multimin.h>

 /* Paraboloid centered on (p[0],p[1]), with  
    scale factors (p[2],p[3]) and minimum p[4] */

 double
 my_f (const gsl_vector *v, void *params)
 {
   double x, y;
   double *p = (double *)params;

   x = gsl_vector_get(v, 0);
   y = gsl_vector_get(v, 1);

   return p[2] * (x - p[0]) * (x - p[0]) +
            p[3] * (y - p[1]) * (y - p[1]) + p[4]; 
 }

 /* The gradient of f, df = (df/dx, df/dy). */
 void 
 my_df (const gsl_vector *v, void *params, 
        gsl_vector *df)
 {
   double x, y;
   double *p = (double *)params;

   x = gsl_vector_get(v, 0);
   y = gsl_vector_get(v, 1);

   gsl_vector_set(df, 0, 2.0 * p[2] * (x - p[0]));
   gsl_vector_set(df, 1, 2.0 * p[3] * (y - p[1]));
 }

 /* Compute both f and df together. */
 void 
 my_fdf (const gsl_vector *x, void *params, 
         double *f, gsl_vector *df) 
 {
   *f = my_f(x, params); 
   my_df(x, params, df);
 }


 int
 main (void)
 {
   size_t iter = 0;
   int status;

   const gsl_multimin_fdfminimizer_type *T;
   gsl_multimin_fdfminimizer *s;

   /* Position of the minimum (1,2), scale factors 
      10,20, height 30. */
   double par[5] = { 1.0, 2.0, 10.0, 20.0, 30.0 };

   gsl_vector *x;
   gsl_multimin_function_fdf my_func;

   my_func.n = 2;
   my_func.f = my_f;
   my_func.df = my_df;
   my_func.fdf = my_fdf;
   my_func.params = par;

   /* Starting point, x = (5,7) */
   x = gsl_vector_alloc (2);
   gsl_vector_set (x, 0, 5.0);
   gsl_vector_set (x, 1, 7.0);

   T = gsl_multimin_fdfminimizer_conjugate_fr;
   s = gsl_multimin_fdfminimizer_alloc (T, 2);

   gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4);

   do
     {
       iter++;
       status = gsl_multimin_fdfminimizer_iterate (s);

       if (status)
         break;

       status = gsl_multimin_test_gradient (s->gradient, 1e-3);

       if (status == GSL_SUCCESS)
         printf ("Minimum found at:\n");

       printf ("%5d %.5f %.5f %10.5f\n", iter,
               gsl_vector_get (s->x, 0), 
               gsl_vector_get (s->x, 1), 
               s->f);

     }
   while (status == GSL_CONTINUE && iter < 100);

   gsl_multimin_fdfminimizer_free (s);
   gsl_vector_free (x);

   return 0;
 }
1
  • Can you provide some more information, maybe relevant errors from the build, or possibly the code you're trying to compile? Oct 24, 2011 at 20:33

1 Answer 1

4

I've just run into the same problem after upgrading to Oneiric (except with c++ code instead of c code). The problem shows up with g++-4.6 and 4.5, but compiling with g++-4.4 works as it did in Natty. So I suspect it's a compiler bug of some sort, but reverting to 4.4 seems to be feasible workaround for now.

EDIT: There is no need to downgrade - here's the root cause: It turns out this happens with any attempt to link in the wrong order because gcc on Oneiric now uses the --as-needed flag. The solution is to change the order of parameters to the linker, see http://ubuntuforums.org/archive/index.php/t-1833136.html . This change is explained in http://wiki.debian.org/ToolChain/DSOLinking; Fedora uses this as well.

1
  • Thank you! Sounds like a feasible work-around for now. I will go for that. One more remark - this problem might be related to this one: "Problems with linking GSL / CBLAS".
    – cuichi
    Oct 25, 2011 at 17:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .