转自:http://my.oschina.net/moooofly/blog/506466

问题场景:

  1. 动态库 librabbitmq_r.so 内部依赖动态库 libevent_core.so 和 libevent_pthreads.so ;
  2. 可执行程序 sa 依赖动态库 librabbitmq_r.so ;
  3. 在链接生成 sa 的时候希望只指定 librabbitmq_r.so 而不指定 libevent_core.so 和 libevent_pthreads.so 。

错误信息:

...
g++ ../source/authorisecfg.o ../source/bmcinst.o ../source/config.o ../source/lgsinst.o ../source/logicsrv.o ../source/logicsrvinst.o ../source/logicsrvmodulelistcfg.o ../source/main.o ../source/moduleinst.o ../source/print.o ../source/routingkeycfg.o ../source/sautils.o ../source/structself.o ../source/../../../common/source/bossutils.o
../source/../../../common/source/bossversion.o -o sa -m32 -L../../../../-common/lib/release/linux -lrt -lwatchdogclient -lfiletransfer -losp -lkprop -ljsonconvert -ljsoncpp -ldeploycfg -lnosectionini -lrabbitmq_r -lmqwrapper -lreadwritelock -lcaptureexception -lnetconfig /usr/bin/ld: warning: libevent_core.so, needed by ../../../../-common/lib/release/linux/librabbitmq_r.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libevent_pthreads.so, needed by ../../../../-common/lib/release/linux/librabbitmq_r.so, not found (try using -rpath or -rpath-link) ../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `event_base_free'
../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `evthread_use_pthreads'
../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `event_assign'
../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `event_base_dispatch'
../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `event_base_loopbreak'
../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `event_del'
../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `event_add'
../../../../-common/lib/release/linux/librabbitmq_r.so: undefined reference to `event_base_new'
collect2: ld returned exit status
make: *** [sa] Error

由错误信息可以看出,未找到的符号均属于 libevent_core.so 和 libevent_pthreads.so 内部。但这两个库确实存在于 -L../../../../10-common/lib/release/linux 路径下,但为什么链接器仍旧无法找到对应的库和符号呢?

下面的文章讨论了这个问题(下面给出部分摘录)

Why does ld need -rpath-link when linking an executable against a so that needs another so?

...


You
system, through ld.so.conf, ld.so.conf.d, and the system environment,
LD_LIBRARY_PATH, etc.., provides the system-wide library search paths
which are supplemented by installed libraries through pkg-config
information and the like when you build against standard libraries. 



...


There
is no standard run-time library search path for custom shared libraries
you create yourself. You specify the search path to your libraries
through the -L/path/to/lib designation during compile and link. For
libraries in non-standard locations, the library search path can be
optionally placed in the header of your executable (ELF header) at
compile-time so that your executable can find the needed libraries.



...


rpath
provides a way of embedding your custom run-time library search path in
the ELF header so that your custom libraries can be found as well
without having to specify the search path each time it is used. This
applies to libraries that depend on libraries as well. As you have
found, not only is the order you specify the libraries on the command
line important, you also must provide the run-time library search path,
or rpath, information for each dependent library you are linking against
as well so that the header contains the location of all libraries
needed to run.



...


back
to the semantics of ld. In order to produce a "good link", ld must be
able to locate all dependent libraries. ld cannot insure a good link
otherwise. The runtime linker must find and load, not just to find the
shared libraries needed by a program. ld cannot guarantee that will
happen unless ld itself can locate all needed shared libraries at the
time the progam is linked.



...

结论就是,像这种 a.so 依赖 b.so ,而 c 依赖 a.so 的情况,在链接过程中需要通过 -rpath-link 指定所需 .so 的位置,而不能仅仅使用 -L 指定。

示例如下:

[root@Betty include_test]# ll
总用量
-rw-r--r-- root root 9月 : main.c
-rw-r--r-- root root 9月 : say_hello.c
-rw-r--r-- root root 9月 : say_hello.h
-rw-r--r-- root root 9月 : time_print.c
-rw-r--r-- root root 9月 : time_print.h
[root@Betty include_test]#

【say_hello.c】

// g++ -o say_hello.so -fpic -shared say_hello.c

#include <stdio.h>
void say_hello()
{
printf( "Hello World!\n" );
}

【say_hello.h】

void say_hello();

【time_print.c】

// g++ -o time_print.so -fpic -shared -I. -L. time_print.c say_hello.so 

#include <time_print.h>
#include <stdio.h>
#include <say_hello.h> int time_print( time_t tmp )
{
int off = ;
time_t t;
char buf[] = {}; t = time( NULL );
off = strftime( buf, sizeof(buf), "%d %b %H:%M:%S", localtime( &t ) );
fprintf( stderr, "current timestamp = %s\n", buf ); say_hello(); return ;
}

【time_print.h】

#include <time.h>
int time_print( time_t t );

【main.c 】

// g++ -o main main.c time_print.so -I. -Wl,-rpath-link,.

#include <time_print.h>

int main()
{
time_t t;
time_print( t );
return ;
}

生成两个 .so 库

[root@Betty include_test]# g++ -o say_hello.so -fpic -shared say_hello.c
[root@Betty include_test]# ll
总用量
-rw-r--r-- root root 9月 : main.c
-rw-r--r-- root root 9月 : say_hello.c
-rw-r--r-- root root 9月 : say_hello.h
-rwxr-xr-x root root 9月 : say_hello.so
-rw-r--r-- root root 9月 : time_print.c
-rw-r--r-- root root 9月 : time_print.h
[root@Betty include_test]#
[root@Betty include_test]# g++ -o time_print.so -fpic -shared -I. -L. time_print.c say_hello.so
[root@Betty include_test]# ll
总用量
-rw-r--r-- root root 9月 : main.c
-rw-r--r-- root root 9月 : say_hello.c
-rw-r--r-- root root 9月 : say_hello.h
-rwxr-xr-x root root 9月 : say_hello.so
-rw-r--r-- root root 9月 : time_print.c
-rw-r--r-- root root 9月 : time_print.h
-rwxr-xr-x root root 9月 : time_print.so
[root@Betty include_test]#

若不指定 -rpath-link 选项,则链接失败

[root@Betty include_test]# g++ -o main main.c time_print.so -I. -L.
/usr/bin/ld: warning: say_hello.so, needed by time_print.so, not found (try using -rpath or -rpath-link)
time_print.so: undefined reference to `say_hello()'
collect2: ld 返回
[root@Betty include_test]#

若指定 -rpath-link 选项,则可以成功链接

[root@Betty include_test]# g++ -o main main.c time_print.so -I. -L. -Wl,-rpath-link,.
[root@Betty include_test]# ll
总用量
-rwxr-xr-x root root 9月 : main
-rw-r--r-- root root 9月 : main.c
-rw-r--r-- root root 9月 : say_hello.c
-rw-r--r-- root root 9月 : say_hello.h
-rwxr-xr-x root root 9月 : say_hello.so
-rw-r--r-- root root 9月 : time_print.c
-rw-r--r-- root root 9月 : time_print.h
-rwxr-xr-x root root 9月 : time_print.so
[root@Betty include_test]#

查看一下共享库依赖关系

[root@Betty include_test]# ldd say_hello.so
linux-vdso.so. => (0x00007fffb53ff000)
libstdc++.so. => /usr/lib64/libstdc++.so. (0x00007f56915d4000)
libm.so. => /lib64/libm.so. (0x00007f5691350000)
libgcc_s.so. => /lib64/libgcc_s.so. (0x00007f5691139000)
libc.so. => /lib64/libc.so. (0x00007f5690da5000)
/lib64/ld-linux-x86-.so. (0x000000388c400000)
[root@Betty include_test]#
[root@Betty include_test]# ldd time_print.so
linux-vdso.so. => (0x00007fff50cfa000)
say_hello.so => not found
libstdc++.so. => /usr/lib64/libstdc++.so. (0x00007ff0f7829000)
libm.so. => /lib64/libm.so. (0x00007ff0f75a5000)
libgcc_s.so. => /lib64/libgcc_s.so. (0x00007ff0f738f000)
libc.so. => /lib64/libc.so. (0x00007ff0f6ffa000)
/lib64/ld-linux-x86-.so. (0x000000388c400000)
[root@Betty include_test]#
[root@Betty include_test]# ldd main
linux-vdso.so. => (0x00007fffc55ff000)
time_print.so => not found
libstdc++.so. => /usr/lib64/libstdc++.so. (0x0000003899800000)
libm.so. => /lib64/libm.so. (0x000000388dc00000)
libgcc_s.so. => /lib64/libgcc_s.so. (0x0000003898000000)
libc.so. => /lib64/libc.so. (0x000000388c800000)
/lib64/ld-linux-x86-.so. (0x000000388c400000)
[root@Betty include_test]#

执行程序

[root@Betty include_test]# ./main
./main: error while loading shared libraries: time_print.so: cannot open shared object file: No such file or directory
[root@Betty include_test]#
[root@Betty include_test]# LD_LIBRARY_PATH=. ./main
current timestamp = Sep ::
Hello World!
[root@Betty include_test]#

最后给出一个 rpath 递归问题的讨论: 《Resursive linking with rpath

Linux下共享库嵌套依赖问题 (转载)的更多相关文章

  1. 转:linux下共享库的注意点之-fpic

    转: http://www.cnblogs.com/leo0000/p/5691483.html linux下共享库的注意点之-fpic 在编译共享库必须加上-fpic.这是为什么呢? 首先看一个简单 ...

  2. linux下共享库的注意点之-fpic

    在编译共享库必须加上-fpic.这是为什么呢? 首先看一个简单的例子: #include <stdio.h> int fun1() { printf("fun1\n") ...

  3. linux下静态库和动态库一些东西

    http://www.cnblogs.com/changefuture/archive/2011/12/22/2297460.html Linux  动态链接库和静态库示例 文件预览 文件目录树如下, ...

  4. 谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH PKG_CONFIG_PATH

    谈谈Linux下动态库查找路径的问题 ldconfig LD_LIBRARY_PATH  PKG_CONFIG_PATH 转载自:http://blog.chinaunix.net/xmlrpc.ph ...

  5. LINUX下动态库及版本号控制

    针对同一动态组件的不同版本链接和加载. 一.概念                  DLL HELL字面意思是DLL"灾难",是由于com组件(动态库)升级引起的程序不能运行的情况 ...

  6. LINUX总结第13篇:LINUX下动态库及版本号控制

    感觉讲得挺详细 注: ln 命令用法 ln –s 源文件 目标文件 (目标文件即为软链接文件) 可用ls -l查看软链接文件具体指向哪个文件 目录[-] 1. File libhello.c 2. F ...

  7. Linux下的库操作工具-nm、ar、ldd、ldconfig和ld.so

    Linux下的库操作工具-nm.ar.ldd.ldconfig和ld.so .nm [options] file 列出file中的所有符号 [option] -c 将符号转化为用户级的名字 -s 当用 ...

  8. 深入理解LINUX下动态库链接器/加载器ld-linux.so.2

    [ld-linux-x86-64.so.2] 最近在Linux 环境下开发,搞了好几天 Compiler 和 linker,觉得有必要来写一篇关于Linux环境下 ld.so的文章了,google上搜 ...

  9. Linux下MiniGUI库的安装

    Linux下MiniGUI库的安装 今天试了下安装MiniGUI的库 先仿照官网的教程安装 传送门:MiniGUI官网 一.配置依赖环境 安装构建工具 apt install binutils aut ...

随机推荐

  1. Kubernetes对象之Service

    系列目录 通过ReplicaSet来创建一组Pod来提供具有高可用性的服务.虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题: Pod IP仅仅是集群内可见的虚拟IP,外部无法访问. ...

  2. 关于input:-webkit-autofill样式问题

    最近在整理项目的时候,遇到了一个chrome浏览器自动填充的样式问题, 用户名跟密码的input都设置为透明颜色,但是会变成黄色,打开chrome调试工具,发现有个input:-webkit-auto ...

  3. 安装protobuf可能遇到的问题

    下载protobuf-2.3.0:    http://protobuf.googlecode.com/files/protobuf-2.3.0.zip http://code.google.com/ ...

  4. Edit conflicts

    Edit conflicts 当副本修改处和服务器版本相同处被修改并下载到本地时,就会发生文件冲突. 操作步骤如下所示: Ø 执行"SVN Update" Ø 若发生冲突,会出现如 ...

  5. .Net——实现IConfigurationSectionHandler接口定义处理程序处理自定义节点

    除了使用.net里面提供的内置处理程序来处理我们的自定义节点外,我们还可以通过多种方法,来自己定义处理类处理我们的自定义节点,本文主要介绍通过实现IConfigurationSectionHandle ...

  6. C# 调用类库里的事件

    首先在类库中定义事件: //定义委托 public delegate void DelWeiTuo(string name); //定义事件 public event DelWeiTuo EventW ...

  7. PHP基础函数、自定义函数以及数组

    2.10 星期五  我们已经真正开始学习PHP 了,今天的主要内容是php基础函数.自定义函数以及数组, 内容有点碎,但是对于初学者来说比较重要,下面是对今天所讲内容的整理:  1 php的基本语法和 ...

  8. funhub 独立游戏团队诚邀策划,美术,技术,QA 大大加入(可远程办公)

    我们刚成立的的独立游戏团队,base:广州,团队陆陆续续已经有 6 个成员了,现在还缺的岗位有策划,美术.不过有其 他岗位的仁人志士也可加入. 另外,我们支持远程办公,这是互联网行业的天然优势,一定要 ...

  9. SAM4E单片机之旅——4、LED闪烁之PWM

    两个LED灯虽然可以闪了,但是总是需要CPU的参与.现在尝试使用一种更为自动化的方法:让脉宽调制(PWM)控制器输出具有一定周期和占空比的方波,以此控制LED灯的亮灭. 一.实现思路 依然使用蓝色和琥 ...

  10. uva 10733 The Colored Cubes<polya定理>

    链接:http://uva.onlinejudge.org/external/107/10733.pdf 题意: N 种颜色可以涂成多少种立方体~ 思路: 使正六面体保持不变的运动群总共有: 1.不变 ...