拓展程序功能,并用gcc编译,结果在添加了库<math.h>后出现问题
gcc -o main main.c
编译错误提示:
/usr/bin/ld: /tmp/cckwgwIa.o: undefined reference to symbol 'sin@@GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
经过查找资料,发现了问题出现的原因:
main.c中使用了Sin_Calcu()来计算sin值
函数具体定义在Signal.c中
函数实现中使用了<math.h>中sin()方法
所以形成了 main.c -> Signal.c ->math.h 的调用关系
结果在链接过程中 main.c 就找不到 math.h 中的 sin() 函数定义了
解决方法:
gcc -o main main.c -lm
显式链接到math.h
这样就编译通过啦
感谢大家的博客,让我弄懂了这个问题。同时,也学到不少其他东西,列在下面:
1.什么是编译,链接
参考链接:http://www.cprogramming.com/compilingandlinking.html
编译就是把C/C++的高级语言翻译成机器语言指令,编译过程是对独立的文件,并不检查函数的定义放在什么地方,也不会生成可以执行的文件,通常是生成.o(.obj)这样的文件。
链接则要根据.o文件生成可执行的程序或库。函数未定义这样的错误都是在链接过程中产生的。编译过程如果找不到一个函数的定义,它会认为这个函数的定义放在其它文件,而链接则一定要找到第个函数的定义。
这样多个库文件在链接时就有了依赖性的问题。
2.检查binutils的版本
ld -v
binutils2.22开始,其中的ld开始把--no-copy-dt-needed-entries默认打开,这样一来,ld不会再自动递归地解析链接的lib,而需要由用户来一一指定。