C - 对 "sqrt"的 undefined reference ,即使是 '-lm'

标签 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 标志(我已经在该行的末尾尝试过但没有任何改变)我仍然得到错误: 对 « sqrt » 的 undefined reference collect2:错误:ld 返回了 1 个退出状态

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

最佳答案

我不认为 您正在运行的命令(好吧,它可能是其中的一个 ,但它肯定不是导致您的错误的那个) .

gcc-c 选项告诉它只创建目标文件(并且您专门将输出发送到 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

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

可能是您从实际的 link 阶段遗漏了链接器标志(例如 -lm),这会导致此问题。它们应该对编译阶段没有影响(除非它们同时影响编译 链接阶段,但 -l 不是其中之一)。

而且,通过“离开”,我还包括了“放错地方”的可能性。一些链接器在它们处理库的方式上是位置的,因为它们只会从库中提取对象,前提是它们在它们列出的位置满足 undefined symbol 。/p>

所以,命令:

linker sparse_matrix.o -lm ...

之所以可行,是因为 .o 文件引入了对 sqrt 的未满足引用,libm 满足了该引用。如果您的链接器位置的,则:

linker -lm sparse_matrix.o ...

不会工作,因为在处理 libm 时,没有 不满足的符号,因此没有提取任何内容。 sqrt 的 undefined reference 在那之后被引入,并且没有其他对象或库可以满足它。

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

关于C - 对 "sqrt"的 undefined reference ,即使是 '-lm',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27475977/

相关文章:

c - 为什么 `pLQ->tail`是空指针?

将指针转换为 intptr_t 并返回

ios - 如何解决架构 i386 的 undefined symbol

c++ - PCL 1.8.0 项目的链接器错误

c - 如果静态编译的代码想要访问内核模块代码中的变量,模块必须静态编译吗?

c - 在 OpenSSL 中使用 HMAC 与 EVP 函数

gcc - 在 GCC 中使用 pragma pack (pop,1)

gcc - 编译静态库时设置较早的最低内核版本

gcc - 分支到 Microblaze CPU 上的中断处理程序,汇编语言

gcc - 构建交叉编译 64 位 GCC 失败