网站搜索

了解 Linux 中的共享库


在编程中,库是可以在程序中重用的预编译代码片段的集合。库简化了程序员的生活,因为它们提供了可重用的函数、例程、类、数据结构等(由另一个程序员编写),他们可以在自己的程序中使用它们。

例如,如果您正在构建需要执行数学运算的应用程序,则不必为此创建新的数学函数,只需使用该编程语言的库中的现有函数即可。

Linux 中的库示例包括 libc(标准 C 库)或 Glibc(标准 C 库的 GNU 版本)、libcurl(多协议文件)传输库)、libcrypt(C 中用于加密、散列和编码的库)等等。

Linux 支持两类库,即:

  • 静态库——在编译时静态地绑定到程序。
  • 动态或共享库 – 在程序启动时加载并加载到内存中,并在运行时发生绑定。

动态或共享库可以进一步分类为:

  • 动态链接库 - 这里程序与共享库链接,内核在执行时加载该库(如果它不在内存中)。
  • 动态加载库 - 程序通过调用库函数来完全控制。

共享库命名约定

共享库有两种命名方式:库名称(又名 soname)和“文件名”(存储库代码的文件的绝对路径)。

例如,libcsonamelibc.so.6:其中 lib 是前缀, >c 是一个描述性名称,因此表示共享对象,6 是版本。它的文件名是:/lib64/libc.so.6。请注意,soname 实际上是文件名的符号链接。

在 Linux 中查找共享库

共享库由ld.so(或ld.so.x)和ld-linux.so(或ld- linux.so.x)程序,其中x是版本。在 Linux 中,/lib/ld-linux.so.x 搜索并加载程序使用的所有共享库。

程序可以使用库名称或文件名来调用库,库路径存储可以在文件系统中找到库的目录。默认情况下,库位于 /usr/local/lib/usr/local/lib64/usr/lib /usr/lib64;系统启动库位于/lib/lib64中。但是,程序员可以在自定义位置安装库。

库路径可以在 /etc/ld.so.conf 文件中定义,您可以使用命令行编辑器进行编辑。

vi /etc/ld.so.conf 

该文件中的行指示内核加载 /etc/ld.so.conf.d 中的文件。这样,包维护者或程序员可以将他们的自定义库目录添加到搜索列表中。

如果您查看 /etc/ld.so.conf.d 目录,您将看到一些常见软件包(kernel、mysql 和 postgresql)的 .conf 文件这个案例):

ls /etc/ld.so.conf.d

kernel-2.6.32-358.18.1.el6.x86_64.conf  kernel-2.6.32-696.1.1.el6.x86_64.conf  mariadb-x86_64.conf
kernel-2.6.32-642.6.2.el6.x86_64.conf   kernel-2.6.32-696.6.3.el6.x86_64.conf  postgresql-pgdg-libs.conf

如果您查看 mariadb-x86_64.conf,您将看到包库的绝对路径。

cat mariadb-x86_64.conf

/usr/lib64/mysql

上述方法永久设置库路径。要临时设置它,请在命令行上使用LD_LIBRARY_PATH环境变量。如果您想永久保留更改,请在 shell 初始化文件 /etc/profile(全局)或 ~/.profile(特定于用户)中添加此行。

export LD_LIBRARY_PATH=/path/to/library/file

在 Linux 中管理共享库

现在让我们看看如何处理共享库。要获取二进制文件的所有共享库依赖项的列表,您可以使用ldd 实用程序ldd 的输出格式如下:

library name =>  filename (some hexadecimal value)
OR
filename (some hexadecimal value)  #this is shown when library name can’t be read

此命令显示 ls 命令的所有共享库依赖项。

ldd /usr/bin/ls
OR
ldd /bin/ls
样本输出
	linux-vdso.so.1 =>  (0x00007ffebf9c2000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003b71e00000)
	librt.so.1 => /lib64/librt.so.1 (0x0000003b71600000)
	libcap.so.2 => /lib64/libcap.so.2 (0x0000003b76a00000)
	libacl.so.1 => /lib64/libacl.so.1 (0x0000003b75e00000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003b70600000)
	libdl.so.2 => /lib64/libdl.so.2 (0x0000003b70a00000)
	/lib64/ld-linux-x86-64.so.2 (0x0000561abfc09000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003b70e00000)
	libattr.so.1 => /lib64/libattr.so.1 (0x0000003b75600000)

由于共享库可以存在于许多不同的目录中,因此在启动程序时搜索所有这些目录的效率将非常低:这可能是动态库的缺点之一。因此,采用了由程序ldconfig执行的缓存机制。

默认情况下,ldconfig读取/etc/ld.so.conf的内容,在动态链接目录中创建适当的符号链接,然后将缓存写入 >/etc/ld.so.cache 然后很容易被其他程序使用。

这非常重要,尤其是当您刚刚安装新的共享库或创建自己的共享库或创建新的库目录时。您需要运行ldconfig命令才能使更改生效。

ldconfig
OR
ldconfig -v 	#shows files and directories it works with

创建共享库后,您需要安装它。您可以将其移动到上述任何标准目录中并运行ldconfig命令。

或者,运行以下命令创建从 soname 到文件名的符号链接:

ldconfig -n /path/to/your/shared/libraries

要开始创建您自己的库,请查看 Linux 文档项目 (TLDP) 中的本指南。

目前为止就这样了!在本文中,我们向您介绍了库并解释了共享库,以及如何在 Linux 中管理它们。如果您有任何疑问或其他想法要分享,请使用下面的评论表。