由于link顺序错误导致的undefined reference
其实我之前就遇到过这个问题,也强调过,GNU-G++在link阶段是依赖输入的.o或者.a文件的顺序的。如果顺序错误会导致undefined reference错误
见这篇随笔:http://www.cnblogs.com/qrlozte/p/4137704.html
刚才我遇到的问题是什么呢?
代码demo.cpp:其中ZJ::open_max在util.h中声明,在$(PATH_ONE)/libutil.a中;err_sys在apue.h中声明,在$(PATH_TWO)/libapue.a中,这里我用makefile里的$(PATH_XXX)来表示路径的宏值
#include "apue.h"
#include "util.h" #include <iostream> int main(void)
{
const long opmax = ZJ::open_max();
std::cout << "opmax = " << opmax << std::endl;
err_sys("test err_sys");
return ;
}
编译链接成功,可运行。
其中链接命令为:
g++ -L$(PATH_ONE) -L$(PATH_TWO) -o bin/test_exe obj/demo.o -lapue -lutil
但是,如果把err_sys那一行代码删掉,再把#include "apue.h"删掉,makefile内容不变,就会报错:
$(PATH_ONE)/libutil.a(util.o): In function `ZJ::open_max()': util.cpp:(.text+0x56): undefined reference to `err_sys(char const*, ...)'
这里,我知道的是:ZJ::open_max中有对err_sys的调用,我不明白的是:如果确实有undefined reference错误,我没删那两行的时候就该报错了吧?我又没改makefile,这是什么情况?
后来经过几番折腾,终于发现这个不起眼的错误,就是在makefile里面:
g++ -L$(PATH_ONE) -L$(PATH_TWO) -o bin/test_exe obj/demo.o -lapue -lutil
正确的应该是:
g++ -L$(PATH_ONE) -L$(PATH_TWO) -o bin/test_exe obj/demo.o -lutil -lapue
为什么?
因为$(PATH_ONE)/libutil.a里面主要包含2个函数,ZJ::open_max和ZJ::path_max,这二者都依赖于$(PATH_TWO)/libapue.a中的err_sys
对于-lapue -lutil的情况,在链接的时候,linker先看到-lapue,在demo.o中也看到了对err_sys的调用,那么linker就知道在$(PATH_TWO)/libapue.a中能找到的err_sys的入口,同理,然后linker也能知道应该去$(PATH_ONE)/libutil.a中找ZJ::open_max的入口
但是,如果你删除了demo.cpp中对err_sys的声明和调用,那么linker就无法直接知道err_sys可以在$(PATH_TWO)/libapue.a中能找到,因此linker就开始顺序查找-lapue -lutil
首先linker开始检查demo.o中的函数调用,在main函数的第一行找到了对ZJ::open_max的调用,显然,此时linker依次查看-lapue(没有,因此跳过),-lutil(找到),因此linker就去$(PATH_ONE)/libutil.a中去找到ZJ::open_max的入口,然后在ZJ::open_max中找到了对err_sys的调用,但是,此时因为-lapue已经被linker跳过了,所以linker只会继续在-lutil中查找(当然找不到),然后再看-lutil后面还有没有-l参数(没有了),因此报错undefined reference to err_sys(当然,g++ linker的实现我不知道,我这里是纯属推测)不会再回头去看-lapue中能不能找到err_sys(而Microsoft的CL.EXE就不存在这个问题)。
对于-lutil -lapue的情况,上述的问题就不存在了,因为linker发现-lutil找不到err_sys,就会继续往下找,从而在-lapue中找到err_sys
废话这么多,总结:用GNU-GCC/G++的时候,链接顺序一定不要搞错!
由于link顺序错误导致的undefined reference的更多相关文章
- gcc参数-l传递顺序错误导致`undefined reference'的一点小结
刚才编译一个pthread的单文件程序, 使用的命令行是: gcc -o thread1 -lpthread thread1.c 结果报错: $ gcc -o thread1 -lpthread th ...
- qt程序运行时的错误error:undefined reference to `_imp___ZN10QTcpSocketD1Ev'
出现的错误: undefined reference to `_imp___ZN10QTcpSocketD1Ev' undefined reference to `_imp___ZN10QTcpSoc ...
- [转载]解决linux 下多线程错误 undefined reference to `sem_init'
转自:https://blog.csdn.net/yzycqu/article/details/7396498?utm_source=copy 解决linux 下多线程错误 undefined ref ...
- Android NDK编译之undefined reference to 'JNI_CreateJavaVM'
利用Android NDK编译动态库,在C文件中调用了两个JNI函数:JNI_GetDefaultJavaVMInitArgs和JNI_CreateJavaVM.编译的时候始终报以下错误: XXX: ...
- undefined reference to `__sync_bool_compare_and_swap_4
然后开始glibc的编译工作. 你必须设定march这个参数才行,要不然会出现“undefined reference to `__sync_bool_compare_and_swap_4′.”这个错 ...
- error: undefined reference to 'av_register_all()'
cygwin下ndk编译工程中使用ffmpeg时出现的错误:“error: undefined reference to 'av_register_all()'” 使用ffmpeg的源文件是 *.c ...
- 47: error: undefined reference to `QWebView::QWebView(QWidget*)'
QT 5.6版本 用Qt界面设计器打开界面文件,在界面上托入QWebView控件,这时运行会出现错误,错误如下: ......... undefined reference to `QWebView ...
- nios ii 13 主程序的函数可以用Open Declaration 查看,但是编译的时候却说 undefined reference to 。。。这是为什么?
在做12864 ip 核试验时,写了三个文件第一个是时序文件QC12864.v第二个是QC12864.H这个文件主要包括声明和宏定义,第三个文件是QC12864.c这个文件包含函数的定义.详细的请看 ...
- Linux下运行《UNIX环境高级编程》undefined reference to `err_quit 编译出错的处理方法
错误信息: : undefined reference to `err_quit': undefined reference to `err_sys' 解决方法: 因为err_quit跟err_sys ...
随机推荐
- idea的一些快捷键
查找文本的出现位置就用Ctrl+F/Ctrl+Shift+F在当前窗口或全工程中查找,再配合F3/Shift+F3前后移动到下一匹配处Intellij的Ctrl+N/Ctrl+Shift+N可以打开类 ...
- OpenCV学习(14) 细化算法(2)
前面一篇教程中,我们实现了Zhang的快速并行细化算法,从算法原理上,我们可以知道,算法是基于像素8邻域的形状来决定是否删除当前像素.还有很多与此算法相似的细化算法,只是判断的条件不一样. ...
- Orchard运用 - 为评论启用Gravatar头像
在前一篇随笔中我曾分享如何为Orchard特定主题添加独立代码文件, 今儿延续如何把对应代码应用到Views上. 对此我不妨把为评论启用Gravatar头像这一例子来实现.其实很简单, 思路大概就是创 ...
- 高性能HTML
避免使用Iframe Iframe也叫内联frame,可以把一个HTML文档嵌入到另一个文档中.使用iframe的好处是被嵌入的文档可以完全独立于其父文档,凭借此特点我们通常可以使浏览器模拟多线程,需 ...
- Echarts动画效果:实现数据左右移动
1.业务背景 图形实时从后台获取数据,让图形从最右边出现,每隔一秒向左移一位,当最左边的数据移到Y轴时,最左边的数据移出屏幕,最右边增加一个数.实现一个从右往左动画的效果 2.先看下项目中的demo解 ...
- powerdesigner 16.5 破解步骤
假设你的PowerDesigner已经安装完成.(PowerDesigner下载地址:http://pan.baidu.com/s/1mgqjmpa) 1. 从网上下载PowerDesigner165 ...
- phpstorm failed to create jvm:error code -6 解决办法 解决方法
phpStorm 软件打开运行提示 failed to create JVM的解决办法. 修改文件 D:\Program Files (x86)\JetBrains\PhpStorm 7.1.3\bi ...
- UNIX网络编程读书笔记:select函数
select函数概况: select函数允许进程指示内核等待多个事件中的任何一个发生,并仅在有一个或多个事件发生或经历一段指定的时间后才唤醒它. 作为一个例子,我们可以调用select,告知内核仅在下 ...
- 使用JavaMelody监控tomcat以及jvm
JavaMelody用于对Java应用或者应用服务器的QA以及开发环境的监控.它并不是一个模拟请求类似JMeter的压力测试工具,而是一个衡量并且计算在应用上的操作信息的工具,也就是说,它只负责对行为 ...
- Android获取手机位置代码实现
1.项目Src下创建...service包,然后新建GPSService类 package com.zebra.mobilesafe.service; import java.io.IOExcepti ...