我在 Oneiric 中遇到了 gsl 库问题 - 从 Natty 升级到 Oneiric 后,我无法再使用自己的 makefile 构建程序,尽管在 QT Creator 中一切正常,程序编译也没有问题。在两个 makefile 中都设置了 gsl 库的必要标志,在 Natty 上,两种编译程序的方式都运行良好。gsl 库文件都已安装。
编辑:我尝试编译的原始代码是用 c++ 编写的,这就是我在 test.c 文件中使用 g++ 的原因
这是错误信息:
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
这是我用于测试目的的文件:
#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
升级到 Oneiric 后,我遇到了同样的问题(除了使用 c++ 代码而不是 c 代码)。该问题出现在 g++-4.6 和 4.5 中,但使用 g++-4.4 进行编译时,效果与在 Natty 中一样。因此,我怀疑这是某种编译器错误,但目前看来,恢复到 4.4 是可行的解决方法。
编辑:无需降级 - 根本原因如下:事实证明,任何尝试以错误顺序链接都会发生这种情况,因为 Oneiric 上的 gcc 现在使用 --as-needed 标志。解决方案是更改链接器参数的顺序,请参阅http://ubuntuforums.org/archive/index.php/t-1833136.html。此更改的解释如下http://wiki.debian.org/ToolChain/DSOLinking;Fedora 也使用这个。