linux 找不到动态库
今天碰到一个问题,程序运行时找不到动态库libxxx.so.0。而这个动态库是我们自己写的,所以:
- rpm查看是否装了该rpm包。
- 查看该包动态库装的路径是否在
/etc/ld.so.conf文件中有配置,查看是否有LD_LIBRARY_PATH环境变量。 - ldconfig 更新缓存。
- 运行程序,还是有问题。
最后,看了下我们自己的动态库,装的是libxxx.so,而需要的是libxxx.so.0。如果打包动态库的时候没有指定soname(简单共享名,Short for shared object name)那就需要手动加个软连接。很显然是没有指定,因为如果指定了的话,ldconfig -n . 就会自动生成。
具体看下是否指定了呢?
可以用readelf -d libxxx.so.1.0.1 命令看下,如果有SONAME这一行,说明是指定了的。没有则没有指定。
Dynamic section at offset 0x670 contains 21 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libxxx.so.0]
0x000000000000000c (INIT) 0x468
0x000000000000000d (FINI) 0x5d8
那么,明明有libxxx.so 我什么要找libxxx.so.0呢? 看下程序依赖的动态库,是libxxx.so.0 not found。
ldd xxx
linux-vdso.so.1 => (0x00007fff73bbb000)
libxxx.so.0 => not found
可以说,程序在编译的时候就确定让调用libxxx.so.0。看下程序编译时候的选项,也只能指定xxx呀-lxxx呀。我什么编译后的动态库需要libxxx.so.0,理论上应该是libxxx.so呀。猫腻在这个动态库,这个动态库指定了noname。让我们做个测试:
$ more hello.*
::::::::::::::
hello.c
::::::::::::::
#include <stdio.h>
#include "hello.h"
void hello(const char *s) {
printf("%s\n", s);
}
::::::::::::::
hello.h
::::::::::::::
void hello(const char *s);
编译,编译后也可以readelf -d libhello.so.1.0.1 看下。
gcc -fPIC -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0.1 hello.c
测试用例:
$ more test.c
#include <stdio.h>
#include "hello.h"
void main(void) {
char *s = "hello liwq";
hello(s);
return;
}
编译:
gcc -L./ -lhello -o test test.c
会报错:/usr/bin/ld: cannot find -lhello,因为-l指定的是hello,只能会找libhello.so。所以需要添加个软链接$ ln -s libhello.so.1.0.1 libhello.so
ldd test 看下,libhello.so.1 => not found 就是动态库的soname。
请问一下这个问题的正解应该是怎么样的?