RPATH与RUNPATH
RPATH与RUNPATH
原文链接: ckamm - RPATH and RUNPATH
DT_RPATH通常设置在这样一种可执行程序中,它依赖的库无法在默认位置中被找到。举例来说,Qt Creator自带一个Qt库的副本,而且有一个指向库文件所在目录的rpath。当你构建自己的Qt库而不将其安装到全局位置时,这也是很有用的:qmlviewer之类的二进制文件之所以能够工作,是因为它们包含了一个指向了编译时所用Qt库的rpath。
如果这些文件没有设置rpath,在启动它们之前你需要显式地设置LD_LIBRARY_PATH,或写一个替你做这些事情的脚本。由于LD_LIBRARY_PATH是一个环境变量,它也有自身的一些问题。
很不幸的是:在基于glibc的系统中,动态加载器的搜索路径有些混乱。尤其是在RPATH和RUNPATH二者的区别上。这方面的文档非常匮乏: Google给出的第一个结果 是不正确的,可能只是过时了。ld和ld.so的man页面是不完整的,而且dlopen中对 RUNPATH如何起作用的描述是错的 。 Debain Wiki 一开始说得不错,但是和dlopen页面有同样的错误,而且后面有些自相矛盾。
另一个混乱的来源是:根据你的发行版的不同,“ld”的-rpath参数表现出不同的行为。在一些发行版中生成DT_RPATH,而在另外一些发行版中却同时生成DT_RPATH和DT_RUNPATH。
好的,这并不严重,但问题是什么呢?
简单地说:在你的应用程序中设置DT_RUNPATH(或者DT_RUNPATH和DT_RPATH)并不足以保证它链接到你所指定目录中的库。
一个导致问题的具体例子:
- Qt Creator链接到它自带的QtGui
- 它通过dlopen加载了系统提供的KDE插件,该插件(间接)依赖QtDBus
- 如果Qt Creator的二进制程序设置了RPATH而没有RUNPATH:Qt Creator自带QtDBus被加载
- 如果Qt Creator的二进制程序设置了RUNPATH:系统提供的QtDBus被加载且导致Qt Creator终止。
该错误将会类似这样“Cannot mix incompatible Qt library (version 473) with this library (version 474)”[不能将当前库(版本474)与不兼容的Qt库(版本473)混用]。因为即使版本间是二进制兼容的,你也不能混用它们。QtDBus可能会依赖QtCore中已经发生变化或者在4.7.4中新增的私有API。
对于所有的链接到自有QtGui库且运行在带有KDE的系统上的应用程序,都可能发生这种问题。但是该问题也并不局限于KDE:任何使用了先前未加载的Qt库的插件,都可能查找到错误的库。
为什么会这种情况?
实验以及对glibc源码(elf/dl-load.c中的_dl_map_object)阅读表明,库的搜索顺序如下:
除非正被加载的对象(object)拥有RUNPATH:
正被加载对象的RPATH,
然后是其加载者(loader)的RPATH(除非它有RUNPATH),...,
直到搜索链的结束,它要么是可执行程序,
要么是通过dlopen加载的对象
除非可执行程序拥有RUNPATH:
该可执行程序的RPATH
LD_LIBRARY_PATH
正被加载对象的RUNPATH
ld.so.cache
默认路径
该过程解释了这种行为:我们依赖于插件加载时检查可执行程序的RPATH。可执行程序的RUNPATH并不被用来查找间接依赖的库。
我们该如何做?
当你发布二进制(程序)时,要么使用RPATH且不使用RUNPATH,要么确保LD_LIBRARY_PATH在运行前被设置。当你在“ld”默认是–enable-new-dtags(因此-rpath会添加RUNPATH)的系统中构建Qt时,要明白一点:在启动使用该版本Qt构建的程序时,你可能必须要先设置LD_LIBRARY_PATH。
RPATH与RUNPATH的更多相关文章
- rpath 与runpath
- linux动态库加载RPATH, RUNPATH
摘自http://gotowqj.iteye.com/blog/1926771 linux动态库加载RPATH, RUNPATH 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共 ...
- 探讨CMake中关于RPATH的使用
最近研究CMake,发现CMake对于RPATH的管理也非常人性化.官方说法是当动态库的编译也和执行档在同级目录下的时候,CMake会自动给执行档加入适当的RPATH.具体可以通过readelf -d ...
- linux动态库加载的秘密
摘自http://gotowqj.iteye.com/blog/1926734 摘自http://www.360doc.com/content/14/0313/13/12747488_36024641 ...
- 高级C/C++编译技术之读书笔记(四)之定位库文件
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- 通过一道简单的例题了解Linux内核PWN
写在前面 这篇文章目的在于简单介绍内核PWN题,揭开内核的神秘面纱.背后的知识点包含Linux驱动和内核源码,学习路线非常陡峭.也就是说,会一道Linux内核PWN需要非常多的铺垫知识,如果要学习可以 ...
- MacOS平台下@rpath在动态链接库中的应用
一.背景介绍 公司开发的一个底层库被用在了Mac平台的多个产品中.在开发这个底层库的初期,对于Mac OSX下的Install name 并没有过多的了解.对于XCode中的install name项 ...
- @rpath/libswiftCore.dylib问题
dyld: Library not loaded: @rpath/libswiftCore.dylib Referenced from: /private/var/containers/Bundle ...
- Objective-C @executable_path、@loader_path和@rpath
工程配置中,有三个路径和库的加载息息相关: 1.@executable_path 可执行文件的路径,例如/Applications/WeChat.app/Contents/MacOS. 2.@load ...
随机推荐
- UESTC_男神的礼物 2015 UESTC Training for Dynamic Programming<Problem A>
A - 男神的礼物 Time Limit: 3000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- RBF径向基神经网络——乳腺癌医学诊断建模
案例描述 近年来疾病早期诊断越来越受到医学专家的重视,从而产生了各种疾病诊断的新方法.乳癌最早的表现是患乳出现单发的.无痛性并呈进行性生长的小肿块.肿块位于外上象限最多见,其次是乳头.乳晕区和内上象限 ...
- [置顶] think in java interview番外篇-谈程序员如何修练英语
一.程序员对英语能力的重视度和能力要求应该是在各行各业中排在比较靠前的 这样说吧,英语程度的好坏直接影响着一个程序员的编程.开发.创新能力. 道理很简单: 1. 计算机和软件是用英语创造出来的 2. ...
- 今日成长笔记2016-11-18 - 关于java开发
好久没有写今日成长笔记了,要记得上一次写笔记还是2016-09-05,今天心血来潮,写一写最近发生在自己身上的事情,以后我要坚持每天写日记.我承认自己身上的确或多或少的存在不足,现在把它们抛出来,并记 ...
- Beauty of Array(思维)
Beauty of Array Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has an array A with N integ ...
- PCI、PCIE配置空间的訪问(MCFG,Bus,Device,Funtion)
一般来说,在x86平台上,有两大类方式能够訪问这一区间的寄存器, 1,配置机制1#或者配置机制2# 訪问时借助in/out指令.请注意,这样的方式有别于一般的in/out指令訪问PCI的IO空 ...
- android视频录制、另一部手机实时观看方案
最近调研android视频录制.另一部手机实时观看,大致有以下几种思路. 1. android手机充当服务器,使用NanoHTTPD充当服务器,另一部手机或者pc通过输入http://手机的ip:80 ...
- mysql跟踪提交的SQL语句
http://www.cnblogs.com/wuyifu/p/3328024.html
- SQL Server 两种判断表名是否存在且删除的方式
邓老师(老邓)教的 if exists(select * from sysobjects where name='Table_88') drop table Table_88 偷的((*^__^ ...
- 终极解法According to TLD or attribute directive in tag file, attribute select does not accept any expressions
3天硬是是把这个问题解决了 有时候突然上个厕所灵感就来了 第一次向用JSTL解析xml 然后我想遍历整个xml文档打印出来 居然不让我输入变量 那让我怎么办啊 在网上各种找答案 说什么<%@ t ...