RPM 包是如何制作的:spec 文件

在上一篇关于 RPM 包构建的文章中,您看到源 RPMS 包含软件的源代码以及“规范”文件。 这篇文章深入研究了规范文件,其中包含有关如何构建 RPM 的说明。 同样,本文使用 fpaste 作为 example.

理解源代码

在开始编写规范文件之前,您需要对要打包的软件有所了解。 在这里,您正在查看 fpaste,一个非常简单的软件。 它是用 Python 编写的,是一个单文件脚本。 当新版本发布时,它会在 Pagure 上提供: https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz

如存档所示,当前版本为 0.3.9.2。 下载它,以便您查看存档中的内容:

$ wget https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz
$ tar -tvf fpaste-0.3.9.2.tar.gz
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/
-rw-rw-r-- root/root        25 2018-07-25 02:58 fpaste-0.3.9.2/.gitignore
-rw-rw-r-- root/root      3672 2018-07-25 02:58 fpaste-0.3.9.2/CHANGELOG
-rw-rw-r-- root/root     35147 2018-07-25 02:58 fpaste-0.3.9.2/COPYING
-rw-rw-r-- root/root       444 2018-07-25 02:58 fpaste-0.3.9.2/Makefile
-rw-rw-r-- root/root      1656 2018-07-25 02:58 fpaste-0.3.9.2/README.rst
-rw-rw-r-- root/root       658 2018-07-25 02:58 fpaste-0.3.9.2/TODO
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/en/
-rw-rw-r-- root/root      3867 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/en/fpaste.1
-rwxrwxr-x root/root     24884 2018-07-25 02:58 fpaste-0.3.9.2/fpaste
lrwxrwxrwx root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/fpaste.py -> fpaste

您要安装的文件是:

  • fpaste.py:应该安装到/usr/bin/。
  • docs/man/en/fpaste.1:手册,应该去 /usr/share/man/man1/。
  • COPYING:许可证文本,应该转到 /usr/share/license/fpaste/。
  • README.rst,TODO:转到 /usr/share/doc/fpaste 的杂项文档。

这些文件的安装位置取决于文件系统层次结构标准。 要了解更多信息,您可以在此处阅读: https://www.pathname.com/fhs/ 或查看您的手册页 Fedora 系统:

$ man hier

第 1 部分:我们在构建什么?

现在我们知道源中有哪些文件,以及它们的去向,让我们看一下规范文件。 您可以在此处查看完整文件: https://src.fedoraproject.org/rpms/fpaste/blob/master/f/fpaste.spec

这是规范文件的第一部分:

Name:   fpaste
Version:  0.3.9.2
Release:  3%{?dist}
Summary:  A simple tool for pasting info onto sticky notes instances
BuildArch:  noarch
License:  GPLv3+
URL:    https://pagure.io/fpaste
Source0:  https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz

Requires:    python3

%description
It is often useful to be able to easily paste text to the Fedora
Pastebin at https://paste.fedoraproject.org and this simple script
will do that and return the resulting URL so that people may
examine the output. This can hopefully help folks who are for
some reason stuck without X, working remotely, or any other
reason they may be unable to paste something into the pastebin

名称、版本等称为标签,在 RPM 中定义。 这意味着您不能只制作标签。 如果您这样做,RPM 将无法理解它们! 需要注意的标签是:

  • Source0:告诉 RPM 该软件的源存档所在的位置。
  • Requires:列出软件的运行时依赖项。 RPM 可以自动检测其中的一些,但在某些情况下必须手动提及它们。 运行时依赖项是系统上必须具有此包才能运行的功能(通常是包)。 这是 dnf 在您安装此软件包时检测是否需要拉入其他软件包的方式。
  • BuildRequires:列出此软件的构建时依赖项。 这些通常必须手动确定并添加到规范文件中。
  • BuildArch:构建此软件的计算机体系结构。 如果省略此标记,则将为所有受支持的架构构建软件。 值 noarch 意味着软件是独立于架构的(如 fpaste,它是纯粹用 Python 编写的)。

本节提供有关 fpaste 的一般信息:它是什么、正在制作 RPM 的版本、它的许可证等。 如果您安装了 fpaste,并查看它的元数据,您可以看到 RPM 中包含以下信息:

$ sudo dnf install fpaste
$ rpm -qi fpaste
Name        : fpaste
Version     : 0.3.9.2
Release     : 2.fc30
...

RPM 会自动添加一些额外的标签来代表它知道的东西。

至此,我们已经掌握了正在为其构建 RPM 的软件的一般信息。 接下来,我们开始告诉 RPM 做什么。

第 2 部分:准备构建

规范的下一部分是准备部分,用 %prep 表示:

%prep
%autosetup

对于 fpaste,这里唯一的命令是 %autosetup。 这只是将 tar 存档解压缩到一个新文件夹中,并为我们构建它的下一部分做好准备。 您可以在此处执行更多操作,例如应用补丁、为不同目的修改文件等等。 如果您确实查看了 Python 源 rpm 的内容,您会在那里看到很多补丁。 这些都在本节中应用。

通常,规范文件中的任何内容都带有 % 前缀是 RPM 以特殊方式解释的宏或标签。 通常这些会出现在大括号中,例如 %{example}。

第 3 部分:构建软件

下一部分是构建软件的地方,用“%build”表示。 现在,由于 fpaste 是一个简单的纯 Python 脚本,因此不需要构建它。 所以,在这里我们得到:

%build
#nothing required

但是,通常,您会在此处使用构建命令,例如:

configure; make

构建部分通常是规范中最难的部分,因为这是从源代码构建软件的地方。 这需要您知道该工具正在使用什么构建系统,这可能是众多系统之一:Autotools、CMake、Meson、Setuptools(用于 Python)等等。 每个都有自己的命令和风格。 您需要充分了解这些才能使软件正确构建。

第 4 部分:安装文件

构建软件后,需要将其安装在 %install 部分:

%install
mkdir -p %{buildroot}%{_bindir}
make install BINDIR=%{buildroot}%{_bindir} MANDIR=%{buildroot}%{_mandir}

RPM 在构建 RPM 时不会修改您的系统文件。 在工作安装中添加、删除或修改文件风险太大。 如果有东西坏了怎么办? 因此,RPM 创建了一个人工文件系统并在那里工作。 这称为 buildroot。 因此,在 buildroot 中,我们创建 /usr/bin,由宏 %{_bindir} 表示,然后使用提供的 Makefile 将文件安装到其中。

至此,我们在人工 buildroot 中安装了 fpaste 的构建版本。

第 5 部分:列出要包含在 RPM 中的所有文件

规范文件的最后一部分是文件部分,%files。 这是我们告诉 RPM 将哪些文件包含在它从该规范文件创建的存档中的地方。 fpaste 文件部分非常简单:

%files
%{_bindir}/%{name}
%doc README.rst TODO
%{_mandir}/man1/%{name}.1.gz
%license COPYING

请注意,在这里,我们没有指定 buildroot。 所有这些路径都是相对于它的。 %doc 和 %license 命令只是做更多的事情——它们创建所需的文件夹并记住这些文件必须放在那里。

RPM 非常聪明。 如果您在 %install 部分安装了文件,但没有列出它们,它会告诉您这一点,因为 example.

第 6 部分:在更改日志中记录所有更改

Fedora 是一个基于社区的项目。 许多贡献者维护和共同维护软件包。 因此,必须不要混淆对包进行了哪些更改。 为了确保这一点,规范文件包含最后一部分,变更日志,%changelog:

%changelog
* Thu Jul 25 2019 Fedora Release Engineering  - 0.3.9.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
 
* Thu Jan 31 2019 Fedora Release Engineering  - 0.3.9.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
 
* Tue Jul 24 2018 Ankur Sinha  - 0.3.9.2-1
- Update to 0.3.9.2
 
* Fri Jul 13 2018 Fedora Release Engineering  - 0.3.9.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
 
* Wed Feb 07 2018 Fedora Release Engineering  - 0.3.9.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
 
* Sun Sep 10 2017 Vasiliy N. Glazov  - 0.3.9.1-2
- Cleanup spec
 
* Fri Sep 08 2017 Ankur Sinha  - 0.3.9.1-1
- Update to latest release
- fixes rhbz 1489605
...
....

对规范文件的每次更改都必须有一个更改日志条目。 正如你在这里看到的,虽然我作为维护者更新了规范,但其他人也有。 清楚地记录更改有助于每个人了解规范的当前状态。 对于系统上安装的所有软件包,您可以使用 rpm 查看它们的更新日志:

$ rpm -q --changelog fpaste

构建 RPM

现在我们已准备好构建 RPM。 如果您想跟随并运行以下命令,请确保您按照上一篇文章中的步骤设置系统以构建 RPM。

我们将 fpaste 规范文件放在 ~/rpmbuild/SPECS 中,将源代码存档放在 ~/rpmbuild/SOURCES/ 中,现在可以创建源 RPM:

$ cd ~/rpmbuild/SPECS
$ wget https://src.fedoraproject.org/rpms/fpaste/raw/master/f/fpaste.spec

$ cd ~/rpmbuild/SOURCES
$ wget https://pagure.io/fpaste/archive/0.3.9.2/fpaste-0.3.9.2.tar.gz

$ cd ~/rpmbuild/SPECS
$ rpmbuild -bs fpaste.spec
Wrote: /home/asinha/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm

让我们看一下结果:

$ ls ~/rpmbuild/SRPMS/fpaste*
/home/asinha/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm

$ rpm -qpl ~/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm
fpaste-0.3.9.2.tar.gz
fpaste.spec

我们到了——源 rpm 已经构建。 让我们一起构建源代码和二进制 rpm:

$ cd ~/rpmbuild/SPECS
$ rpmbuild -ba fpaste.spec
..
..
..

RPM 将向您展示完整的构建输出,以及我们之前看到的每个部分的详细信息。 这个“构建日志”非常重要。 当构建没有按预期进行时,我们打包人员会花费大量时间来检查它们,跟踪完整的构建路径以查看问题所在。

真的是这样! 您准备好安装的 RPM 应该是:

$ ls ~/rpmbuild/RPMS/noarch/
fpaste-0.3.9.2-3.fc30.noarch.rpm

回顾

我们已经介绍了如何从规范文件构建 RPM 的基础知识。 这绝不是一份详尽的文件。 事实上,它根本不是文档,真的。 它只是试图解释事情是如何在幕后工作的。 这是一个简短的回顾:

  • RPM 有两种类型:源代码和二进制文件。
  • 二进制 RPM 包含要安装以使用该软件的文件。
  • 源 RPM 包含构建二进制 RPM 所需的信息:完整的源代码,以及如何在规范文件中构建 RPM 的说明。
  • 规范文件有不同的部分,每个部分都有自己的用途。

在这里,我们在本地构建了 RPM,在我们的 Fedora 安装。 虽然这是基本过程,但我们从存储库获得的 RPM 构建在具有严格配置和方法的专用服务器上,以确保正确性和安全性。 这 Fedora 打包管道将在以后的帖子中讨论。

您想开始构建软件包并帮助 Fedora 社区维护我们提供的大量软件? 你可以 从加入包集合维护者开始.

如有任何疑问,请发布到 Fedora 开发者邮件列表——我们总是乐于提供帮助!

参考

以下是构建 RPM 的一些有用参考: