[问题]关于头文件连接的问题

软件和网站开发以及相关技术探讨
回复
luchen
帖子: 52
注册时间: 2007-07-16 18:40
来自: 浙江

[问题]关于头文件连接的问题

#1

帖子 luchen » 2007-11-21 23:19

小弟的这个文件make一下,它提示
root@person:/home/luchen/mytext# make
gcc -o prime prime.c
prime.c: In function ‘main’:
prime.c:12: warning: return type of ‘main’ is not ‘int’
prime.c:68:3: warning: no newline at end of file
/tmp/cca79Qmv.o: In function `prime':
prime.c:(.text+0xb6): undefined reference to `sqrt'
prime.c:(.text+0xd3): undefined reference to `sqrt'
prime.c:(.text+0x144): undefined reference to `sqrt'
collect2: ld returned 1 exit status
make: *** [prime] Error 1
竟然找不到sqrt对应的math.h.但是在/usr/include/下明明有这个头文件,但是就是不识别,晕,请问我该咋办?
附件
Screenshot.png
vupiggy
帖子: 89
注册时间: 2006-03-19 18:25
来自: FZ->TJ->PEK->AMS->MTL

#2

帖子 vupiggy » 2007-11-22 7:30

gcc -o prime prime.c -lm

你搞错原因了。不是头文件没找到,错误并非出在编译阶段,而是链接阶段。你需要指明链接什么库,使连接器能找到对应的symbol,这里是libm。
头像
madoldman
帖子: 599
注册时间: 2006-02-27 20:19
来自: works system
联系:

#3

帖子 madoldman » 2007-11-22 11:55

为虾米总有人分不清编译的错还是链接的错呢?
先gcc -c再gcc很费劲吗??
东西路,南北走
十字路口人咬狗
拿起狗来打砖头
砖头咬了狗一口
图片
vupiggy
帖子: 89
注册时间: 2006-03-19 18:25
来自: FZ->TJ->PEK->AMS->MTL

#4

帖子 vupiggy » 2007-11-22 12:24

madoldman 写了:为虾米总有人分不清编译的错还是链接的错呢?
先gcc -c再gcc很费劲吗??
大佬,不要打击新手的积极性嘛 ;)

好多好多人都是从这样开始的,都是教学方法闹得。
luchen
帖子: 52
注册时间: 2007-07-16 18:40
来自: 浙江

#5

帖子 luchen » 2007-11-22 13:16

小弟也知道是连接方面出了问题,但是小弟对于linux下的编程环境还不是很熟。所以想请教一下该如何写这个makefile?
除了
prime:prime.c
TAB gcc -o prime prime.c外还要咋加才能连接上比如<math.h>这样的头文件啊?
palxex
帖子: 136
注册时间: 2006-10-30 11:23

#6

帖子 palxex » 2007-11-22 13:35

问这个问题证明……VC真是害人啊。
gcc下没有vc那种可以在头文件里指明链接库的非标准预处理。所以这里是编译器已经从预处理器那儿拿到了sqrt的定义,只是链接器ld发现找不到目标码指明要的sqrt的定义在哪里。所以用-lm来指明要连接libm.a/so吧。
这里似乎也有CRT实现上的不同,VC的数学库是不需要另外链接的。
头像
猛将兄
帖子: 2052
注册时间: 2005-10-19 17:33

#7

帖子 猛将兄 » 2007-11-22 13:36

Linux下面编译和连接和windows下面以及和所有现代OS下面的编译和连接都没有区别啊。。。。。。
计算机以及相关专业,对这些应该讲的很详细了,但是的确考试不大会考这些的,反正我们当时不考。
我在这里没办法和你讲太详细编译,连接的过程,而编译原理教材,也过于注重语意解析的算法,而没有太多实际的例子。我大概说一下,大家补充
编译(compile),其实仅仅是将计算机语言翻译成目标代码的过程,而要从目标代码再到可执行文件,必须经过连接(link)才行。
h文件,仅仅是告诉你的编译器,我有一个这么样签名的函数,你需要给我留出多少位置来容纳我。而并没有说,我具体在做什么。
而到连接的过程,连接器会去找,这么一个函数他是在你自己写的源代码里面(在上一步编译的时候,已经被编译成了目标代码)还是在系统的其他库里面。如果是在系统的其他库里面,那么连接器会在生成的可执行文件中详细指出这个函数要从哪个库文件里面load,以方便可执行文件最后被执行的时候,系统能正确地调用该函数。

对于楼主的问题,gcc里面指定库是用-l,比如math库,在linux里面是libm.so
那么楼主应该
gcc -o prime -lm prime.c

最后强调一遍,连接的不是头文件,而是库。库分动态链接库和静态链接库,我不继续讲了,楼主要学会自己学习
头像
madoldman
帖子: 599
注册时间: 2006-02-27 20:19
来自: works system
联系:

#8

帖子 madoldman » 2007-11-22 14:08

prime:prime.o
TAB gcc prime.o -lm -o prime
prime.o:prime.c
TAB gcc -c prime.c -Wall
东西路,南北走
十字路口人咬狗
拿起狗来打砖头
砖头咬了狗一口
图片
回复