C 对已链接的函数的未定义引用

C 对已链接的函数的未定义引用,c,makefile,math.h,C,Makefile,Math.h,我正在制作一个名为reporter的C程序,下面是包括: #include <lcthw/dbg.h> #include <lcthw/stats.h> #include <stdio.h> #include <math.h> Stats\u转储在Stats.cimplementation文件中: void Stats_dump(Stats *st){ fprintf(stderr,"sum : %f, sumsq %f, n: %ld,min:

我正在制作一个名为reporter的C程序,下面是包括:

#include <lcthw/dbg.h>
#include <lcthw/stats.h>
#include <stdio.h>
#include <math.h>
Stats\u转储在Stats.cimplementation文件中:

void Stats_dump(Stats *st){
fprintf(stderr,"sum : %f, sumsq %f, n: %ld,min:%f, max: %f,mean: %f, stddev: %f",
    st->sum,st->sumsq,st->n,st->min,st->max,Stats_mean(st),Stats_stddev(st));}
这会导致Stats.h中的Stats\u stddev出现错误:

static inline double Stats_stddev(Stats *st){
return sqrt((st->sumsq-st->sum*st->sum/st->n)/(st->n-1)); // potential error?
}
当我在makefilebuild/libYOURLIBRARY.a中运行这一行时,我存储自制的lib,比如stats:

cc -g -O2 -Wall -Wextra -Isrc -rdynamic  -fPIC  reporter.c -lm  build/libYOURLIBRARY.a -o reporter
然而,它返回:

build/libYOURLIBRARY.a(stats.o): In function `Stats_stddev':
/media/thang/DATA/gay/liblcthw/src/lcthw/stats.h:17: undefined reference to `sqrt'
我在每个单独的文件中都包含了math.h,并且在makefile的每一行中都添加了-lm,但是没有效果


是什么导致了这个问题,以及如何解决这个问题?

有些链接器往往相当简单。当他们在命令行上遇到-lsomething时,他们使用它来满足任何当前未解析的符号

引入一个新的未解析符号,如build/libYOURLIBRARY。a可能不会导致它备份并再次尝试前面提到的库

在您的特定情况下,可能只需将-lm移到存档文件之后即可修复:

cc -g -O2 -Wall -Wextra -Isrc -rdynamic  -fPIC  reporter.c build/libYOURLIBRARY.a -lm -o reporter

这样,当您开始查看数学库时,未解析的符号是已知的,因此它将解析它。

一些链接器往往相当简单。当他们在命令行上遇到-lsomething时,他们使用它来满足任何当前未解析的符号

引入一个新的未解析符号,如build/libYOURLIBRARY。a可能不会导致它备份并再次尝试前面提到的库

在您的特定情况下,可能只需将-lm移到存档文件之后即可修复:

cc -g -O2 -Wall -Wextra -Isrc -rdynamic  -fPIC  reporter.c build/libYOURLIBRARY.a -lm -o reporter

这样,当您开始查看数学库时,未解析的符号是已知的,因此它将解析它。

特别是,请参见。我现在得到它,特别是感谢,请参见。我现在得到它,感谢,它解决了我的问题,但是,当我将stats.c编译为stats.o时,我已经添加了一次-lm,在那之后,我将stats.o放入build/libYOURLIBRARY.a,链接器不算吗?@Van:不算。将对象归档到库中的行为就是这样。它获取具有未解析引用的对象文件,并将其放入仍具有未解析引用的库中。当您尝试将编译C文件的对象、已编译的对象或已编译并放入存档库的对象组合成可执行形式时,您需要解析所有引用。在编译时,您不需要lib,只需要头文件-lib可能甚至没有被使用。您必须记住,您运行的gcc通常是一个前端,它将预处理器、编译器、汇编程序、库管理器、链接器等作为单独的进程或阶段调用。即使您在前端指定了-lm,它也可能只用于链接阶段。是的,它解决了我的问题,但是,当我将stats.c编译到stats.o中时,我已经添加了一次-lm,之后我将stats.o放入build/libYOURLIBRARY.a中,那个链接器不算数吗?@Van:不。将对象归档到库中的行为就是这样。它获取具有未解析引用的对象文件,并将其放入仍具有未解析引用的库中。当您尝试将编译C文件的对象、已编译的对象或已编译并放入存档库的对象组合成可执行形式时,您需要解析所有引用。在编译时,您不需要lib,只需要头文件-lib可能甚至没有被使用。您必须记住,您运行的gcc通常是一个前端,它将预处理器、编译器、汇编程序、库管理器、链接器等作为单独的进程或阶段调用。即使在前端指定了-lm,它也可能只用于链接阶段。