Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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;
 }
share|improve this question
    
Can you provide some more information, maybe relevant errors from the build, or possibly the code you're trying to compile? –  Marco Ceppi Oct 24 '11 at 20:33
add comment

1 Answer

up vote 4 down vote accepted

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.

share|improve this answer
    
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 '11 at 17:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.