《手把手教你构建自己的 Linux 系统》学习笔记(7)

目录

  • tee 命令的缺陷是什么?如何解决这个缺陷?
  • /etc/ld.so.conf 文件的作用是什么?
  • 动态链接和静态链接有什么不同?
  • 动态编译
  • 静态编译
  • 共享库为什么会有版本?共享库的版本升级原理是怎样的?

tee 命令的缺陷是什么?如何解决这个缺陷?

tee 命令只接收标准输入,而如果明林广化寺用了错破五输出则错误输出的内容无法被 tee 接受到,为了让错误信息也能够被记录,我们将标准错误输出重定向到标准输出中,在命令中使用 2>&1 重定向错误输出。

/etc/ld.so.conf 文件的作用是什么?

他的作用只是用于帮助 ld-linux*.so 在程序运行过程中去搜索其他依赖的共享库,编译和链接的构成中 /etc/ld.so.conf 并不参与。

动态链接和静态链接有什么不同?

程序编译时,可以分成两种,一种是静态编译,一种是动态编译。

动态编译

程序编译的时候仅仅编译程序自身的代码,对于需要使用的各种外部函数采用链接到外部共享库的方式,程序运行期间再从共享函数库中运行其中的函数。

该方式编译的程序在运行时所依赖或者提供函数实现的共享库必须存在,有效,且能够被搜索到。

动态编译对于空间的占用比较阶跃,大量的软件使用了相同的库文件,如果用静态编译则每个程序都需要将库文件编译进自己的程序中,这会占用大量的数据空间。使用动态编译只需要编译进函数实现的链接就行了,运行的时候再从库文件里面提取,有效的节省了存储空间。

采用动态编译时,对函数库进行兼容的更新,不需要重新编译程序就可以使用更新过的功能,如果是不兼容的更新则会导致程序无法正常运行,这时只能通过重新编译程序来恢复正常。

静态编译

静态编译不会受到外部函数库文件变更的影响,因此静态编译非常适合将程序移植到内核兼容的不同系统环境中。

静态编译和动态编译各有优点和缺点,使用哪种方式需要根据实际情况来确定,通常使用动态编译的方式来搭建我们的系统,对于一些非常关键的程序我们不希望他的运行状态受到影响,或者希望该程序能够在比较简单的环境中运行,这就适合采用静态编译的方式。

共享库为什么会有版本?共享库的版本升级原理是怎样的?

Linux 中存在大量的共享库,例如 Zlib 软件包就会产生共享库,提供共享库的软件包进行版本升级,其新版本可能提供了新的功能或者提高了原功能的某些方面,这时有可能需要去升级这些共享库。

这时问题就出现了,已经存在的共享库如果已经被其他程序所链接,并且使用了其中的某些特性,新版本中很可能取消了或者改变了这个特性,替换掉共享库则会导致这些程序出现问题。

为了解决这样的问题,共享库的文件名中会带有版本号,例如 Zlib-1.2.2 所提供的共享库文件名是 libz.so.1.2.2 这样就可以在同一个系统下面存在多个共享库的版本,当 Zlib 发布了 1.2.3 版本只要生成的共享库命名为 libz.so.1.2.3

但是这又产生了另外一个问题,绝大部分的函数库升级是向下兼容的,升级一般会给原来的软件带来某些方面的提升(例如性能),这时我们又希望通过只更新共享库的版本就可以让所有相关的程序都能收益。

我i饿了解决上面的矛盾,在系统中一般对共享库采用多级版本管理的方式,利用版本号的大小进行分层控制,大版本链接到低一级版本的文件上。

下面以 Zlib 为例进行讲解。

安装 Zlib-1.2.2 时产生了 libz.so.1.2.2 文件,这时创建一个 libz.so.1 的链接文件指向 libz.so.1.2.2. 再创建一个 libz.so 的链接文件指向 libz.so.1 关系如下:

libz.so -> libz.so.1 -> libz.so.1.2.2

当再安装 Zlib-1.2.3 时,只要安装上 libz.so.1.2.3 并且将 libz.so.1 链接指向 libz.so.1.2.3 就可以了,关系如下:

libz.so -> libz.so.1 -> libz.so.1.2.3
注意,让 libz.so.1 换了一个指向目标,我猜使用这种方法解决是因为,如果没有 libz.so.1 这种类似快捷方式的存在,会导致很多软件直接就写死了共享库的版本号,这样的话,那些软件就无法利用共享库的升级的新功能。

某程序必须某些程序必须使用 libz.so.1.2.2 共享库的功能时,且不希望函数库发声变更,则只需要在一开始编译这个程序的时候使他链接到文件 libz.so.1.2.2 上即可。该文件不会发声变化,当程序链接到文件 libz.so.1 时,则 Zlib 在大版本为 1 的范围内升级会导致这些程序也进行了升级,这些程序所链接的库已经升级为新的 Zlib 了。

假设 Zlib 将来会出现 2.0 版本,就可能产生 libz.so.2.0.0 和 libz.so.2 的文件,这时链接到在 libz.so.1 的程序不会受到影响,而链接到 libz.so 的程序则可以立即享受到 2.0 版本所带来的好处,当然也同时承担着升级的风险。

主意程序链接到哪一个版本级别的共享库是需要更急实际情况来进行决定的,有程序本身的因素也有共享库本身的因素,不能一概而论,可以充分利用 linux 对于共享库版本管理的灵活性使用最适合的共享库。

posted @ 2015-08-18 19:29  0x1D  阅读(1025)  评论(2编辑  收藏  举报