undefined reference to: xxx

总结一下原因:


1. 编译链接时

1> 库的搜索路径不对

a. 默认路径是:/lib,  /usr/lib/,  /usr/local/lib

b. -L: 指定连接时动态库的路径

c. LD_LIBRARY_PATH:  指定连接路径

一般编译时用-L指明路径即可


2> 链接库之间有依赖关系,链接时顺序书写不对  // 在编译可执行程序或静态库时,编译动态库时不会出错,但运行时出错

假设liba.a 依赖于libb.b,目标test需要liba和libb,那么生成test的命令应该为

gcc -o test -la -lb 而不是gcc -o test -lb -la

解决办法有两种,一是书写顺序正确,二是使用--start-group xxx --end-group(或“-(”和“-)”),start-group和end-group之间的库会循环查找依赖


建议书写规则如下:

g++ ...  obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib)  -o $@

即先.o文件,再是依赖的lib,lib顺序从最上层到最底层,最后是输出目标


2. 运行时

1> 库的搜索路径不对

a: ELF可执行文件中动态段中DT_RPATH所指定的路径。这实际上是通过一种不算很常用,却比较实用的方法所设置的:编译目标代码时,可以对gcc加入链接参数“-Wl,-rpath”指定动态库搜索路径;

b: 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

c: /etc/ld.so.cache中所缓存的动态库路径(如果支持ld.so.cache的话)。这可以通过修改配置文件/etc/ld.so.conf中指定的动态库搜索路径来改变;

d: 默认的动态库搜索路径/lib;     // linux平台, android/win 平台不同

e: 默认的动态库搜索路径/usr/lib  // linux平台, android/win 平台不同


-Wl,-rpath在嵌入式平台下常用

2> 依赖的so有问题

在1的2>中已说明,如果编译so时,so所依赖的动态库顺序不对,会造成运行时出错

例如:libtest.so依赖libxxx.so,编译链接命令如下:

g++ -fPIC -shared -lxxx test.o -o libtest.so

显然lxxx放在的test.o的前面,可以编译通过,但是运行就会报错了

解决办法: 一是保证lxxx在test.o的右边,而是使用-Wl,--no-as-needed

g++ -fPIC -shared test.o-lxxx -o libtest.so

g++ -fPIC -shared -Wl,--no-as-needed -lxxx test.o -o libtest.so

no-as-needed的解释

Always set DT_NEEDED for following dynamic libs  // 总是把后面的libs放到DT_NEEDED中,可以通过readelf -d来查看是否已经将lxxx加入了DT_NEEDED中


3> dlopen打开的so用到了主程序或宿主so的api

编译时需要-rdynamic -whole-archive参数,保证主程序或宿主

参考http://blog.csdn.net/fingding/article/details/46906773


dlopen遇到的undefined reference to: 问题

具体问题和这位仁兄是一样的

https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/dlopen/chromium-dev/tCdkayOKBlk/B8d5MgOiPEMJ

I have a question related to dynamic library loading in ContentShell, or in general dynamic lib loading in Java

Problem description:
In Content_Shell_Activity.java, libcontent_shell_content_view. so is loaded with System.LoadLibrary().  
I modified libcontent_shell_content_view. so which internally dlopen() my own libx.so 

libx.so uses some symbols defined in libcontent_shell_content_view. so.  However, System.LoadLibrary() loads library as LOCAL scope, which means the symbols are not visible for libx.so to resolve. 

Question:
Does anyone know how to get around this java lib loading limitation, and make the symbols global? 

Thanks a lot in advance!

解决方法主要参考,主要还是动态库中DT_NEEDED的问题

http://m.blog.csdn.net/blog/Pun_C/39231175


一般性问题:

dlopen两个不同的so,假设分别为liba.so和libb.so,轻重liba.so依赖与libb.so,而且是直接调用libb.so中的函数。

如果dlopen时使用参数RTLD_GLOBAL,也就没问题了。但现在是如果不使用RTLD_GLOBAL,怎么保证不出现undefined reference错误(应用场景就是android平台下,System.loadlibrary或System.load都是调用了dlopen且参数是RTLD_LAZY,如何保证android平台下通过System.loadlibrary打开的两个so能够互相访问(直接调用函数)


解决方法:

编译liba.so时加入libb.so依赖,且保证liba.so的dynamic section的NEEDED有libb.so,另外就是保证运行是在系统搜索路径能找到libb.so

这一点在在4.3版本的代码里,nativeLoad这个方法接受多一个参数ldLibraryPath(即app安装路径,如/data/data/org.chromium.content_shell/lib,参考3)

所以

g++ -fPIC -shared -a.o -L. -lb -o liba.so

readelf -d liba.so 就能查看是否有(NEEDED)             Shared library: [libb.so]



参考:

1 http://www.cnblogs.com/OCaml/archive/2012/06/18/2554086.html#sec-1-1

2 http://blog.csdn.net/fingding/article/details/39547123

http://m.blog.csdn.net/blog/Pun_C/39231175


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值