【Linux命令】《鸟哥Linux基础》第二十一章 软件安装:源代码与Tarball

第二十一章 软件安装:源代码与Tarball

了解:如何将开放源码的程序设计、加入函数库的原理、通过编译而成为可执行的二进制程序,最后该文件可被我们所使用的一连串过程。

这一章介绍最原始的软件管理方式,使用Tarball来安装与升级管理我们的软件。

21.1 开放源码的软件安装与升级简介

Windows中无法修改该软件的源代码,如果想增加或者减少软件的某些功能时,只能求助于发行该软件的厂商。

如果能提前修补软件中的漏洞,就不用等到软件开发商提供修补程序包。提早补洞是很重要的一件事。

Linux上的软件几乎都是经过GPL授权,所以每个软件几乎均提供源代码,可以自行修改程序代码,定制自己的软件。

21.1.1 什么是开放源码、编译器与可执行文件

Linux系统上的可执行文件,是指:首先针对该文件具有可执行的权限,另外它应该是二进制文件。

[root@study ~]$ file /bin/bash					如果是二进制文件,那么就会显示ELF 64-bit LSB executable
/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=7e644dee920bc3ba797c38e05383286563712b49, stripped


[root@study ~]$ file /etc/init.d/network		如果不是二进制文件,而是脚本,就会显示ASCII text executable
/etc/init.d/network: Bourne-Again shell script, ASCII text executable
  • 首先写程序代码,这个程序代码文件就是一般的纯文本文件;
  • 将这个文件编译成为操作系统看得懂的二进制程序(会用到编译器操作,经过编译器的编译和链接后,会产生一个可以执行的二进制程序)。

Linux上面最标准的程序语言为C,所以使用C的语法进行源代码编写,写完后,以Linux上标准的C语言编译器gcc这个程序来编译,可以制作一个可以执行的二进制程序。

编译过程会产生目标文件(.o),C语言的源代码一般是(.c)文件。有时候我们会在程序中引用、调用 其他的外部子程序,或是利用其他软件提供的函数功能,这时候,就必须在编译过程中,将该函数库加进去,这样,编译器就可以将所有的程序代码与函数库作一个链接以产生正确的执行文件。

21.1.2 什么是函数库

Linux内核提供很多函数库给开发者们调用。

函数库分为动态函数库和静态函数库。

函数库就是类似子程序的角色,可以被调用来执行一段功能函数。

21.1.3 什么是make与configure

每个主程序与子程序都需要写上一条编译过程的命令,除此之外,还要写上最终的链接程序。程序代码短还好,如果非常大,编译命令会非常非常多,这时候可以利用make这个命令的相关功能来进行编译过程的简化。

使用make时,make会在当前的目录下查找Makefile(或makefile)这个文本文件,而Makefile里面记录了源代码如何编译的详细信息。make会自动判别源代码是否经过变动了,而自动更新执行文件,是有力工具!

一般软件开发商会写一个检测程序来检测用户的操作环境,以及该操作环境是否具有软件开发商需要的其他功能。该检测软件检测完毕后,会主动地建立这个Makefile的规则文件,通常这个检测程序的文件名为configure或是config。

一般检测的内容包括:

  • 是否有适合的编译器可以编译本软件的程序代码
  • 是否已经存在本软件所需要的函数库,或者其他需要的依赖软件
  • 操作系统平台是否适合本软件,包括Linux的内核版本
  • 内核的头文件是否存在(驱动程序必须要的检测)

我们要做的只有两件事:

  1. 执行configure来建立Makefile,这个步骤务必要成功
  2. 成功后,再以make来调用所需要的数据进行编译即可,很简单

21.1.4 什么是Tarball的软件

将源代码这种纯文本文件压缩后,得到的就是Tarball的软件。

这样能够利用打包与压缩技术,将文件的数量和容量减小,既方便用户下载,也能节省软件开发商的网站带宽。

Tarball文件一般是将所有的源代码文件,先以tar打包,再以压缩技术来压缩,通常最常见的是以gzip来压缩。利用了tar和gzip的功能,Tarball文件的一半扩展名就是.tar.gz.tgz。近期bzip2和xz的压缩率较优,Tarball也会以bzip2和xz的压缩技术来替换gzip,因此文件名也会变成.tar.bz2.tar.xz之类的。

解压缩后Tarball里包括:

  • 源代码文件
  • 检测程序文件(可能是configure或config等文件)
  • 本软件的简易说明与安装说明(INSTALL或README,最重要

参考INSTALL或README进行软件安装,很简单。

21.1.5 如何安装与升级软件

  1. 将Tarball由厂商的网站下载
  2. 将Tarball解开,产生很多的源代码文件
  3. 开始以gcc进行源代码的编译(会产生目标文件object files)
  4. 然后以gcc进行函数库、主、子程序的链接,以形成主要的二进制文件
  5. 将上述的二进制文件以及相关的配置文件安装至自己的主机上面

3和4两步可以通过make命令的功能简化它。

要求你的Linux系统里至少要安装有gccmake两个软件。

21.2 使用传统程序语言进行编译的简单范例

21.2.1 单一程序:打印Hello World

[root@study ~]$ vim hello.c			首先,编写hello.c源代码
[root@study ~]$ cat hello.c
#include
int main(){
	printf("Hello World\n");
}


[root@study ~]$ gcc hello.c			直接编译,产生一个a.out文件
[root@study ~]$ ll hello.c a.out
-rwxr-xr-x. 1 root root 8360 Jun 18 14:28 a.out
-rw-r--r--. 1 root root   58 Jun 18 14:28 hello.c


[root@study ~]$ ./a.out				这个a.out文件是可执行文件
Hello World




如果希望一步一步生成,同时能指定可执行文件的名称:
[root@study ~]$ gcc -c hello.c			首先产生目标文件.o文件
[root@study ~]$ ll hello*
-rw-r--r--. 1 root root   58 Jun 18 14:28 hello.c
-rw-r--r--. 1 root root 1496 Jun 18 14:29 hello.o <======这里可以看到,已经产生了


[root@study ~]$ gcc -o hello hello.o	根据目标文件生成可执行文件,起名hello
[root@study ~]$ ll hello*
-rwxr-xr-x. 1 root root 8360 Jun 18 14:30 hello	<======这里可以看到,已经产生了
-rw-r--r--. 1 root root   58 Jun 18 14:28 hello.c
-rw-r--r--. 1 root root 1496 Jun 18 14:29 hello.o


[root@study ~]$ ./hello 
Hello World

21.2.2 主、子程序链接:子程序的编译

[root@study ~]$ vim thanks.c 		主程序
[root@study ~]$ cat thanks.c
#include
int main(){
	printf("Hello World\n" );
	thanks_2();
}


[root@study ~]$ vim thanks_2.c 		子程序
[root@study ~]$ cat thanks_2.c 
#include
void thanks_2(){
	printf("Thank you!\n");
}


[root@study ~]$ gcc -c thanks.c thanks_2.c 			指定需要针对哪几个源代码生成目标文件
[root@study ~]$ ll thanks*
-rw-r--r--. 1 root root   62 Jun 18 14:39 thanks_2.c
-rw-r--r--. 1 root root 1504 Jun 18 14:39 thanks_2.o<======这里可以看到,已经产生了
-rw-r--r--. 1 root root   72 Jun 18 14:39 thanks.c
-rw-r--r--. 1 root root 1560 Jun 18 14:39 thanks.o<======这里可以看到,已经产生了


[root@study ~]$ gcc -o thanks thanks.o thanks_2.o	将两个目标文件一起链接到一个可执行文件中
[root@study ~]$ ll thanks*
-rwxr-xr-x. 1 root root 8424 Jun 18 14:40 thanks<======这里可以看到,已经产生了
-rw-r--r--. 1 root root   62 Jun 18 14:39 thanks_2.c
-rw-r--r--. 1 root root 1504 Jun 18 14:39 thanks_2.o
-rw-r--r--. 1 root root   72 Jun 18 14:39 thanks.c
-rw-r--r--. 1 root root 1560 Jun 18 14:39 thanks.o


[root@study ~]$ ./thanks	执行这个可执行文件
Hello World
Thank you!

如果哪天你更新了thanks_2.c的内容,只需要重新编译thanks_2.c这个文件内容产生thanks_2.o,再拿着生成的目标文件去重新链接出一个新的可执行文件即可。

一般编译过程很耗时,这样的机制就可以节省大量的时间。

[root@study ~]$ gcc -O -c thanks.c thanks_2.c		加上-O能产生最佳化的参数
[root@study ~]$ gcc -Wall -c thanks.c thanks_2.c	加上-Wall能产生跟详细的编译过程信息
thanks.c: In function ‘main’:
thanks.c:4:2: warning: implicit declaration of function ‘thanks_2’ [-Wimplicit-function-declaration]
  thanks_2();
  ^
thanks.c:5:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

21.2.3 调用外部函数库:加入链接的函数库

[root@study ~]$ vim sin.c		编写源代码
[root@study ~]$ cat sin.c
#include
#include				其中要用到某个库
int main(){
	float value;
	value=sin(3.14/2);
	printf("%f\n",value);
}


[root@study ~]$ gcc sin.c 	直接编译,可以的!

[root@study ~]$ gcc sin.c -lm -L/lib -L/lib64		将库链接过来编译,也可以的!

[root@study ~]$ gcc sin.c -lm -I/usr/include		指定include文件的放置位置

-l:加入某个函数库library的意思。

m:是指libm.solibm.a这个函数库。其中lib与扩展名不需要写。

Linux默认将函数库放置在/lib/lib64中,所以就算没写-L/lib -L/lib64也没关系。如果哪天你用的函数库不是放在这两个目录下,那么-L/path就很重要了,否则找不到函数库。

Linux的include文件放置位置一般是/usr/include/中。

-I/path:后面接的路径就是设置要去查找相关的include文件的目录。

21.2.4 gcc的简易用法(编译、参数、连接)

gcc是Linux上最标准的编译器,是由GNU计划所维护的。

gcc -c hello.c		仅将源代码编译成目标文件
gcc -O hello.c -c 	会自动产生hello.o这个文件,但是并不会产生二进制执行文件;-O根据操作环境给予最佳化执行速度
gcc sin.c -lm -L/lib -I/usr/include	在尽心二进制文件制作时,将链接的函数库与相关的路径加入
gcc -o hello hello.c 				将编译的结果输出成某个特定文件名
gcc -o hello hello.c -Wall 			加入-Wall后,程序编译会变得更为严谨,警告信息也会显示出来

21.3 用make进行宏编译

21.3.1 为什么要用make

vim makefile	文件内容如下:
main:main.o haha.o sin_value.o cos_value.o 		指出这个main需要4个目标文件
	gcc -o main main.o haha.o sin_value.o cos_value.o -lm	执行链接操作

make的优点:

  • 简化编译时所需要执行的命令
  • 若在编译完成后,修改了某个源代码文件,则make仅会针对被修改了的文件进行编译,其他的目标文件不会被修改
  • 最后可以依照依赖性来更新执行文件

21.3.2 Makefile的基本语法与变量

目标(target):目标文件1 	目标文件2 ...
<tab>	gcc -o	欲建立的执行文件	目标文件1 	目标文件2 ...
clean:
	rm -f 目标 目标文件1 目标文件2 ... 
  • 井号键#代表注释
  • tab键需要在命令行的第一个字符(gcc这个编译器命令)
  • 目标(target)与依赖文件(就是目标文件)之间需要以冒号:隔开
  • 这个makefile中具有至少两个目标,分别是mainclean。执行make clean,通过makeclean为目标;想要建立main,输入make main;如果想先清除再建立,输入make clean main

使用变量进一步简化makefile:

vi makefile
LIBS = -lm
OBJS = main.o haha.o sin.o cos.o
CFLAGS = -Wall
main:${OBJS}
	gcc -o main ${OBJS} ${LIBS}
clean:
	rm -f main ${OBJS}

变量的基本语法:

  1. 变量与变量内容以【=】隔开,同时两边可以具有空格
  2. 变量左边不可以有tab键,例如上面范例的第一行LIBS左边不可以是tab键
  3. 变量与变量内容在【=】两边不能具有【:】
  4. 在习惯上,变量最好是以【大写字母】为主
  5. 运用变量时,以${变量}$(变量)使用
  6. 在该shell的环境变量是可以被套用,例如提到的CFLAGS这个变量
  7. 在命令行模式也可以设置变量

环境变量既可以定义在文件内,也可以在命令行当场定义,到底以哪个为主?牵扯到环境变量的使用规则:

  • make命令行后面加上环境变量为优先
  • makefile里面指定的环境变量第二
  • shell原本具有的环境变量第三
  • 此外,$@代表目前的目标(target)

上述代码可以把main换成$@:

vi makefile
LIBS = -lm
OBJS = main.o haha.o sin.o cos.o
CFLAGS = -Wall
main:${OBJS}
	gcc -o $@ ${OBJS} ${LIBS}	这里可以把main换成$@
clean:
	rm -f $@ ${OBJS}   			这里可以把main换成$@

21.4 Tarball的管理与建议

如何使用具有源代码的Tarball来建立一个属于自己的软件?

Tarball的安装是可以跨平台的,因为C语言的程序代码在各个平台上是可以通用的,只是需要的编译器可能不同。

21.4.1 使用源代码管理软件所需要的基础软件

gcc或cc等C语言编译器

GNU的gcc是Linux上首选的自由软件编译器。

为了简化编译流程,配合make命令根据文件的依赖性进行编译。但是make需要makefile的文件规则,不同系统里的基础软件环境可能不相同,所以需要检测用户的操作环境,好自行建立一个makefile文件。这个自行检测的小程序也必须要借由autoconfig这个相关软件来辅助才行。

需要内核提供的Library以及相关的include文件。很多软件直接使用操作系统内核提供的函数库和include文件,这样才可以与这个操作系统兼容。尤其是驱动程序方面的模块。在RedHat系统中,内核的相关功能通常被包含在kernel-sourcekernel-header软件中。

安装CentOS或者RedHat过程中应选择Development toolskernel source development等相关的软件包,这样才能默认安装gccmake等软件。

安装系统过程中如果没有选择上述选项,可以通过其他方式安装gcc和make。

如果么有网络,可以通过RPM安装;
如果有网络,可以用YUM安装:

  • 安装gcc等软件开发工具:yum groupinstall "Development Tools"
  • 如果安装的软件需要图形用户界面的支持,还得:yum groupinstall "X Software Development"
  • 如果安装的软件较旧,可能需要:yum groupinstall "Legacy Software Development"

21.4.2 Tarball安装的基本步骤

先将Tarball解压缩,然后到源代码所在的目录下进行makefile的建立,再以make来进行编译与安装:

  1. 获取原始文件:将tarball文件在/usr/local/src目录下解压缩;
  2. 获取步骤流程:进入新建立的目录下,去查看INSTALLREADME等相关文件内容(很重要!!!);
  3. 依赖属性软件安装:根据INSTALL/README的内容查看并安装好一些依赖的软件(非必要);
  4. 建立makefile:以自动检测程序(configconfigure)检测操作环境,并建立Makefile这个文件;
  5. 编译:用make这个工具,并使用该目录下的Makefile作为他的参数配置文件,来进行make的操作;
  6. 安装:以make这个程序,并以Makefile这个参数配置文件,根据install这个目标(target)的指定来安装到正确的路径。

大部分的Tarball软件安装的命令执行方式:

  1. ./configure
    这个步骤是在建立Makefile文件。一般是开发者写的一个脚本,用来检测你的Linux系统、相关的软件属性等,很重要!未来你的安装信息都是在这一步完成的。
  2. make clean
    让make去读取Makefile中关于clean的工作。这个步骤不一定有,但是最好执行一下,可以移除目标文件
  3. make
    make会根据Makefile中的默认设置进行编译的操作。编译,主要是用gcc将源代码编译成为可被执行目标文件,但是这些目标文件通常还需要链接一些函数库后,才能产生一个完整的执行文件。使用make就是要将源代码编译成为可以被执行的文件,但是这个可执行文件会放置在目前所在的目录下,尚未被安装到预定安装的目录中。
  4. make install
    最后的安装步骤,make会根据Makefile这个文件中关于install的选项,将第三步锁边已完成的内容安装到预定的目录中。

以上步骤只要有一个失败,后续的都会失败。如果安装成功,需要手动将软件的man page写入/etc/man_db.conf中。

21.4.3 一般Tarball软件安装的建议事项(如何删除?升级?)

Tarball要在/usr/local/src里面解压缩,因为

  • Linux发行版发布安装的软件大多在/usr里面
  • 用户自行安装的软件建议放在/usr/local里面
  • 源代码(Tarball)建议放置在/usr/local/man里面

与info和man的功能有关,默认情况下,man会去查找/usr/local/man里的说明文件。

将Apache安装好后,应该安装在以下文件夹中:

  • /usr/local/apache/etc
  • /usr/local/apache/bin
  • /usr/local/apache/lib
  • /usr/local/apache/man

这样,删除该目录/usr/local/apache就可视为删除了Apache软件。具体为rm -f /usr/local/apache

安装完成后,需要将路径加入该加入的位置:

  • /usr/local/apache/bin加入PATH里面
  • /usr/local/apache/man加入man page查找的路径中

安装Tarball时:

  1. 最好将Tarball的原始数据解压缩到/usr/local/src
  2. 安装时,最好安装到/usr/local这个默认路径下
  3. 考虑到未来的反安装步骤,最好可以将每个软件单独安装在/usr/local下面
  4. 为安装到单独目录的软件的man page加入man path查找:在/etc/man_db.conf内的40-50行左右写下如下一行:MANPATH_MAP /usr/local/software/bin /usr/local/software/man

从实用角度来说,一般不太会用到Tarball安装,除非要安装的软件是专属软件(要钱的)或者是比较冷门的软件,否则在RMP的补充计划EPEL中,一般常用软件都已经被打包好了。

21.4.4 一个简单的范例,利用ntp来示范

cd /usr/local/src

tar -zxvf /root/ntp-4.2.8p3.tar.gz

cd ntp-4.2.8p3

vi INSTALL

./configure --help | more

./configure --prefix=/usr/local/ntp --enable-all-clocks --enable-parse-clocks	开始建立Makefile

make clean;make

make check

make install

21.4.5 利用patch更新源代码

tar -zxvf main-0.1.tar
cd main-0.1
make clean main
./main
patch -p 数字 < patch_file		此处应格外注意 -p 数字,表示拿掉几个斜线/的意思
patch -p1 < ../main_0.1_to_0.2.patch	目前所在目录实在main-0.1下面,注意与patch文件的相对路径
make clean main
./main
make install		将它安装至/usr/local/bin
main				直接输入命令执行此程序
make uninstall		删除此软件

只需要下载patch文件就能将你现有的软件源代码更新了,但是更新源代码后不代表软件已经完成更新,所以还要将该软件编译后,采食最终正确的软件,因为patch的功能主要只是更新源代码文件而已,切记。

如果patch过程出错,想要还原:

patch -R < ../main_0.1_to_0.2.patch

21.5 函数库管理

函数库很重要,用于身份验证的函数库PAM、用于网络连接加密机制的函数库SSL等。

函数库依照是否被编译到程序内部分为动态、静态函数库。

21.5.1 动态与静态函数库

静态函数库特点:

  • 扩展名libxxx.a
  • 编译时会直接整合到执行程序中,所以利用静态函数库编译完成的文件会比较大一些
  • 独立执行的状态:静态库的最大优点就是编译成功的可执行文件可以独立运行,不需要再向外部要求读取函数库的内容
  • 升级难:只要函数库升级了,所有使用此函数库的程序都需要重新编译。(因为是整合到整个程序中)

动态库特点:

  • 升级易:目前的Linux发行版倾向于使用动态函数库,函数库升级时,只需要动态函数库自身升级,其他软件无需变动
  • 绝大多数函数库都放置在/lib64/lib目录中。很多函数库内核就提供了。内核的函数库是放在/lib/modules中的。不同版本的内核提供的函数库差异性挺大的,所以kernel2.4.xx版本的系统不要想将内核换成2.6.xx版本,很容易由于函数库的不同而导致很多原本可以执行的软件无法顺利运行

21.5.2 ldconfig与/etc/ld.so.conf

如何增强函数库的读取性能?
因为内存的访问速度是硬盘的好多倍,如果将常用的动态函数库加载到内存当中(缓存,cache),如此一来,当软件要使用动态函数库时,就不需要从头由硬盘里读出,这样就能提高动态函数库的读取速度了。

如何将函数库加载到内存?

  1. 首先要在/etc/ld.so.conf里写入想要读入高速缓存当中的动态函数库所在的目录,是目录,不是文件;
  2. 接下来是利用ldconfig这个执行文件将/etc/ld.so.conf的数据读入缓存中;
  3. 同时也将数据记录一份至/etc/ld.so.cache这个文件中。
ldconfig [-f conf] [-C cache]
ldconfig [-p]
			-f conf	那个conf指的是某个文件名称,也就是说使用conf作为libarary函数库的获取路径,而不以/etc/ld.so.cache为默认值
			-C cache 那个cache指的是某个文件名称,也就是说使用cache作为高速缓存的函数库数据,而不以/etc/ld.so.cache为默认值
			-p	列出目前所有函数库数据内容(在/etc/ld.so.cache内的数据)

MariaDB数据库函数库在/usr/lib64/mysql中,如何读入cache:

vim /etc/ld.so.conf.d/vbird.conf
新增:/usr/lib64/mysql 
ldconfig
ldconfig -p

这样就完成了将MariaDB的相关函数库读入缓存当中,这样可以提高函数库读取的效率。

某些时候,你可能会自行加入某些Tarball安装的动态函数库,若想要让这些动态函数库的相关链接可以被读入到缓存当中,这时候你可以将动态函数库所在的目录名称写入/etc/ld.so.conf.d/yourfile.conf当中,然后执行/ldconfig就可以。

21.5.3 程序的动态函数库解析:ldd

如何判断某个可执行的二进制文件含有什么动态函数库?

ldd [-vdr] [filename]
		-v  列出所有内容信息
		-d	重新将数据有遗失的链接点显示出来
		-r	将ELF有关的错误内容显示出来

找出/usr/bin/passwd这个文件的函数库信息:
ldd /usr/bin/passwd

ldd -v /lib64/libc.so.6	找出这个函数的相关函数库

21.6 检验软件正确性

md5sum
sha1sum
sha256sum

md5sum ntp-4.2.8p3.tar.gz	检验刚刚下载的这个文件,看看校验值

可以对重要文件创建校验值,每天比对,防止被木马入侵:

1 建立重要文件的文件名列表important.file
ls /etc/{passwd,shadow,group} > important.file
find /usr/bin /usr/bin -perm /6000 >> important.file

2 通过这个文件名列表,以名为md5.checkfile.sh的文件名去建立校验值,并将校验值文件finger1.file设置为不可修改的属性:
vim md5.checkfile.sh
文件内容:
#!/bin/bash
for filename in $(cat important.file)
do 
	md5sum $filename >> finger1.file
done
	
运行文件:
sh md5.checkfile.sh
设置不可修改:
chattr +i finger1.file

3 通过相同的机制建立后续的分析数据为finger_new.file,并将两者对比,若有问题,发送email给root
vim md5.checkfile.sh
文件内容:
#!/bin/bash
if [ "$1" == "new" ];then
	for filename in $(cat important.file)
	do 
		md5sum $filename >> finger1.file
	done
	echo "New file finger1.file is created."
	exit 0;
fi
if [ ! -f finger1.file ];then
	echo "file: finger1.file NOT exist."
	exit 1
fi

[ -f finger new.file ] && rm finger_new.file
for filename in $(cat important.file)
do 
	md5sum $filename >> finger_new.file
done

testing=$(diff finger1.file finger_new.file)
if [ "$testing" != "" ];then
	diff finger1.file finger_new.file | mail -s 'finger trouble..' root
fi

让这个文件定期执行(每天执行一次):
vim /etc/crontab
30 2 * * * root cd /root; sh md5.checkfile.sh

如果是正常的系统升级,升级后应该删掉原来的finger1.file,重新建立一个finger1.file,否则总会收到邮件。

你可能感兴趣的:(Linux基础,linux,操作系统,软件安装,源代码,Tarball)