linux编译动态库未定义,GCC链接库的⼀个坑:动态库存在却
提⽰未定义动态库的函数...
背景
在GCC中已经指定链接库,然⽽编译时却提⽰动态库函数未定义!
测试出现的错误提⽰如下:
[GMPY@13:48 tmp]$gcc -o test -L. -lmylib test.c
/tmp/ccysQZI3.o:在函数‘main’中:
test.c:(.text+0x1a):对‘func_lib’未定义的引⽤
collect2: error: ld returned 1 exit status
⽽在测试⽤的动态库libmylib.so中是有定义函数func_lib的
[GMPY@13:55 tmp]$cat mylib.c
#include
越的组词int func_lib(void)
{
自制烤地瓜printf("In share library\n");
return 0;
}
[GMPY@13:56 tmp]$gcc -fPIC -shared mylib.c -o libmylib.so
GCC的链接坑
此处的"坑"指对不熟悉GCC机制的童鞋⽽⾔,会出现⽆法理解的不符合预期的效果
在⽤gcc编译时,我们可以⽤-L指定链接库位置,⽤-l指定。
man gcc查询时,我发现这么⼀段描述:
-
llibrary
-l library
... ## 这⾥为了⽅便阅读,对原⽂进⾏了换⾏排版优化
It makes a difference where in the command you write this option;
the linker arches and process libraries and object files in the order they are specified.
Thus, foo.o -lz bar.o arches library z after file foo.o but
If bar.o refers to functions in z, tho functions may not be loaded.
...
人生哲理的句子嗯,这段话什么意思呢? 如果-l链接库在源码之前,就会链接不到库!!
就像下⾯两个命令的差别:
异常:gcc -o test -L. -lmylib test.c
正常:gcc -o test -L. test.c -lmylib
竟然对执⾏时参数的位置都有要求,也是醉了
GCC的链接步骤
GCC是怎么样理解-l的呢?
A library is a collection (an archive) of object files. When you add a library using the -l option,
the linker does not unconditionally take all object files from the library. It only takes tho object
files that are currently needed, i.e. files that resolve some currently unresolved (pending) symbols.
After that, the linker completely forgets about that library.
The list of pending symbols is continuously maintained by the linker as the linker process input
摘抄格式object files, one after another from left to right. As it process each object file, some symbols get
resolved and removed from the list, other newly discovered unresolved symbols get added to the list.
So, if you included some library by using -l, the linker us that library to resolve as many currently
pending symbols as it can, and then completely forgets about that library. If it later suddenly
discovers that it now needs some additional object file(s) from that library, the linker will not "return"
to that library to retrieve tho additional object files. It is already too late.
什么个意思呢?就是说,GCC链接器按下⾯的步骤链接⽂件:
从左往右链接源⽂件
在链接时,如果出现源⽂件调⽤了却没有定义的函数、变量等,则记录下来
如果遇到-l指定的库,则在库中尽可能检索所有记录下来的没有定义的函数、变量,只从库中提取⽤到的部分,其他完全抛弃
在全部链接完后,如果依然存在未定义的函数、变量,则报错
正因为GCC链接器的"始乱终弃",在检索-l的库后,就抛弃了这个库,后⾯还需要⽤时,⾃然就找不到了
GCC并不会回过头来检索之前链接过的库
从这样的链接步骤,我猜测还会有个特性:
由于GCC链接库会在⾸先指定的库中"贪婪匹配"所有未定义的函数、变量,因此,
即使两个库有相同的函数、变量的定义,只会使⽤最先找到的库中的定义
node中通过orm2链接mysql的⼀个坑
代码是orm上的例⼦,出现如下错误: ORMError: Connection protocol not supported - have you installed the databa dri ...幻灯片
Visual Studio 安装easyX且导⼊graphics库后,outtextxy提⽰未定义标⽰符
1.点击 “项⽬” ,然后点击 “属性”.
2. 然后点击左侧 “配置与属性” 下的 “常规” ,在点击 “字符集” ,选择 “使⽤多字节字符集” 即可解决问题
xamarin绑定原⽣库的⼀些坑
最近⼀个项⽬涉及到较多的第三⽅库的绑定技术,中间遇到了⼏个坑,记录下来与⼤家分享 绑定Jar库 monoandroid对原⽣库的调⽤都通过Android.Runtime.JNIEnv进⾏调⼊(http ...
Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别
昨天在⾃⼰的CentOs7.1上写makefile的时候,发现在⼀个C程序在编译并链接⼀个已⽣成好的lib动态库的时候出错.链接命令⼤概是这样的: [root@typecodes tcpmsg]# g ...
gcc链接g++编译⽣成的静态库和动态库的makefile⽰例
使⽤c++开发程序或者库时,将库提供给其他⼈使⽤. 然⽽使⽤者是使⽤c开发的程序,链接g++编译⽣成的库时,于链接gcc⽣成的库,有所不同.⾸先是静态库,以链接g++编译⽣成的libmylib.a为 ...
g++/gcc 链接头⽂件 库 PATH
游戏创业记前端状态管理库Akita中的⼀个坑
记状态管理库Akita中的⼀个坑 Akita是什么 Akita是⼀种基于RxJS的状态管理模式,它采⽤Flux中的多个数据存储和Redux中的不可变更新的思想,以及流数据的概念,来创建可观察的数据存储 ...
GCC链接的⼏个注意点
库⽂件依赖顺序 GCC在链接时对依赖库的顺序是敏感的,被依赖的库必须放在后⾯,⽐如liba.a依赖libb.a,必须写成liba.a libb.a,否则链接将出错.在库⽐较多依赖关系⽐较复杂或者相互依 ...
十大电冰箱排行榜随机推荐
PhoneGap: Android ⾃定义组件
nslog
今天有⼈问我怎么更好的使⽤nslog,打包的时候⽼注释 pch⾥加下⾯的代码就好了平时debug的时候打印,relea后就不打印了 #ifdef DEBUG#define NSLog(...) N ...
i++为什么没有⾃增探析——JVM中i++的实现(转)
很多朋友在使⽤Java时候会发现⼀个很奇怪的现象. 那就是使⽤下列的短句时会发现i没有⾃增,这是很让⼈迷惑的,因为⼤家印象中,虽然
i++优先级较低,但是总是会⾃增的,这⾥为什么i++没有⾃增? i=i ...
给 input 中 type=";text"; 设置CSS样式
input[type="text"], input[type="password"] { border: 1px solid #ccc; paddi ...
[设计模式] 3 创建者模式 builder
OAuth 2.0介绍学习
OAuth2.0是OAuth协议的下⼀版本,但不向后兼容OAuth 1.0即完全废⽌了OAuth1.0. OAuth 2.0关注客户端开发者的简易性.要么通过组织在资源拥有者和HTTP服务商之间的被批 ...读书笔记30篇
[Tools] Wireshark Primer Tutorials
Docker⼊门 - 003 Docker 实例
Docker Hello World Docker 允许你在容器内运⾏应⽤程序, 使⽤ docker run 命令来在容器内运⾏⼀个应⽤程序. 输出Hello world runoob@runoob: ...
基于Vue的Quasar Framework 介绍 这个框架UI组件很全⾯
前端回顾:2016年 JavaScript 之星
JavasScript社区在创新的道路上开⾜了马⼒,曾经流⾏过的也许⼀个⽉之后就过时了.2016已经结束
了.你可能会想你是否错过⼀些重要的东西?不⽤担⼼,让我们来回顾2016年前端有哪些主流.通过⽐较 ...