在Linux上如何确定共享库的依赖路径?

14
当我使用ldd命令运行共享库(例如libphp5.so)时,我看到它有一个对libmysqlclient.so.16的依赖项:

$ ldd ./libphp5.so
libmysqlclient.so.16 => /usr/lib/mysql/libmysqlclient.so.16 
[其他依赖项已省略]

这些依赖项文件名和路径(/usr/lib/mysql/libmysqlclient.so.16)是否嵌入到了共享库二进制文件中?或者这个路径是通过其他方式确定的,比如通过/etc/ld.so.conf.d/mysql-i386.conf,该文件包含以下内容:

/usr/lib/mysql/

还有一件事让我感到困惑:

我有一个共享库,我从源代码编译而来。这个库依赖于 libmysqlclient_r。gcc编译器用来生成这个库的开关看起来像:

gcc -shared -L/usr/lib/mysql -lmysqlclient_r [+各种其他开关]

当我执行 ldd mylib.so 时,我看到:

libmysqlclient_r.so.16 => /usr/lib/mysql/libmysqlclient_r.so.16 (0x0055c000)

然而在 /usr/lib/mysql 目录下,我看到:

-rwxr-xr-x. libmysqlclient_r.so -> libmysqlclient_r.so.16.0.0
lrwxrwxrwx. libmysqlclient_r.so.16 -> libmysqlclient_r.so.16.0.0
-rwxr-xr-x. libmysqlclient_r.so.16.0.0
lrwxrwxrwx. libmysqlclient.so -> libmysqlclient.so.16.0.0
lrwxrwxrwx. libmysqlclient.so.16 -> libmysqlclient.so.16.0.0
-rwxr-xr-x. libmysqlclient.so.16.0.0

libmysqlclient_r.so 是指向 libmysqlclient_r.so.16.0.0 的符号链接,那么为什么 ldd 显示依赖关系为 libmysqlclient_r.so.16?我是否错过了一些黑科技?

作为一个多年的Windows开发人员,我对gcc和在Linux上进行开发还比较新。

我的Linux发行版是CentOS 6.0 x86-32bit。

2个回答

15

通过运行此命令,您可以看到来自哪里的路径:

LD_DEBUG=libs ldd ./libphp5.so

这些依赖项的文件名和路径(例如/usr/lib/mysql/libmysqlclient.so.16)是否在共享库二进制文件中?

文件名几乎肯定是固定的,但路径通常不是。你可以通过以下命令查看二进制文件中包含的内容:

readelf -d ./libphp5.so

查找(NEEDED)(RPATH)条目。

同时阅读man ld.so。有许多因素会影响动态加载器如何搜索共享库:包括ld.so.confLD_LIBRARY_PATH、可执行文件是否具有suid权限、glibc的配置方式、链接时给出的-rpath设置等等。


你不知道,但我希望我可以给这个问题更多的赞。我的问题源于无法加载Python奶酪商店包(MySQL-Python)中使用的libmysqlclient_r,尽管它编译/构建得非常好。 LD_DEBUG = libs ldd是我的救命稻草。事实证明,在/etc/ld.co.conf.d中保存的路径文件没有以.conf结尾,而我的/etc/ld.so.conf文件指定:include ld.so.conf.d/*.conf。因此,/usr/lib/mysql文件夹从未被搜索过。 - Kev

1
这些依赖文件名和路径(/usr/lib/mysql/libmysqlclient.so.16)是否嵌入到共享库二进制文件中?
是的,它们可以并且经常被嵌入其中。关键字在于-rpath。然而,ld.conf也有发言权。整个系统非常复杂,不幸的是。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接