基本原理
-L
编译选项是编译期间使用
LD_LIBRARY_PATH
环境变量是运行期间使用,可以用来指定so的加载路径,并且优先级高于系统默认的。
RPATH
和RUNPATH
是ELF格式里面的一个数据,rpath
编译选项实际上是在可执行文件中加入了RUNPATH
或者RPATH
。
小结一下一个ELF文件自身加载so的情况(不可信,仅供参考):
其实这三者的关系概括起来没有几点:
LD_LIBRARY_PATH
是个环境变量,优先级高于系统默认的。RPATH
是ELF格式里面的一个数据,他的优先级比LD_LIBRARY_PATH
还要高RUNPATH
很特殊,如果他出现了RPATH
就躲起来了,LD_LIBRARY_PATH
又成了首选??
ELF 中 RPATH | ELF 中 RUNPATH | LD_LIBRARY_PATH 变量 | 尝试加载目录的顺序 |
---|---|---|---|
未设置 | 未设置 | 未设置 | /lib => /usr/lib |
未设置 | 未设置 | 设置 | ${LD_LIBRARY_PATH} => /lib => /usr/lib |
设置 | 未设置 | 未设置 | ${RPATH} => /lib => /usr/lib |
设置 | 未设置 | 设置 | ${RPATH} => ${LD_LIBRARY_PATH} => /lib => /usr/lib |
设置 或 未设置 | 设置 | 设置 | ${LD_LIBRARY_PATH} => ${RUN_PATH} => /lib => /usr/lib |
设置 或 未设置 | 设置 | 未设置 | ${RUN_PATH} => /lib => /usr/lib |
LD_LIBRARY_PATH 例子
// a.c
#include <stdio.h>
extern void test_b();
void test_a()
{
test_b();
}
int main()
{
test_a();
return 0;
}
// b.c
#include <stdio.h>
void test_b()
{
}
root@ubuntu:/usr1/tmp/2# gcc b.c -shared -fPIC -o lib/libmyb.so
root@ubuntu:/usr1/tmp/2# gcc -o a a.c -Llib -lmyb
root@ubuntu:/usr1/tmp/2#
root@ubuntu:/usr1/tmp/2# ./a
./a: error while loading shared libraries: libmyb.so: cannot open shared object file: No such file or directory
root@ubuntu:/usr1/tmp/2#
root@ubuntu:/usr1/tmp/2# export LD_LIBRARY_PATH=lib
root@ubuntu:/usr1/tmp/2# ./a
root@ubuntu:/usr1/tmp/2#
root@ubuntu:/usr1/tmp/2# tree
RPATH和RUNPATH 例子
// a.c
#include <stdio.h>
extern void test_b();
void test_a()
{
test_b();
}
int main()
{
test_a();
return 0;
}
// b1.c, b2.c
#include <stdio.h>
void test_b()
{
printf("test_b in: %s\n", __FILE__);
}
unset LD_LIBRARY_PATH
gcc b1.c -shared -fPIC -o lib1/libmyb.so
gcc b2.c -shared -fPIC -o lib2/libmyb.so
gcc -o a a.c -Llib1 -lmyb -Wl,-rpath=lib2
tree
ldd ./a
readelf -d ./a | grep PATH
export LD_LIBRARY_PATH=lib1
ldd ./a
readelf -d ./a | grep PATH
参考文档
RPATH和RUNPATH区别 - 简书 (jianshu.com)
RPATH RUNPATH 和 LD_LIBRARY_PATH_pkpkpk的专栏-CSDN博客
标签:LD,lib,路径,LIBRARY,搜索,设置,test,PATH,共享 From: https://www.cnblogs.com/devin1024/p/17489916.html