动态链接库的RPATH和RUNPATH解惑
来源:互联网 发布:淘宝运营费用 编辑:程序博客网 时间:2024/05/01 10:55
最近在使用SPP网络框架进行业务开发的时候,遭遇动态库搜索路径问题,为了避免其他同学继续在这方面浪费精力,简单整理了相关知识点。
【背景知识】
这里不打算深入链接器内部,简明扼要给出链接器进行动态库搜索的一些规则。
以上是man ld结果部分截图,这里着重澄清两个基本概念:"link time"(链接时)和"runtime"(运行时),比如常用的-L选项属于链接时,而-rpath,LD_LIBRARY_PATH都属于运行时。
很多运维同学倾向于使用LD_LIBRARY_PATH,但是个人认为这并不是一种好方法,因为LD_LIBRARY_PATH作用于全局,可能对其他程序造成未预期的影响。有兴趣的同学可以读一读《Why LD_LIBRARY_PATH is bad》,这篇文章有比较全面的分析。
【实践检验】
目录文件:
// main.c#include <dlfcn.h>typedef void (*FuncA)(void);int main(int argc, char *argv[]){ void *plugin = dlopen("./libfunc_a.so", RTLD_LAZY); FuncA func = (FuncA)dlsym(plugin, "FuncA"); func(); return 0;}
// func_a.c#include <stdio.h>void FuncB(void);void FuncA(void){ printf("[%s]%s:%d\n", __FUNCTION__, __FILE__, __LINE__); FuncB();}
// func_b_sys.c// func_b_user.c#include <stdio.h>void FuncB(void){ printf("[%s]%s:%d\n", __FUNCTION__, __FILE__, __LINE__);}
# Makefileall: gcc -g -Wall -fPIC -shared -o libfunc_b_sys.so func_b_sys.c gcc -g -Wall -fPIC -shared -o libfunc_b_user.so func_b_user.c ln -sf /data/warezhou/test/ld/libfunc_b_sys.so /usr/lib64/libfunc_b.so ln -sf /data/warezhou/test/ld/libfunc_b_user.so ./lib/libfunc_b.so gcc -g -Wall -fPIC -shared -o libfunc_a.so func_a.c -lfunc_b gcc -g -Wall -o main main.c -ldl gcc -g -Wall -o main_rpath main.c -ldl -Wl,--rpath=./lib,--disable-new-dtags gcc -g -Wall -o main_rpath_runpath main.c -ldl -Wl,--rpath=./lib,--enable-new-dtagsclean: rm main main_rpath main_rpath_runpath rm -rf *.so rm -rf /usr/lib64/libfunc_b.so rm -rf ./lib/*
实验结果:
【原因分析】
上图关于动态库搜索路径的总结来自qt工程师的blog,有兴趣的同学可以阅读原文。简单来说,当可执行文件同时设置RPATH和RUNPATH时,两者同时失效。
查看SPP源码后,发现Makefile里面没有显式指定disable-new-dtags,而这个选项的默认值是平台相关的,我们公司老的suse默认关闭,而新的tlinux默认开启。所以导致发行包里的可执行文件同时设置了RPATH和RUNPATH,最终导致业务模块.so依赖的第三方.so查找不到。
当然,上述问题,通过设置libfunc_a.so的RPATH也是可以解决问题的,有兴趣的同学可以试一试,因为整个搜索过程是递归向上执行的。
0 0
- 动态链接库的RPATH和RUNPATH解惑
- rpath和runpath的区别
- rpath和runpath的区别
- - RPATH RUNPATH 和 LD_LIBRARY_PATH
- 动态库加载路径之RPATH与RUNPATH(小记)
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- 动态库的链接和链接选项-L,-rpath-link,-rpath
- -L、-rpath和-rpath-link的区别
- GCC链接选项-L,-rpath-link和-rpath
- 关于初学Java的一些注意要点(一)
- 《第2章:线程安全性》一种常见的加锁约定
- 分享WMRNET-IV低功耗水表、燃气表无线扩频抄表系统 - APPCON
- ExtJs之组件(window)
- 无法打开包含文件#include”cxtypes.h”问题————OpenCV笔记
- 动态链接库的RPATH和RUNPATH解惑
- SUSE Install Oracle
- uva 10163 Storage Keepers
- Android学习(22)-实战要点
- ExtJs之列表(grid)
- ORACLE常用数值函数、转换函数、字符串函数
- interface脱耦合和Android当中onclickListener接口浅析
- Roman to Integer - LeetCode
- 使用OpenMP给程序加速