链接选项-rpath的一个问题记录
问题简述
大概是这么一个情况,有一个过去已经写好的程序,这个程序用于处理网络通信,接收一些操作指令。具体的指令操作通过运行时加载动态库的形式进行扩展。(类似于net-snmp二次开发的一种形式)
问题是这样的,用于扩展功能的动态库,其本身又链接了一系列的动态库,这些库的位置与这个扩展用的动态库存放的位置是相对的。大概如下
程序 program
|
| 运行时加载(dlopen/LoadLibrary等)
sodir/lib1.so
| 相对路径存放
sodir/lib2/lib2.so
问题在于编译lib1.so的时候,并不知道将来lib1.so会存放于相对程序program的工作路径的什么位置,导致不知道lib2.so的位置在哪里。
如果链接的时候直接使用-rpath=./lib2的话,这就需要lib2.so在程序工作路径下的lib2目录下方可,因为运行时加载路径并不是相对于lib1.so而是相对于program的。
这里还有一个问题,那就是如果lib2.so还有依赖,且生成lib2.so的时候没有使用-rpath选项那就比较麻烦了,因为没有相对路径,必须放置在系统默认的so搜索路径或者在/etc/ld.so.conf中添加。
假定lib2.so依赖lib3.so,那么即便是将lib3.so加入到lib1.so的链接选项中,也不会链接进去(很早之前的时候ld程序应该是把所以的都链接进去的,不管有没有使用,但最近我测试都是没有的,应该是默认使用--as-needed选项),所以查找的时候没有使用lib1.so中指定的runpath路径。这个可以使用readelf -d lib1.so命令查看。这个可以给ld添加--no-as-needed选项来强制链接所有指定的库,而不是仅仅链接需要的。
解决办法
当前没有好的解决办法。
一个简单的方法是写一个libwarp来包装一下lib1,在libwarp中先设置一下LD_LIBRARY_PATH环境变量(设置自身进程的没有用,要设置父进程或全局的(加载自身进程的进程)),加上自身所在的路径(dladdr/GetModulePath获取),然后再使用ldopen的方式加载lib1。而程序则按照原来加载lib1.so的方式加载libwarp.so即可。
这种方式实现起来比较麻烦,需要把自己终结之后重新启动以使环境变量生效,不如直接写一个脚本去运行program,在这之前去设置LD_LIBRARY_PATH环境变量。
这个问题大概可以用下面的代码来表示(就不详细叙述了)
https://files.cnblogs.com/files/oloroso/sopath.tar.gz
链接选项-rpath的一个问题记录的更多相关文章
- Linux ToolChain (二) --- Linker (1)链接选项 -L -rpath -rpath-link
一.动态库的链接和链接选项-L,-rpath-link,-rpath (1). 现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开, 用 ...
- 动态库的链接和链接选项-L,-rpath-link,-rpath
https://my.oschina.net/shelllife/blog/115958 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置.linux的可执行程序在执行 ...
- ld 链接选项-L,-rpath-link,-rpath
转载自:http://blog.csdn.net/q1302182594/article/details/42102961 1. 三个C文件 1. world.c #include<stdio. ...
- --with-http_realip_module选项(后台Nginx服务器记录原始客户端的IP地址 )
转自:http://blog.itpub.net/27043155/viewspace-734234/ 通过这个模块允许我们改变客户端请求头中客户端IP地址值(例如,X-Real-IP 或 X-For ...
- Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group
参照这两篇博客: http://stackoverflow.com/questions/805555/ld-linker-question-the-whole-archive-option http: ...
- linux 2.6.32.220的一个crash记录
有同事分析一个crash,我参与了分析,记录如下,供遇到相同crash的兄弟参考: crash> bt PID: TASK: ffff881723ce8080 CPU: COMMAND: &qu ...
- 1 - JVM随笔分类(java虚拟机的内存区域分配(一个不断记录和推翻以及再记录的一个过程))
java虚拟机的内存区域分配 在JVM运行时,类加载器ClassLoader在加载到类的字节码后,交由jvm的执行引擎处理, 执行过程中需要空间来存储数据(类似于Cpu及主存),此时的这段空间的分 ...
- HorizontalScrollView做页卡的一个小记录
用HorizontalScrollView做页卡,实现一个如下图的效果:
- window.setTimeout和window.setInterval的区别,及用其中一个方法记录时间。
window.setTimeout(语句,时间)是在多久之后执行语句,语句只执行一次. window.setInterval(语句,时间)是每隔多久执行一次语句,语句循环执行. <!DOCTYP ...
随机推荐
- Hibernate之关联关系映射(一对一主键映射和一对一外键映射)
1:Hibernate的关联关系映射的一对一外键映射: 1.1:第一首先引包,省略 1.2:第二创建实体类: 这里使用用户信息和身份证信息的关系,用户的主键编号既可以做身份证信息的主键又可以做身份证信 ...
- thinkphp注册验证
在model中新建一个UserModel //覆盖原本的设置 //一次性获得全部验证错误 protected $patchValidate = true; //实现表单项目验证 //通过重写父类属性_ ...
- day8--socket回顾
后面学习了线程.协成和异步,它们的框架都是基于socket的协议,基本原理都是一样的,现在把这几个模块重温一下,尽量掌握这些知识更全面一些. 动态导入模块,知道知道模块名,可以像反射一样,使用字符串来 ...
- BZOJ1786 [Ahoi2008]Pair 配对 动态规划 逆序对
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1786 题意概括 给出长度为n的数列,只会出现1~k这些正整数.现在有些数写成了-1,这些-1可以变 ...
- Unity3d 之 理解Gameobject ,gameObject,Transform,transform的区别和关联
Gameobject是一个类型,所有的游戏物件都是这个类型的对象. gameobject是一个对象, 就跟java里面的this一样, 指的是这个脚本所附着的游戏物件 public class Sho ...
- PopupWindow下拉列表
效果图 步骤: 1.画出编辑框的布局.popupWindow的布局.popupWindow中listview每行的布局 2.new一个PopupWindow对象,设置其属性 3.定义一个BaseAda ...
- Python打包方法——Pyinstaller (转)
Python版本:Python3.5.2 一.安装Pyinstaller 1.安装pywin32 下载安装文件:查找到跟自己适用的python版本及window系统版本匹配的pywin32,下载后 ...
- hdu 1576 A/B 【扩展欧几里得】【逆元】
<题目链接> <转载于 >>> > A/B Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)( ...
- Linux使用tcpdump命令抓包并使用wireshark分析
Linux使用tcpdump命令抓包并使用wireshark分析 介绍 有时分析客户端和服务器网络交互的问题时,为了查找问题,需要分别在客户端和服务器上抓包,我们的客户端一般是windows上的,抓包 ...
- JavaScript函数使用技巧
JavaScript中的函数是整个语言中最有趣的一部分,它们强大而且灵活.接下来,我们来讨论JavaScript中函数的一些常用技巧: 一.函数绑定 函数绑定是指创建一个函数,可以在特定的this环境 ...