1. 概述

说明

  1. 点击这里,查看制作 Openresty RPM 包的 SPEC 文件

  2. 本文运行环境:

    • 操作系统:CentOS Linux release 7.8.2003 (Core)
    • rpm/rpmbuild:RPM version 4.11.3

常见的 Linux 发行版主要分为两类:类 RedHat 系列和类 Debian 系列。在类 RedHat 系统中,软件包的格式是 rpm;在类 Debian 系统中,软件包的格式是 deb。类 RedHat 系统提供 rpm(RedHat Package Manager)命令,用于安装、卸载和升级 RPM 软件包;类 Debian 系统提供 dpkg 命令,用于安装、卸载和升级 DEB 软件包。

CentOS 提供 yum 工具,自动解决软件包的安装依赖,yum 本质上还是调用 rpm。不同发行版上的包管理工具,如下所示:

分类 发行版 手动安装命令 自动安装命令 软件包后缀
类 RedHat
Fedora/CentOS rpm
yum *.rpm
openSUSE/SUSE zypper
Mandriva Linux/Mageia urpmi
类 Debian Debian/Ubuntu dpkg apt *.deb

2. 目录结构

从运行结构来看,软件主要分为三部分:可执行程序、配置文件和动态链接库。还可能包含可选的头文件、手册、示例程序等。

本文主要讲述如何使用 rpmbuild 制作 RPM 包,rpmbuild 的输入对象是 SPEC 文件,下面开始介绍 SPEC 文件。

对于版本小于等于 4.4.x 的 rpmrpmbuild 的默认工作目录是 /usr/src/redhat,这使得普通用户无法制作 RPM 包。所以从版本 4.5.x 开始,rpmbuid 的默认工作路径被移动到 $HOME/rpmbuild,并且建议用户在制作 RPM 包时,尽量不要使用 root 身份进行操作。rpmbuild 的默认工作路径通常由 /usr/lib/rpm/macros 文件里的 %{_topdir} 宏定义。如果用户想要更改 rpmbuild 的工作路径,那么可以在用户的家目录下创建一个名为 .rpmmacros 的隐藏文件,然后在其中重新定义 %{_topdir}。比如:

%{_topdir} 目录下,一般需要建立 6 个目录:

在建立上述目录之后,将用于生成 RPM 包的所有源代码、Shell 脚本、配置文件拷贝到 SOURCES目录。通常情况下,源代码的格式是 *.tar.gz,SPEC 文件的命名格式是“软件名-版本.spec”。将 SPEC 文件拷贝到 SPECS 目录,cdSPECS 目录,然后执行:

最终生成的 RPM 包在 RPMS 目录。


3. SPEC 文件的头部

SPEC 文件分为头部和阶段。阶段有多个,比如 %prep、%build、%install、%clean、%files、%pre、%post、%preun、%postun 等。执行 rpmbuild 时,它首先解析 SPEC 文件,然后依次执行每个阶段里的指令。

接下来,简单地介绍 SPEC 文件的头部:


4. SPEC 文件中的阶段

下面是可选的阶段:


5. 其它

如果准备将正在制作的 RPM 包放到系统安装光盘中,那么需要考虑 RPM 包中定义的脚本是否有问题。由于系统安装时只依赖于一个“小”环境,该环境与实际安装完成的环境有很大区别,所以大部分脚本在该安装环境中无法生效,甚至带来麻烦。

因此对于需要放到安装光盘中的套件,较好的方法是不加入执行脚本。

此外,RPM 还提供一种信号机制 - 不同操作返回不同信息,并且保存到 $1 中(0 代表卸载;1 代表安装;2 代表升级):

下面是 RPM 包用到的一些文件和目录:

在安装的时候,修改默认路径:

或者同时修改多个路径:


6. 补丁文件

6.1. 使用 diff 命令,生成补丁文件

diff 命令用于比较文件的内容,找到改动的地方。diff 的输出称为补丁(patch),Linux 系统中的 patch 命令可以根据 diff 程序的输出,将源文件的内容更新为目标文件。diff 是 SVN、Git 等版本控制工具不可或缺的一部分。

diff 可以比较单个文件或目录。如果比较单个文件,那么只有当输入文件是文本文件时才有效,diff 以逐行的方式,比较文本文件的异同。如果比较目录,那么 diff 将比较两个目录下文件名相同的文本文件,并且列出不同的二进制程序、公共子目录和只在一个目录中出现的文件。

命令格式为:

常用参数包括:

下面通过几个示例进行说明,示例文件如下:

a/sub/1.txt:

b/sub/1.txt:

示例 1:

2,4c2 的含义如下:

前面的数字 2,4 表示第一个文件中的行,中间的字母 c 表示需要在第一个文件上执行的操作(a=add、c=change、d=delete),后面的数字 2 表示第二个文件中的行。也就是说,第一个文件中的第 [2, 4] 行需要做出修改才能与第二个文件中的第 2 行匹配。

接下来的内容是需要修改的地方,前面带 < 的部分表示左边文件的第 [2, 4] 行的内容,带 > 的部分表示右边文件第 2 行的内容,中间的 - 则是两个文件内容的分隔符。

示例 2:

说明:

示例 3:

说明:

示例 4:

说明:

6.2. 使用 patch 命令,打补丁

patchdiff 制作的补丁,实现源文件(目录)和目标文件(目录)的相互转换。常用的选项有:

示例 1:

使用上一小节的示例 4 生成的 patch.log

说明:


7. RPM SPEC 示例

示例文件:

rpmbuild/SOURCES/hello_world.sh:

rpmbuild/SPECS/rpmtester.spec:

打包:

生成的 RPM 包在:

安装 RPM 包:

运行安装的命令: