Linux 上的共享库依赖路径是如何确定的?
当我针对 libphp5.so
等共享库运行 ldd
时,我发现它依赖于 libmysqlclient.so.16
:
$ ldd ./libphp5.so libmysqlclient.so.16 => /usr/lib/mysql/libmysqlclient.so.16 [other dependencies snipped out]
这些是依赖文件名和路径(/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 [+various other switches]
当我执行 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。
When I run ldd
against a shared library such as libphp5.so
I see that it has a dependency on libmysqlclient.so.16
:
$ ldd ./libphp5.so libmysqlclient.so.16 => /usr/lib/mysql/libmysqlclient.so.16 [other dependencies snipped out]
Are these dependency filenames and paths (/usr/lib/mysql/libmysqlclient.so.16
) baked into the shared library binary? Or is this path determined by some other means such as via /etc/ld.so.conf.d/mysql-i386.conf
, which incidentally contains:
/usr/lib/mysql/
One other thing is puzzling me:
There is a shared library I have that I compile from source. This has a dependency on libmysqlclient_r
. The gcc
compiler switches to produce this this library look like:
gcc -shared -L/usr/lib/mysql -lmysqlclient_r [+various other switches]
When I do ldd mylib.so
I see:
libmysqlclient_r.so.16 => /usr/lib/mysql/libmysqlclient_r.so.16 (0x0055c000)
However in the /usr/lib/mysql
directory I see:
-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
is a symbolic link to libmysqlclient_r.so.16.0.0
, so why does ldd
show the dependency as libmysqlclient_r.so.16
. Is there some magic I'm missing here?
Having been a Windows dev for many years I'm a bit new to gcc
and development on Linux.
My Linux distribution is CentOS 6.0 x86-32bit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以通过运行查看哪些路径来自哪里
文件名几乎肯定是。路径通常不是。 来查看二进制文件中包含的内容
您可以通过查找
(NEEDED)
和(RPATH)
条目。还请阅读
man ld.so
。有很多因素会影响动态加载器搜索共享库的方式:ld.so.conf
、LD_LIBRARY_PATH
、可执行文件是否是suid
,如何配置 glibc,在链接时给出哪些-rpath
设置,等等。You can see which paths are coming from where by running
The filename almost certainly is. The path usually isn't. You can see what is baked into the binary with
Look for
(NEEDED)
and(RPATH)
entries.Also give
man ld.so
a read. There are many factors that affect how dynamic loader searches for shared libraries:ld.so.conf
,LD_LIBRARY_PATH
, whether the executable issuid
or not, how glibc was configured, which-rpath
settings were given at link time, etc. etc.是的,它们可以而且经常如此。这里的关键字是
-rpath
。然而,ld.conf 也有它的发言权。不幸的是,整个系统非常复杂。Yes, they can be and often are. The keyword here is
-rpath
. However, ld.conf also has its say. The whole system is quite complex, unfortunately.