为什么要从源码安装软件

在什么情况之下,我们需要从源代码安装软件呢?我想不外乎这些情形:一种情况是软件放出了新的版本,而所用的发行版并没有及时跟进,这时候,想要尝鲜的话,就非得靠自己不可;另一种情形是不管是软件的开发者,还是现用的系统都没有提供可直接使用的二进制包,而自己又非要使用该软件,那么也需亲自出马才行;当然,还有其他的情形。总而言之,学会从源代码安装软件是一项非常重要的技能。

什么是make 与 configure

make 是一支程序,当执行make 时,make 会在当前目录下寻找 makefile 这个文本文件。 makefile 中定义了源码是如何编译的详细信息,如何调用 gcc对源代码进行编译生成目标文件,如何链接生成可执行文件。

makefile

准备工作

    那么,要如何才能从源代码安装软件呢?首先,你必须要做好为编译源代码所需的准备工作。这包括两个方面:

  1. 编译工具:要将源代码编译成可执行的二进制文件,编译工具必不可少: gcc , g++ , make , autoconfig 等等。在CentOS系列中,可以通过 yum -y groupinstall "Development Tools" 来安装。在 Ubuntu 中,可以从终端中执行 sudo apt-get install build-essential
  2. 编译依赖:除了安装基本的编译工具之外,为了顺利编译源代码,我们也要把该程序所需要的依赖安装好。包含系统提供的库函数, 以及第三方软件的依赖包。在CentOS系列中,可以通过 yum -y install  xxxx   xxxx-devel来安装相应的依赖包。Ubuntu 系统可以通过 sudo apt-get build-dep 命令后跟包名的方式来准备所需的依赖。一般情况下,如果 configure 或者 make 报错,其报错信息都明确的指出缺少依赖,只需按要求做即可。或者把错误信息复制到 google 一下,即可愉快的解决。


源码安装3部曲: ./configure ; make && make install

tar zxvf *.tar.gz 来解包,后者则用 tar jxvf *.tar.bz2。通常情况建议解压到 /usr/local/src 目录: # tar xf *.tar.gz -C /usr/local/src

这一步超级重要!!!

当所有的事情都准备妥当了后,那么让我们来进行源代码编译的三部曲吧。

  1. 配置,建立makefile文件:这是编译源代码的第一步,通过 

./configure

  1.  命令完成。执行此步以便为编译源代码作准备。常用的选项有 

--

  1. prefix=PREFIX,用以指定程序的安装位置。更多的选项可通过 --help
  2. 编译:一旦配置通过,可即刻使用 

make

  1. 安装:如果编译没有问题,那么执行 

make install

需要注意的是:上面的步骤必须一步一步的进行,只要其中的一个步骤无法成功,那么后续就完全没有办法再进行。


管理:目录规划,卸载,升级

  • 源码通常解压到 /usr/local/src 目录
  • 安装时最好安装在 /usr/local 目录
  • 将 软件的 man page 加入 man path 中, 编辑 /etc/man.config ,增加 MANPATH  项。
  • 把软件的 bin 目录加入到 PATH 环境变量, 编辑 /etc/profile.d/xxxx.sh, 增加 export PATH=$PATH:/usr/local/xxx/bin

若是觉得所编译的软件不够适用想要删除,又如何做呢?我们只需转到编译源代码的目录,执行 sudo make uninstall


什么是库?

    以下内容转自:

    库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常

    本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。

    所谓静态、动态是指链接。回顾一下,将一个程序编译成可执行程序的步骤:

centos 源代码编译出操作系统镜像_操作系统


静态库

    之所以成为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。

    试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。静态库特点总结:

l  静态库对函数库的链接是放在编译时期完成的。

l  程序在运行时与函数库再无瓜葛,移植方便。

l  浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

centos 源代码编译出操作系统镜像_静态库_02

Linux静态库命名规则

Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为.a。


动态库

通过上面的介绍发现静态库,容易使用和理解,也达到了代码复用的目的,那为什么还需要动态库呢?

为什么还需要动态库?

为什么需要动态库,其实也是静态库的特点导致。

l  空间浪费是静态库的一个问题。

centos 源代码编译出操作系统镜像_运维_03

l  另一个问题是静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。

    动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新

centos 源代码编译出操作系统镜像_静态库_04

动态库特点总结:

l  动态库把对一些库函数的链接载入推迟到程序运行的时期。

l  可以实现进程之间的资源共享。(因此动态库也称为共享库)

l  将一些程序升级变得简单。

l  甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。


linux动态库的命名规则

动态链接库的名字形式为 libxxx.so,前缀是lib,后缀名为“.so”。


ldconfig 与 /etc/ld.so.conf

通过上面的讲解,我们可以知道,动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入内存。如果从硬盘上读取,将会影响程序加载运行的效率,我们可以预先把 动态库 加载到内存中 cache,这样以提高效率。

    如何将动态库加载到高速缓存 cache 中呢?

  1. 编辑 /etc/ld.so.conf , 添加需要读入 cache 的动态库目录
  2. 利用ldconfig 可执行文件将 /etc/ld.so.conf 数据读入缓存中
  3. 同时,以上命令也将数据记录在 /etc/ld.so.cache 中 


    ldconfig 是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命

令 ldconfig。 ldconfig 命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件 

/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib*.so*),进而创建出动态装入

程序(ld.so)所需的连接和缓存文件.缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表.

    linux下的共享库机制采用了类似于高速缓存的机制,将库信息保存在/etc/ld.so.cache里边。

ldconfig命令的作用是
    ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib). The cache is used by the run-time linker, ld.so or ld-linux.so. ldconfig checks the header and filenames of the libraries it encounters when determining which versions should have their links updated.

ldconfig命令需要注意的问题

1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library会找不到

2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到

比 如安装了一个mysql到/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,这时就 需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,保存过后ldconfig一下,新的library才能在程 序运行时被找到。

3. 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变 量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时 候使用。

4. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。

5. 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事

https://blog.51cto.com/skypegnu1/1626265