第 6 章 打包软件
了解打包流程与 RPM 软件包管理器的基础知识。
6.1. 关于 spec 文件 复制链接链接已复制到粘贴板!
spec 文件是一个包含 rpmbuild 工具用来构建 RPM 软件包的指令的文件。
spec 文件通过在一系列小节中定义指令来为构建系统提供必要的信息。这些部分在 spec 文件的 Preamble 和 Body 部分中定义:
- Preamble 部分包含一系列在 Body 部分中使用的元数据项。
- Body 部分代表说明的主要部分。
6.1.1. spec 文件的 preamble 项 复制链接链接已复制到粘贴板!
在 RPM spec 文件的 Preamble 部分中使用以下指令。
| 指令 | 定义 |
|---|---|
|
|
软件包的基本名称必须与 |
|
| 软件的上游版本号。 |
|
| 软件包版本发布的次数。
将初始值设置为 |
|
| 软件包的一行简短摘要。 |
|
| 被打包的软件的许可证。
如何在 |
|
| 有关软件的更多信息的完整 URL,例如,打包软件的上游项目网站。 |
|
| 到压缩的未打补丁的上游源代码的存档的路径或 URL。此链接必须指向存档的可访问且可靠的存储,例如上游页面,不是打包程序的本地存储。
您可以在指令名称的末尾使用或不使用号码应用 |
|
| 应用到源代码的第一个补丁的名称(如有必要)。
您可以在指令名称的末尾使用或不使用号码应用
您可以使用 |
|
| 将为之构建软件的架构
如果软件不依赖于架构,例如,如果您完全使用解释型编程语言编写软件,请将值设为 |
|
|
构建使用编译语言编写的程序所需的逗号或空格分开的软件包的列表。 |
|
|
安装之后,软件需要以逗号或空格分开的软件包列表。可以有多个 |
|
|
如果软件的一部分无法在特定的处理器架构上运行,您可以在 |
|
|
不必安装在系统上,以便您的软件在安装时可以正常工作的用逗号或空格分开的软件包的列表。可以有多个 |
|
|
|
|
|
如果您向软件包中添加了 |
6.1.2. spec 文件的正文项 复制链接链接已复制到粘贴板!
在 RPM spec 文件的 Body 部分中,使用以下指令:
| 指令 | 定义 |
|---|---|
|
| RPM 中打包的软件的完整描述。此描述可跨越多行,并且可以分为几个段落。 |
|
|
准备进行构建的软件的命令或一系列命令,例如,在 |
|
| 用于配置用于构建的软件的命令或一系列命令。 |
|
| 将软件构建成机器码(用于编译的语言)或字节码(用于某些解释语言)的命令或一系列命令。 |
|
|
软件构建后,
请注意, |
|
| 用于测试软件(如单元测试)的命令或一系列命令。 |
|
| RPM 软件包提供的要安装到用户的系统中的文件的列表,以及系统上它们的完整路径位置。
在构建期间,如果
在 |
|
|
在不同的 |
6.1.3. 高级 spec 文件项 复制链接链接已复制到粘贴板!
spec 文件可以包含高级项目,如 Scriptlets、File 触发器和 Triggers。这些指令会影响 spec 文件,以及通过更新 RPM 中信息安装结果 RPM 的目标操作系统。
Scriptlets、File Triggers 和 Triggers 在目标系统的安装过程中的不同点生效,而不是构建过程:
- Scriptlets 在安装或删除软件包之前或之后无条件执行。
- 当指定触发器条件与安装系统上的其他软件包匹配或事务中的其他软件包匹配时,触发器会被有条件执行。
- 当指定路径前缀与安装的系统或事务中的其他文件匹配时,就会有条件地执行文件触发器。
6.1.3.1. scriptlets 指令 复制链接链接已复制到粘贴板!
Scriptlets 是在与软件包生命周期相关的预先确定的插槽执行的任意程序,例如在安装或删除软件包之前或之后。使用 scriptlets 仅适用于在构建时或在启动脚本中无法完成的任务。
默认情况下,scriptlet 是 spec 文件中的各种 %pre 或 %post 指令声明的短 shell 脚本。
常见 scriptlet 指令与 spec 文件部分标题类似,如 %build 或 %install。它们由多行代码段定义,它们通常写为标准的 POSIX shell 脚本。但是,它们也可以使用其他 RPM 接受目标机器的分发编程语言编写。
6.1.3.2. scriptlets 指令执行顺序 复制链接链接已复制到粘贴板!
查看在软件包升级过程中执行 scriptlet 的顺序。
| 指令 | 描述 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
在从目标系统卸载软件包前,执行 |
|
|
|
|
|
|
6.1.3.3. 关闭 scriptlets 执行 复制链接链接已复制到粘贴板!
使用带有 scriptlet 名称的-- no 选项,关闭任何 scriptlet 的执行。
您还可以使用 the- noscripts 选项,它等同于关闭以下所有 scriptlet 的执行:
-
--nopre -
--nopost -
--nopreun -
--nopostun -
--nopretrans -
--noposttrans -
--nopreuntrans -
--nopostuntrans
如需更多信息,请参阅系统中的 rpm 手册页。
流程
关闭 scriptlet 执行:
# rpm --no<scriptlet_name>例如,要关闭
%pretransscriptlet 的执行,请输入:# rpm --nopretrans
6.1.3.4. scriptlets 的宏示例 复制链接链接已复制到粘贴板!
以下是可用于 spec 文件中的 scriptlet 的宏示例。这些宏是由 systemd-rpm-macros 软件包提供的实际宏。您可以使用这些宏打包 systemd相关内容。您还可以对其他软件包应用类似的原则。
包含 systemd 单元文件的软件包必须使用 scriptlets 来正确处理 systemd 服务。systemd 软件包提供了一组宏来处理 systemd scriptlet 操作。例如:
%post
%systemd_post httpd.service
%preun
%systemd_preun httpd.service
这些宏扩展到软件包中的以下内容:
$ rpm --eval "%systemd_preun httpd.service"
if [ $1 -eq 0 ] && [ -x "/usr/lib/systemd/systemd-update-helper" ]; then
# Package removal, not upgrade
/usr/lib/systemd/systemd-update-helper remove-system-units httpd.service || :
fi
宏的行为方式可能会改变。例如,宏的行为可能会随着软件包的开发而改变。
6.1.4. Epoch 指令 复制链接链接已复制到粘贴板!
如果设置 Version spec file 指令不足以比较软件包版本,您可以使用 Epoch 指令。例如,您可以使用 Epoch 解决所发生的升级路径问题,因为上游更改以不兼容的方式在版本号方案中。
epoch 是一个数字字段。如果您为 Epoch 分配了一个值,它会添加一个 RPM 在比较软件包版本时使用的限定符。没有在 spec 文件中列出的 Epoch 指令意味着未设置 Epoch。这与不设置 Epoch 而通常的原则不同,即 Epoch 为 0。但是,出于处理目的,如果您没有设置 Epoch,RPM 将其视为与 Epoch 设置为 0 时一样,反之亦然。
在 spec 文件中使用 Epoch 通常会省略,因为在大多数情况下,在大多数情况下,引入了一个 Epoch 值,在比较软件包时,会中断预期的 RPM 行为。因此,请考虑使用 Epoch 作为最后的手段。
例如,您使用 Epoch: 1 和 Version: 1.0 安装 foobar 软件包。另一个软件包 foobar with Version: 2.0,但没有 Epoch 指令。因此,新版本永远不会被视为更新,因为 Epoch 版本优先于为 RPM 软件包版本控制的传统 Name-Version-Release 标记。
6.1.5. 软件包版本基本 复制链接链接已复制到粘贴板!
软件包描述的基本部分是 Name,Version, 和 Release (NVR) spec 文件指令中定义的信息。RPM 使用此信息比较软件包版本并跟踪软件包依赖项。
使用 RPM 时,您还可以看到 EVR (epoch-version-release), NEVR (name-epoch-version-release)和 NEVRA (name-epoch-version-release-architecture)。EVR 是 RPM 始终用来比较的软件包的完整版本信息。RPM 一次比较一个组件,从第一个组件开始。当发现组件的不同时,RPM 将停止此比较。例如,如果 Epoch 不同,RPM 不会比较 EVR 组件的其余部分。
您可以通过查询 RPM 数据库来显示特定软件包的 NVR 信息,例如:
# rpm -q bash
bash-4.4.19-7.el8.x86_64
在这里,bash 是软件包名称,4.4.19 是版本,7el8 是发行版本。x86_64 标记是软件包架构。与 NVR 不同,架构标记不在 RPM 打包程序的直接控制之下,而是由 rpmbuild 构建环境定义。这种情况的例外是独立于架构的 noarch 软件包。
rpm -q 命令默认以 NEVRA 格式显示软件包信息。