注意,这次使用的源码包,指的是软件所有源代码的压缩包,其后缀名为 “.tar.gz” 或 “.tar.bz2”;而 SRPM 源码包本质上属于 RPM 包,也就是源码的RPM包,其文件后缀为 “.src.rpm”。虽然都叫源码包,但不是一码事。
软件的源代码,也就是软件的原始数据,任何人都可以通过源代码查看该软件的设计架构和实现方法,但软件源代码无法再计算机中直接运行安装,需要将源代码通过编译转换为计算机可以识别的机器语言,然后才可以安装。
Linux 系统中,绝大多数软件的源代码都是用 C 语言编写的,少部分用C++(或其他语言)编写。因此要想安装源码包,必须安装 gcc 编译器(如果涉及 C++ 源码程序,还需要安装 gcc-c++)。安装 gcc 之前,可先使用如下命令看看是否已经安装:
[root@CncLucZK ~]# rpm -qa gcc
gcc-8.2.1-3.5.el8.x86_64
[root@CncLucZK ~]# rpm -qa|grep gcc
libgcc-8.2.1-3.5.el8.x86_64
gcc-8.2.1-3.5.el8.x86_64
如果未安装,考虑到安装 gcc 所依赖的软件包太多,推荐使用 yum 安装 gcc
除了安装编译器,还需要安装 make 编译命令。要知道,编译源码包可不像编译一个 hello.c 文件那样轻松,包中含大量的源码文件,且文件之间有着非常复杂的关联,直接决定着各文件编译的先后顺序,因此手动编译费时费力,而使用 make 命令可以完成对源码包的自动编译。
同样,在安装 make 命令之前,可使用如下命令查看其是否已经安装:
[root@CncLucZK httpd-2.4.54]# rpm -qa make
make-4.2.1-9.el8.x86_64
yum -y install make
命令直接安装 make。由Linux文件目录结构一节可知:将各种文件分门别类保存在对应的目录中,成为约定俗成的习惯。Linux 系统中用于保存源代码的位置主要有 2 个,分别是 “/usr/src” 和 “/usr/local/src”,其中 “/usr/src” 用来保存内核源代码,“/usr/local/src” 用来保存用户下载的源代码。
2.将源码包进行解压缩,使用命令如下
[root@CncLucZK ~]#tar -zxvf httpd-2.4.54.tar.gz|more
3.进入解压目录,执行如下命令
[root@CncLucZK ~]# cd httpd-2.4.54
[root@CncLucZK httpd-2.4.54]#./configure --help|more
#查询apache支持的选项功能(不是必需步骤)
此步具体执行代码如下:
[root@CncLucZK httpd-2.4.54]# ./configure --prefix=/usr/local/apache2 --prefix 选项的含义为指定安装目录。
checking for chosen layout...Apache
checking for working mkdir -p…yes
checking build system type...i686-pc-linux-gnu
checking host system type...i686-pc-linux-gnu
checking target system typa...i686-pc-linux-gnu
…省略部分输出…
此命令没有加载其他功能,只是指定安装目录。需要说明的是,“/usr/local/apache2” 目录不需要手工建立,安装完成后会自动建立(这个目录是否生成也是检测软件是否正确安装的重要标志)。
5.make 编译。make 会调用 gcc 编译器,并读取 Makefile 文件中的信息进行系统软件编译。编译的目的就是把源码程序转变为能被 Linux 识别的可执行文件,这些可执行文件保存在当前目录下。执行的编译命令如下.编程过程较为耗时。
[root@CncLucZK httpd-2.4.54]# make
6.正式开始安装软件,这里通常会写清程序的安装位置,如果没有,则建议读者把安装的执行过程保存下来,以备将来删除软件时使用。安装指令如下:
[root@CncLucZK httpd-2.4.54]# make install
注意,如果在 “./configure” 或 “make” 编译中报错,则在重新执行命令前一定要执行
make clean
命令,它会清空 Makefile 文件或编译产生的 “.o” 头文件。
[root@CncLucZK ~]# rm -rf /usr/local/apache2/
使用补丁文件更新源码包,省去了用 ./configured 生成新的 Makefile 文件,还省去了大量的编译工作,因此效率更高。
[root@localhost ~]# diff 选项 old new #比较old和new文件的不同
此命令中可使用如下几个选项:
从生成补丁文件,到使用其实现更新软件的目的,下面我们自己创建两个文件(分别模拟旧软件和新软件),通过对比新旧文件生成补丁文件,最后利用补丁文件更新旧文件,具体步骤如下:
[root@CncLucZK test]# cat demoold.txt
hello world 1!
hello world 2!
hello world 3!
hello world 4!
hello world 5!
hello world 6!
[root@CncLucZK test]# sed -i 's/world/linux/g' demonew.txt
hello linux 1!
hello linux 2!
hello linux 3!
hello linux 4!
hello linux 5!
hello linux 6!
2.利用 diff 命令,比较两个文件(demoold.txt 和 demonew.txt)的不同,并生成补丁文件(txt.patch),执行代码如下:
[root@CncLucZK test]# diff -Naur demoold.txt demonew.txt > differ.patch
[root@CncLucZK test]# cat differ.patch
#旧文件
--- demoold.txt 2022-10-13 18:56:30.001597669 +0800
#新文件
+++ demonew.txt 2022-10-13 20:06:35.491676677 +0800
@@ -1,6 +1,6 @@
-hello world 1!
-hello world 2!
-hello world 3!
-hello world 4!
-hello world 5!
-hello world 6!
+hello linux 1!
+hello linux 2!
+hello linux 3!
+hello linux 4!
+hello linux 5!
+hello linux 6!
#后一个文件比前一个文件多行(用+表示)
3.利用补丁文件 txt.patch 更新 old.txt 旧文件,实现此步操作需利用 patch 命令,该命令基本格式如下:
[root@CncLucZK test]# patch -pn < 补丁文件 #按照补丁文件进行更新
-pn 选项中,n 为数字(例如 p1、p2、p3 等),pn 表示按照补丁文件中的路径,指定更新文件的位置。这补丁文件是要打入旧文件的,但是当前所在目录和补丁文件中记录的目录不一定是匹配的,需要 “-pn” 选项来同步两个目录。
例如,当前位于 “/root/test/” 目录下(要打补丁的旧文件就在当前目录下),补丁文件中记录的文件目录为 “/root/test/demoold.txt”,如果写入 “-p1”(在补丁文件目录中取消一级目录),那么补丁文件会打入 “root/test/root/test/demoold.txt” 文件中,这显然是不对的;如果写入的是 “-p2”(在补丁文件目录中取消二级目录),补丁文件会打入 “/root/test/test/demo.txt” 文件中,这显然也不对。如果写入的是 “-p3”(在补丁文件目录中取消三级目录),补丁文件会打入 “/root/test/demo.txt” 文件中,demo.txt 文件就在这个目录下,所以应该用 “-p3” 选项。
如果当前所在目录是 “/root/” 目录呢?因为补丁文件中记录的文件目录为 “/root/test/old.txt”,所以这里就应该用 “-p2” 选项(代表取消两级目录),补丁打在当前目录下的 “test/old.txt” 文件上。
因此,-pn 选项可以这样理解,即想要在补丁文件中所记录的目录中取消几个 “/”,n 就是几。去掉目录的目的是和当前所在目录匹配。
现在更新 “demoold.txt” 文件,命令如下:
[root@CncLucZK test]# patch -p0< differ.patch
patching file demoold.txt
[root@CncLucZK test]# cat demoold.txt
hello linux 1!
hello linux 2!
hello linux 3!
hello linux 4!
hello linux 5!
hello linux 6!
期间可能会报一个错误:-bash: patch: command not found,说明patch包没有安装需要先安装patch包
[root@CncLucZK test]# yum -y install patch
这里使用的补丁文件,修补了 apache 代理 FTP 站点时,模块空指针引用拒绝服务攻击的漏洞
[root@CncLucZK ~]# cp mod_proxy_ftp_CVE-2008-2939.diff httpd-2.2.9
[root@CncLucZK ~]# cd httpd-2.2.9
#进入apache源码目录
[root@CncLucZK httpd-2.2.9]# cat mod_proxy_ftp_CVE-2008-2939.diff
#查看补丁文件
--modules/proxy/mod_proxy_ftp.c (Revision 682869)
+ + + modules/proxy/mod_proxy_ftp.c (Revision 682870)
…省略部分输出…
#查看一下补丁文件中记录的目录,以便一会儿和当前所在目录同步
[root@CncLucZK httpd-2.2.9]# patch - p0 < mod_proxy_ftp_CVE-2008-2939.diff
#打入补丁
为什么是 “-p0” 呢?因为当前在 “/root/httpd-2.2.9” 目录中,但补丁文件中记录的目录是 “modules/proxy/mod_proxy_ftp.c”,就在当前所在目录中,因此一个 “/” 都不需要去掉,所以是 “-p0”。
[root@CncLucZK httpd-2.2.9]# make
5.安装 apache,执行如下命令
[root@CncLucZK httpd-2.2.9]# make install
注意,如果未安装过 httpd-2.2.9,就需要先打入补丁,再依次执行 "./configure"、"make"、
"make install" 命令。
[root@CncLucZK httpd-2.2.9]# patch -R < modjDroxy_ftp_CVE-2008-2939.diff
-R(大写)选项表示还原补丁。
参考文献:
Linux源码包安装和卸载教程