目录

  • 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 对于共享库版本管理的灵活性使用最适合的共享库。

《手把手教你构建自己的 Linux 系统》学习笔记(7)的更多相关文章

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

    目录 /etc/fstab 文件的作用是什么? Linux 内核的图形化启动是怎么回事? Linux 系统中的文件名是否以大小写来进行区别? 「GRUB 中无法找到硬盘」怎么解决? 「GRUB 及配置 ...

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

    目录 autoreconf 命令的作用是什么? aclocal automake -a autoconf 一条命令搞完三面三步 既然有其他的「编译控制软件」为何还是使用 make 来进行编译控制? M ...

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

    目录 Binutils 软件包有什么用? make -k 的作用是什么? man-pages 里有几种文档?分别表示什么意思? 如何查询指定目录的 man-pages ? 如何使用 make 命令的同 ...

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

    目录 /dev 目录是干什么的? /proc 和 /sys 目录是干什么的? udev 这个软件是干什么用的? 目录映射是临时性的,还是永久性的? 命令行里大括号 "{}" 的作用 ...

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

    交叉编译是什么? 交叉编译就是在一个系统上,编译生成另外一个系统运行的程序文件. 「硬件体系结构」和「操作系统」的关系是什么? 硬件体系结构也可以称为架构,主要是通过 CPU 的指令集来进行区分的,操 ...

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

    Linux 系统定制原理 虚拟根目录 我们的目标是为了完成目标系统(也就是我们要做的系统),他是一个可以独立运行的系统,不依赖雨主系统和临时系统,根据 Linux 系统的特点它需要存放在根目录下面,但 ...

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

    第二章.基础准备--Linux 系统定制原理 Linux 系统的组成及架构 共享库和静态库 在 Linux 系统中,函数库包含两种形式:共享库和静态库. 共享库 共享库在程序运行时,为其提供所需要的函 ...

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

    汇编链接器(Binutils) 这是一个软件包,这个软件包其实是一个工具集,里面含有了大量的用于汇编程序活着读取二进制文件相关的程序. CC 它是一条命令的别名,这条命令的作用是使用 GCC 的 C ...

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

    需要注意的是,制作操作系统权限全程都要用 root pushd 和 popd 为了方便目录管理,所以出现了这种两个命令,他们的原理就是利用堆栈来实现目录管理. 这两个命令,pushd 负责将指定的目录 ...

随机推荐

  1. 简单的在jsp页面操作mysql

    ---恢复内容开始--- 上一篇讲了在DOS界面下操作mysql 现在我们来说说怎么在jsp页面中操作mysql 要用jsp页面操作mysql需要jdbc(不是非要jdbc,还有其他的) 下载地址:w ...

  2. crtmpserver服务器的搭建

    https://blog.csdn.net/wutong_login/article/details/7612477 https://www.cnblogs.com/wangqiguo/p/60145 ...

  3. java容器(二) Map类框架图解

  4. npm、node版本升级与淘宝镜像

            npm --version  ==   npm -v       查看npm版本            node -v  查看node版本         升级npm版本   npm  ...

  5. python 内置模块之ConfigParser--配置读写

    用于对特定的配置进行操作,当前模块的名称在 python 3.x 版本中变更为 configparser. #配置文件test.cfg [section1] k1 = v1 k2 :v2 k3 = 1 ...

  6. ncbi-blast 本地安装

    详见:http://blog.shenwei.me/local-blast-installation/ Linux系统中NCBI BLAST+本地化教程 本文面向初学者(最好还是懂得基本的linux使 ...

  7. 用MYSQL的存储过程创建百万级测试数据表

    创建随机字符串函数,便于创建名称 DROP function if EXISTS rand_string; #创建一个指定字符个数的函数 create function rand_string(n I ...

  8. 最大流-前置push-relabel算法实现

    Front Push-Relabel Algorithm 接口定义 Input:容量数组vector<vector<int>> capacity ,大小为n:源点int sou ...

  9. 第3章 JDK并发包(三)

    3.2 线程复用:线程池 一种最为简单的线程创建和回收的方法类似如下代码: new Thread(new Runnable() { @Override public void run() { // d ...

  10. 1.3.4分析你的第一个Android程序——Android第一行代码(第二版)笔记

    切换项目结构模式 Project模式的项目结构 我们将项目切换成Project模式,这就是真实的目录结构. .gradle和.idea 这两个目下放置的都是Android Studio自动生成的一些文 ...