C - 对“sqrt”的未定义引用,即使使用'-lm'

时间:2014-12-15 00:57:49

标签: c gcc ld math.h

我尝试在C中编译一个需要“math.h”的库,这里是.c文件的开头:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h> 
#include "sparse_matrix.h"
...

我用这个命令编译:

gcc -c ./sparse_matrix.c -o sparse_matrix.o -lm -Wall -pedantic -std=c99 -g -O

但即使完成#include并且文件后面有-lm标志(我已尝试在行尾但没有改变)我仍然得到错误:     undefined reference to « sqrt » collect2: error: ld returned 1 exit status

我在谷歌搜索一小时后没有得到它。 我在ubuntu 14.10(utopic unicorn)下使用gcc 4.9。 提前感谢您的帮助!

1 个答案:

答案 0 :(得分:10)

我不认为你正在运行的命令(好吧,它可能只是一个,但它已经当然不是导致你的错误的那个。)

-c的{​​{1}}选项告诉它只创建目标文件(并且你专门将输出发送到gcc,一个目标文件而不是一个可执行文件)。

在这种情况下,链接器 根本不应该被调用。

事实上,假的sparse_matrix.o为:

sparse_matrix.c

你的命令工作正常,当我用:

完成这个过程时
#include <math.h>
int main(void) {
    return (int)(sqrt(16.0));
}

你可以看到它也运行得很好。

可能是您从实际的链接阶段中删除链接器标志(例如pax> gcc -o sparse_matrix sparse_matrix.o -lm pax> ./sparse_matrix pax> echo $? 4 ),这会导致此问题。它们应该对编译阶段没有影响(除非它们影响编译链接阶段,但-lm不是其中之一)。

并且,通过&#34;离开&#34;,我还包括&#34;错位&#34;的可能性。一些链接器在它们处理库的方式中是位置,因为只有在它们被列出的位置满足未定义的符号时,它们才会从库中提取对象。

所以,命令:

-l

会起作用,因为linker sparse_matrix.o -lm ... 文件引入了对.o的不满意的引用,sqrt满足了该引用。如果链接器位于位置,则:

libm

不会起作用,因为在处理linker -lm sparse_matrix.o ... 时,有没有不满足的符号,所以没有提取任何内容。然后在那个点之后引入的未定义引用,并且没有其他对象或库来满足它。

libmsqrt链接器阶段是否有此限制,我不知道,我只是提出了一些需要注意的可能性。