Linux添加相对库路径,Linux C编程(8) 使用相对路径加载动态库-rpath和$ORIGIN
商业程序如何加载自己的so
使用LD_LIBRARY_PATH的缺点是要实现设置LD_LIBRARY_PATH。不够自动化。那么大型的商业程序是如何加载自己的so呢。
这里以QtCreator为例。
QtCreator安装在/home/xxx/Qt5.3.1目录下。使用ldd查看qtcreator依赖的so。结果如下:
xxx@ubuntu:~/Qt5.3.1/Tools/QtCreator/bin$ ldd qtcreator
linux-gate.so.1 => (0xb7701000)
libExtensionSystem.so.1 => /home/xxx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/libExtensionSystem.so.1 (0xb76c2000)
libQt5Widgets.so.5 => /home/xxx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/libQt5Widgets.so.5 (0xb707e000)
libQt5Network.so.5 => /home/xxx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/libQt5Network.so.5 (0xb6f19000)
libQt5Gui.so.5 => /home/xxx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/libQt5Gui.so.5 (0xb69d8000)
libQt5Core.so.5 => /home/xxx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/libQt5Core.so.5 (0xb649d000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb646b000)
libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb6382000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb6364000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb61b6000)
libgobject-2.0.so.0 => /usr/lib/i386-linux-gnu/libgobject-2.0.so.0 (0xb6164000)
libglib-2.0.so.0 => /lib/i386-linux-gnu/libglib-2.0.so.0 (0xb6058000)
libX11.so.6 => /usr/lib/i386-linux-gnu/libX11.so.6 (0xb5f24000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb5edd000)
libGL.so.1 => /usr/lib/i386-linux-gnu/mesa/libGL.so.1 (0xb5e7d000)
libicui18n.so.52 => /home/xx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/./libicui18n.so.52 (0xb5c53000)
libicuuc.so.52 => /home/xxx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/./libicuuc.so.52 (0xb5ad7000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb5ad2000)
libgthread-2.0.so.0 => /usr/lib/i386-linux-gnu/libgthread-2.0.so.0 (0xb5ace000)
librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0xb5ac5000)
/lib/ld-linux.so.2 (0xb7702000)
libffi.so.6 => /usr/lib/i386-linux-gnu/libffi.so.6 (0xb5abe000)
libpcre.so.3 => /lib/i386-linux-gnu/libpcre.so.3 (0xb5a80000)
libxcb.so.1 => /usr/lib/i386-linux-gnu/libxcb.so.1 (0xb5a5e000)
libglapi.so.0 => /usr/lib/i386-linux-gnu/libglapi.so.0 (0xb5a45000)
libXext.so.6 => /usr/lib/i386-linux-gnu/libXext.so.6 (0xb5a32000)
libXdamage.so.1 => /usr/lib/i386-linux-gnu/libXdamage.so.1 (0xb5a2e000)
libXfixes.so.3 => /usr/lib/i386-linux-gnu/libXfixes.so.3 (0xb5a28000)
libX11-xcb.so.1 => /usr/lib/i386-linux-gnu/libX11-xcb.so.1 (0xb5a25000)
libxcb-glx.so.0 => /usr/lib/i386-linux-gnu/libxcb-glx.so.0 (0xb5a0c000)
libxcb-dri2.so.0 => /usr/lib/i386-linux-gnu/libxcb-dri2.so.0 (0xb5a06000)
libxcb-dri3.so.0 => /usr/lib/i386-linux-gnu/libxcb-dri3.so.0 (0xb5a02000)
libxcb-present.so.0 => /usr/lib/i386-linux-gnu/libxcb-present.so.0 (0xb59fe000)
libxcb-sync.so.1 => /usr/lib/i386-linux-gnu/libxcb-sync.so.1 (0xb59f7000)
libxshmfence.so.1 => /usr/lib/i386-linux-gnu/libxshmfence.so.1 (0xb59f3000)
libXxf86vm.so.1 => /usr/lib/i386-linux-gnu/libXxf86vm.so.1 (0xb59ed000)
libdrm.so.2 => /usr/lib/i386-linux-gnu/libdrm.so.2 (0xb59df000)
libicudata.so.52 => /home/xxx/Qt5.3.1/Tools/QtCreator/bin/./../lib/qtcreator/././libicudata.so.52 (0xb4373000)
libXau.so.6 => /usr/lib/i386-linux-gnu/libXau.so.6 (0xb436e000)
libXdmcp.so.6 => /usr/lib/i386-linux-gnu/libXdmcp.so.6 (0xb4367000)
在看一下本身直接加载的动态库:
xxx@ubuntu:~/Qt5.3.1/Tools/QtCreator/bin$ readelf --dynamic qtcreator
Dynamic section at offset 0x11eb0 contains 30 entries:
标记 类型 名称/值
0x00000001 (NEEDED) 共享库:[libExtensionSystem.so.1]
0x00000001 (NEEDED) 共享库:[libQt5Widgets.so.5]
0x00000001 (NEEDED) 共享库:[libQt5Network.so.5]
0x00000001 (NEEDED) 共享库:[libQt5Gui.so.5]
0x00000001 (NEEDED) 共享库:[libQt5Core.so.5]
0x00000001 (NEEDED) 共享库:[libpthread.so.0]
0x00000001 (NEEDED) 共享库:[libstdc++.so.6]
0x00000001 (NEEDED) 共享库:[libgcc_s.so.1]
0x00000001 (NEEDED) 共享库:[libc.so.6]
0x0000000f (RPATH) Library rpath: [$ORIGIN/../lib/qtcreator]
秘密就在这句:0x0000000f (RPATH) Library rpath: [$ORIGIN/../lib/qtcreator]
rpath与ORIGIN
rpath是gcc的一个参数。rpath添加一个目录。当程序被加载时,搜寻此目录,寻找动态库。rpath添加的目录信息保存在可执行文件中。即使这句
0x0000000f (RPATH) Library rpath: [xxx]。
现在的问题是,可执行文件如何知道自身所在目录。
ORIGIN变量代表了此目录。关于ORIGIN更详细的信息,可参考此文档。
例子
例子目录结构如下
src
…main.c
…Makefile
…lib/foo.c
操作系统:ubuntu 14 32位
编译i:gcc 4.8
main.c文件源码
void test_tk();
int main(void)
{
test_tk();
return 0;
}
Makefile文件内容
main:main.c lib/libfoo.so
gcc -L${shell pwd}/lib -g -Wall -o test -Wl,-rpath,'$$ORIGIN/lib' main.c -lfoo
lib/libfoo.so:lib/foo.c
gcc -g -Wall -fPIC -shared -o lib/libfoo.so lib/foo.c
foo.c文件源码
#include
void test_tk()
{
printf("called!\n");
}
编译,生成test可执行文件。
执行readelf –dynamic test 来看加载的动态库。
Dynamic section at offset 0xf04 contains 26 entries:
标记 类型 名称/值
0x00000001 (NEEDED) 共享库:[libfoo.so]
0x00000001 (NEEDED) 共享库:[libc.so.6]
0x0000000f (RPATH) Library rpath: [$ORIGIN/lib]
..........................................................
运行test。执行结果位
called!
可以讲src拷贝到其他目录试试。发现程序也可以正常运行。
Linux添加相对库路径,Linux C编程(8) 使用相对路径加载动态库-rpath和$ORIGIN相关推荐
- Linux系统程序运行时加载动态库路径顺序
程序运行时加载动态库路径顺序(Linux) 在linux系统中,如果程序需要加载动态库,它会按照一定的顺序(优先级)去查找: 链接时路径(Link-time path)和运行时路径(Run-time ...
- linux直接运行程序加载动态库失败,扣丁学堂Linux培训详解程序运行时加载动态库失败解决方法...
今天扣丁学堂Linux培训老师给大家介绍一下关于Linux程序运行时加载动态库失败的解决方法,希望对同学们学习有所帮助,下面我们一起来看一下吧. Linux下不能加载动态库问题 当出现下边异常情况 . ...
- linux加载动态库问题
当我们在linux系统引用动态库时,经常会遇到一个问题,加入我们需要的动态库没有在系统的默认目录下,我们编译时使用-L指定了动态库的路径,编译时没有问题,但是执行调用该动态库的可执行文件时,却提示找不 ...
- linux平台 加载动态库dlsym返回null
linux 平台加载动态库通常使用dlopen,dlsym,dlclose三个函数实现 最近写了一个小程序,遇到dlsym总是调用失败返回空值,查找了很多相关的资料,确定动态库的创建有问题.下面是最初 ...
- sunPKCS11加载动态库(转)
sunPKCS11加载动态库(转) http://www.cnblogs.com/sunfb/archive/2013/03/01/2938491.html 这篇文章不介绍具体的编程方法,而是针对PK ...
- tableview动态修改和删除_Ubuntu加载动态库失败的解决方案
在ubuntu下代码编译通过的情况下,经常出现运行时加载动态库出错的情况.这些问题很琐碎,不具备任何技术含量,纯属耽误时间,这也是linux系统的通病,花里胡哨,故弄玄虚. 为了减少初学者在这种无意义 ...
- php无法加载dll插件,php无法加载动态库怎么办
php无法加载动态库的解决办法:1.将PHP的集成包里的"libmySQL.dll"复制到system32目录下:2.将PHP的解压目录添加到PATH里:3.在Apache的配置文 ...
- 使用Poco实现插件方式加载动态库
动态库封装虚基类 //AbstractPlugin.h #ifndef __ABSTRACTPLUGIN_H__ #define __ABSTRACTPLUGIN_H__#include <st ...
- 加载动态库失败(loadLibrary返回为空)的几种解决办法
如果遇到了以下几种问题,也许可以在本文找到解决方法: 一.版本更新后,原本正常的功能突然无法使用了: 二.VS编译的时候,弹出"xxx(win32):已加载"xx.dll" ...
- LoadLibrary加载动态库失败
[1]LoadLibrary加载动态库失败的可能原因以及解决方案: (1)dll动态库文件路径不对.此场景细分为以下几种情况: 1.1 文件路径的确错误.比如:本来欲加载的是A文件夹下的动态库a.dl ...
最新文章
- 快速理解VirtualBox的四种网络连接方式
- .NET3.0已经Pre-release了
- python软件是哪个国家的品牌_有哪些好用的软件被国人误认为是外国研发的?
- IntelliJ IDEA + Maven环境编写第一个hadoop程序
- go设置后端启动_开源一个go的H5游戏服务端开发框架
- LeetCode OJ - Longest Substring Without Repeating Characters
- 金鹏GB28181平台对接
- Element UI踩坑记 —— el-table中 formatter 的属性居然失效了
- linux删除用户名命令,linux删除用户命令
- miui8 android.policy,小米MIUI8系统调教记:轻快好省 畅爽静稳
- MKS_SGEN_L V1.0 marlin 固件编译
- DZS-115/DC110V中间继电器
- xml解析之dom、dom4j、SAX
- 营养学和计算机交叉,营养配餐系统综述
- 网关系统就该这么设计,万能通用,稳的一批!
- Linux下实现苹果AirPlay音频服务器
- Stereogram(极射赤面)投影--主要用于中高纬和极区的天气图
- 【时空序列】AAAI2021| 利用时空融合图神经网络进行交通流量预测
- 在打破传统保险业的“玻璃屋顶” 之前,AI+保险还需跨过几道坎
- 蓝桥杯 — IAP15F2K61S2-89C52 转换板说明文件
热门文章
- linux 查看新增文件夹记录_微信7.0.23测试版,新增查看访客记录,朋友圈内容能折叠?...
- DQL——数据查询语言
- linux源代码剖析之二boot
- Linux命令解释之groupadd,groupdel,groupmod,groupmems
- ip8plus多重_【苹果 iPhone 8 Plus 手机使用总结】容量|处理器|手感_摘要频道_什么值得买...
- redmin3 忘记管理密码找回方法
- tipask mysql调取dedecms_如何实现dedecms外部数据库调用
- 发的楷体怎么写_孩子作业实在写不完,父母该怎么办?我直接给老师发信息
- 安装ISE.14.7后仿真时遇到的问题与解决
- 微信快速开发框架(五)-- 利用快速开发框架,快速搭建微信浏览博客园首页文章...