undefined reference问题总结

来源:互联网 发布:nero10刻录软件怎么用 编辑:程序博客网 时间:2024/04/27 18:26

最近在Linux下编程发现一个诡异的现象,就是在链接一个静态库的时候总是报错,类似下面这样的错误:


(.text+0x13): undefined reference to `func'

    

关于undefined reference这样的问题,大家其实经常会遇到,在此,我以详细地示例给出常见错误的各种原因以及解决方法,希望对初学者有所帮助。


1. 链接时缺失了相关目标文件(.o)


测试代码如下:


 

    

然后编译。


gcc -c test.c  gcc -c main.c

    

得到两个 .o 文件,一个是 main.o,一个是 test.o ,然后我们链接 .o 得到可执行程序:


gcc -o main main.o

    

这时,你会发现,报错了:


main.o: In function `main':  main.c:(.text+0x7): undefined reference to `test'  collect2: ld returned 1 exit status

    

这就是最典型的undefined reference错误,因为在链接时发现找不到某个函数的实现文件,本例中test.o文件中包含了test()函数的实现,所以如果按下面这种方式链接就没事了。


1
gcc -o main main.o test.o


【扩展】:其实上面为了让大家更加清楚底层原因,我把编译链接分开了,下面这样编译也会报undefined reference错,其实底层原因与上面是一样的。


gcc -o main main.c //缺少test()的实现文件


需要改成如下形式才能成功,将test()函数的实现文件一起编译。


gcc -o main main.c test.c //ok,没问题了


2. 链接时缺少相关的库文件(.a/.so)

    

在此,只举个静态库的例子,假设源码如下。


    

先把test.c编译成静态库(.a)文件


gcc -c test.c  ar -rc test.a test.o

   

至此,我们得到了test.a文件。我们开始编译main.c


gcc -c main.c

    

这时,则生成了main.o文件,然后我们再通过如下命令进行链接希望得到可执行程序。


gcc -o main main.o

    

你会发现,编译器报错了:


/tmp/ccCPA13l.o: In function `main':  main.c:(.text+0x7): undefined reference to `test'  collect2: ld returned 1 exit status

    

其根本原因也是找不到test()函数的实现文件,由于该test()函数的实现在test.a这个静态库中的,故在链接的时候需要在其后加入test.a这个库,链接命令修改为如下形式即可。


gcc -o main main.o ./test.a  //注:./ 是给出了test.a的路径

     

【扩展】:同样,为了把问题说清楚,上面我们把代码的编译链接分开了,如果希望一次性生成可执行程序,则可以对main.c和test.a执行如下命令。


gcc -o main main.c ./test.a  //同样,如果不加test.a也会报错


3. 链接的库文件中又使用了另一个库文件


这种问题比较隐蔽,也是我最近遇到的与网上大家讨论的不同的问题,举例说明如下,首先,还是看看测试代码。


    

从上图可以看出,main.c调用了test.c的函数,test.c中又调用了fun.c的函数。
    

首先,我们先对fun.c,test.c,main.c进行编译,生成 .o文件。


1
gcc -c func.c  gcc -c test.c  gcc -c main.c

    

然后,将test.c和func.c各自打包成为静态库文件。


ar -rc func.a func.o  ar -rc test.a test.o

    

这时,我们准备将main.o链接为可执行程序,由于我们的main.c中包含了对test()的调用,因此,应该在链接时将test.a作为我们的库文件,链接命令如下。


gcc -o main main.o test.a

    

这时,编译器仍然会报错,如下:


test.a(test.o): In function `test':  test.c:(.text+0x13): undefined reference to `func'  collect2: ld returned 1 exit status

    

就是说,链接的时候,发现我们的test.a调用了func()函数,找不到对应的实现。由此我们发现,原来我们还需要将test.a所引用到的库文件也加进来才能成功链接,因此命令如下。


gcc -o main main.o test.a func.a

    

ok,这样就可以成功得到最终的程序了。同样,如果我们的库或者程序中引用了第三方库(如pthread.a)则同样在链接的时候需要给出第三方库的路径和库文件,否则就会得到undefined reference的错误。


4. 多个库文件链接顺序问题


这种问题也非常的隐蔽,不仔细研究你可能会感到非常地莫名其妙。我们依然回到第3小节所讨论的问题中,在最后,如果我们把链接的库的顺序换一下,看看会发生什么结果?


gcc -o main main.o func.a test.a

    

我们会得到如下报错.


test.a(test.o): In function `test':  test.c:(.text+0x13): undefined reference to `func'  collect2: ld returned 1 exit status

   

因此,我们需要注意,在链接命令中给出所依赖的库时,需要注意库之间的依赖顺序,依赖其他库的库一定要放到被依赖库的前面,这样才能真正避免undefined reference的错误,完成编译链接。


5. 在c++代码中链接c语言的库


如果你的库文件由c代码生成的,则在c++代码中链接库中的函数时,也会碰到undefined reference的问题。下面举例说明。

    

首先,编写c语言版库文件:


    


编译,打包为静态库:test.a


gcc -c test.c  ar -rc test.a test.o

    

至此,我们得到了test.a文件。下面我们开始编写c++文件main.cpp


    

    

然后编译main.cpp生成可执行程序:


g++ -o main main.cpp test.a

    

会发现报错:


/tmp/ccJjiCoS.o: In function `main': main.cpp:(.text+0x7): undefined reference to `test()' collect2: ld returned 1 exit status

    

原因就是main.cpp为c++代码,调用了c语言库的函数,因此链接的时候找不到,解决方法:即在main.cpp中,把与c语言库test.a相关的头文件包含添加一个extern "C"的声明即可。例如,修改后的main.cpp如下:


    


g++ -o main main.cpp test.a

    

再编译会发现,问题已经成功解决。


6. 总 结

    

当然,上面几种是我目前发现的比较常见的undefined reference错误的原因和解决方法,可能也有其他各种原因,欢迎大家来信lujun.hust@gmail.com或者关注我的新浪微博@卢_俊获取最新的文章和资讯。 


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为换电池之后卡没反应怎么办 汽车钥匙换电池后没反应怎么办 汽车解锁换电池后没反应怎么办 包裹显示待收件人向海关申报怎么办 在越南签证被公安扣了怎么办 酷派手机收不到验证码怎么办 苹果想把图片上的字盖上怎么办 婴儿自己把眼珠子抠红了怎么办 如果美陆战队员进入台湾那怎么办? 顺产生完小孩吸不通奶怎么办 耐克空军一号白色底发黄怎么办 中行网银u盾丢了怎么办 有人用你的手机号码不停注册怎么办 获得公开你微信头像的权限是怎么办 手机能进的网站电脑进不去怎么办 苹果8p下不了微信怎么办 苹果手机版本过底不能下微信怎么办 手机打开视频跳转到qq是怎么办 淘宝店铺显示服务竟然出错了怎么办 母羊下完羊羔把羊衣吃了怎么办? 移植后56天有黑色东西怎么办 我家的金丝熊浑身都是尿怎么办 一键启动车钥匙丢了怎么办 把爷爷的遗物弄丢了怎么办 如果你娶了一个傻子你怎么办 在国外订机票手机收不到信息怎么办 网上买机票名字写错了怎么办 买机票名字错了一个字怎么办 微店没收到货却显示已收货怎么办? 手机存的照片误删了怎么办 魔兽世界把要用的装备分解了怎么办 邻居家的狗见到我就叫怎么办 我的世界玩的时间长会卡应该怎么办 网易我的世界密码账号都忘了怎么办 我的世界创建世界画面乱码了怎么办 网易我的世界云端存档不够用怎么办 玩刺激战场带耳机声音有延迟怎么办 我的世界手机版狼变色怎么办 我的世界开了光影太阳太刺眼怎么办 我的世界饥饿值掉的慢怎么办 我的世界合装备过于昂贵怎么办