这个问题是实际工作中遇到,不过为了便于描述作了些改变,就不使用工作中用到的库名,c文件名……
本次问题会用到的文件:
1.libtest.so #动态库文件
2.main.c #动态库中函数调用点
编译:
gcc libtest.so main.c -Wall
运行及错误信息:
env LD_LIBRARY_PATH=. ./a.out
./a.out: error while loading shared libraries: libtest.so.0: cannot open shared object file: No such file or directory
WHY?
为什么会说libtest.so.0而不是libtest.so找不到,编译链接的时候都是libtest.so,可执行文件里面怎么嵌入的是libtest.so.0。
当时的解决方法:
ln -s libtest.so libtest.so.0
引起这个问题的真正原因:
要想明白可执行文件里面为什么没有使用动态库的文件名,就要说明动态库里面一个神奇的属性 SONAME,如果动态库设置了SONAME,那么在静态链接阶段会将 SONAME嵌入到可执行文件中,而不会使用真实文件名称,同时后面的动态链接器
在运行时也会使用这个SONAME来搜索库。
真相大白:
$ objdump -p libtest.so | grep SONAME
SONAME libtest.so.0