打包教程 1:banner
本教程通过打包 banner 程序来演示RPM打包。这是一个简单的带有 GNU Autotools 构建脚本的程序。
有关如何创建 RPM 文件的全面信息,请参阅 RPM Reference Manual。 如果您计划为 Fedora 存储库创建 RPM 软件包,请遵循以下流程:加入包维护者,包括遵循各种 Fedora 指南。
本教程旨在在 Fedora 40 系统上运行。 不过,它应该也适用于其他 Fedora 版本。只需将 f40
等字符串替换为您的版本号即可。 由于本教程使用了 Fedora 特定功能,而这些功能在其他环境中可能不可用,因此 CentOS Stream 或 Red Hat Enterprise Linux 等 Fedora 下游发行版可能会工作,也可能不会工作。
本教程以逐步的方式进行,其中大多数步骤都是编辑包的规范文件。 最终生成的规范文件列在最后,因此,如果不清楚如何应用特定更改,您可以查看那里。
创建包目录
在 Fedora 中,包构建指令被组织在所谓的 dist-git 存储库中。 每个包都有一个单独的存储库。 我们通过为本教程创建一个新目录来模仿这个系统。 在 dist-git 中,存储库名称与包名称匹配。 Fedora 的包命名规则写在 Naming Guidelines。 对于 banner 项目,包应该简单命名为 banner
。这也是 Fedora official banner package 的名称。
$ mkdir banner && cd banner
Spec 文件内部
RPM packages are configured by .spec
files. Tools such as rpmdev-newspec
can be used to generate empty specfiles for different purposes. For this tutorial, just create a file called banner.spec
and paste the following minimal specfile. It does not work yet, but we will try to build it and fix errors as we encounter them.
Name: banner
Version: 1.3.6
Release: %autorelease
Summary: Prints a short string to the console in very large letters
License: GPL-2.0-only
URL: https://github.com/pronovic/banner
Source: https://github.com/pronovic/banner/releases/download/BANNER_V%{version}/banner-%{version}.tar.gz
%description
This is a classic-style banner program similar to the one found in Solaris or
AIX in the late 1990s. It prints a short string to the console in very large
letters.
%prep
%autosetup
%build
%configure
%make_build
%install
%make_install
%files
%changelog
%autochangelog
规范文件以一组 tags 开头,例如 Name:
和 Version:
,接下来是 sections 例如 %description
和 %prep
。 每个标签占一行,而每个部分都会持续到下一个部分开始。
请注意,令人困惑的是,除了标记章节名称之外,百分号 %
还标记 RPM 宏。因此 %autosetup
,%configure
,%make_build
,%make_install
和 %autochangelog
不是章节。
标签
Version
包含打包软件的版本号。
Release
Fedora 中的 spec 文件更新、软件包重建和其他工作。这里使用的值 %autorelease
是https://docs.pagure.org/fedora-infra.rpmautospec/index.html[rpmautospec] 的一部分, 推荐用于Fedora 软件包 。它将 Release
与包的 Git 历史记录联系起来。 由于我们没有 Git 存储库,%autorelease
将计算为默认值 1。
通常,可以从上游 READNE 文件中复制 Summary
。 第一个字母应该是大写以避免 rpmlint
报错"。
License
使用 SPDX 许可证标识符描述生成的二进制包的许可证。它必须遵循 Fedora licensing guidelines。在实际中,确定正确的值通常意味着检查各个源文件中的许可证通知。上游开发者可能还需要被要求澄清或更正。在本教程中,我们仅采用上游的说法,即许可证是GNU Public License,版本 2。
URL
指向上游项目的网站,在本例中是 GitHub 存储库的页面。
Source
定义构建包时使用的上游源。通常,如本例所示,它是指向上游发布的 tarball 的 url,但它也可以是本地文件。如果需要,可以有多个 Source
标签。
章节
%description
通常可以从上游 README 文件中复制。
%prep
包含一个用于准备构建源的 shell 脚本。通常只是单个宏 %autosetup
,在这种情况下,它只是提取源代码。
%build
包含所需构建步骤的 shell 脚本,例如将源代码编译为二进制文件。由于 banner 程序的构建系统是https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html[Autotools],因此构建它需要运行 configure
和 make
。宏 %configure
和 %make_build
使用 Fedora 的编译标志和其他配置调用这些命令。
%install
包含一个用于将 %build
的结果复制到最初为空的 build root 目录中的 shell 脚本。由于 banner 使用 Autotools,因此使用宏`%make_install`。
%files
列出生成的包的内容。大多数情况下,这些文件来自 %install
创建的构建根目录,但文档和许可证文件也可以直接从源添加。此部分暂时留空,稍后填写。
%changelog
记录每个新软件包版本和发行版中的更改。更改日志数据可以通过 rpm --query --changelog PACKAGE_NAME
显示,这很有用,例如,可以查明是否包含特定的错误和安全补丁。它的值 %autochangelog
同样来自 rpmautospec
。它从 Git 提交消息填充变更日志。 由于我们没有 Git 存储库,因此变更日志将为空。
不需要的行可以用 #
注释掉。
您可以在 RPM 参考手册的 Spec file format 章节找到更多信息。
下载源文件
我们需要由 Source
标签定义的源码,通常被称为 upstream 源。使用 spectool
命令最容易实现这一点:
$ spectool -g banner.spec
现在,您的工作目录中应该有了在 Source
中列出的文件:
$ ls *.tar.gz banner-1.3.6.tar.gz
构建包
我们已准备好首次运行以构建源代码、二进制文件和调试包。此任务以及许多其他任务都是使用 fedpkg
工具完成的。Fedora 的生产版本是在 Koji 构建系统中构建的,它又使用 Mock 来管理隔离的构建环境。为了在本地尽可能接近生产构建,我们使用 fedpkg mockbuild
命令,该命令也调用 Mock:
$ fedpkg --release f40 mockbuild
Mock 创建的构建环境非常基础。 默认情况下它不包含 C 编译器,因此构建将失败。 输出中解释了原因:
checking whether the C compiler works... no configure: error: in `/builddir/build/BUILD/banner-6': configure: error: C compiler cannot create executables See `config.log' for more details RPM build errors: error: Bad exit status from /var/tmp/rpm-tmp.R4Tf16 (%build) Bad exit status from /var/tmp/rpm-tmp.R4Tf16 (%build)
通过将 BuildRequires:
行添加到规范文件来定义其他构建工具。 在Fedora中,GCC是标准编译器,因此我们需要为 gcc
添加一行 。 Autotools 也使用 make
,因此也应该为其添加一行。 在 Source
之后添加这些行:
BuildRequires: gcc
BuildRequires: make
再次运行 mockbuild 。
安装文件
rpm 将报错的下一件事是未打包的文件,即将要安装在系统中但未声明为属于该包的文件。我们需要在 %files
部分声明它们。修复这些错误是一个迭代过程。在spec文件中声明缺少文件后,再次运行 fedpkg
, 然后声明下一个丢失的文件等等。
我们将一一浏览文件列表。
可执行文件
Installed (but unpackaged) file(s) found: /usr/bin/banner
这是可执行的二进制程序。 /usr/bin
与许多其他系统目录一样,有一个 默认 rpm 宏。应始终在可用时使用宏,因此可执行文件在 %files
中列出,如下所示:
%files
%{_bindir}/banner
手册页
Installed (but unpackaged) file(s) found: /usr/share/man/man1/banner.1.gz
打包指南有一个关于 Manpages 的专门章节。按照其说明,手册页列表如下:
%{_mandir}/man1/banner.1.*
至此,mockbuild 已成功完成,但仍有更多文件需要添加到包中。
使用 rpmlint 检查结果
接下来,您应该通过在specfile、源rpm 和二进制rpm 上运行 rpmlint
来检查是否符合RPM 设计规则。 命令 fedpkg lint
执行以下操作:
$ fedpkg --release f40 lint
如果一切正常,应该不会有警告或错误。 为了教程的缘故,我们故意在前面的步骤中留下了一个错误:
banner.x86_64: E: zero-length /usr/share/doc/banner/NEWS
各种错误码的描述可以通过 rpmlint -e <error_code>
查询。 在本例中,必须删除不必要的零长度文件。 将文档行更改为
%doc AUTHORS ChangeLog README.md
再次运行 fedpkg mockbuild
和 fedpkg lint
观察警告是否已修复。
完整 spe 文件
这是 banner.spec
的最终版本:
Name: banner
Version: 1.3.6
Release: %autorelease
Summary: Prints a short string to the console in very large letters
License: GPL-2.0-only
URL: https://github.com/pronovic/banner
Source: https://github.com/pronovic/banner/releases/download/BANNER_V%{version}/banner-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: make
%description
This is a classic-style banner program similar to the one found in Solaris or
AIX in the late 1990s. It prints a short string to the console in very large
letters.
%prep
%autosetup
%build
%configure
%make_build
%install
%make_install
%files
%{_bindir}/banner
%{_mandir}/man1/banner.1.*
%license COPYING
%doc AUTHORS ChangeLog README
%changelog
%autochangelog
通过这个 spec 文件,您应该能够成功完成构建过程,并创建源代码和二进制 RPM 包。
检查结果
有了一个可用的 spec 文件和从中构建的 rpm,就可以检查结果。 在通过安装包检查结果之前,让我们做一些简单的检查。 RPM 包管理器 rpm
可用于此目的。
文件
列出包中包含的文件:
$ rpm --query --package --list results_banner/6/1.fc40/banner-1.3.6-1.fc40.x86_64.rpm /usr/bin/banner /usr/lib/.build-id /usr/lib/.build-id/01 /usr/lib/.build-id/01/360ae02508eaa0a77d216953b8b658a1e90b10 /usr/share/doc/banner /usr/share/doc/banner/AUTHORS /usr/share/doc/banner/ChangeLog /usr/share/doc/banner/README /usr/share/licenses/banner /usr/share/licenses/banner/COPYING /usr/share/man/man1/banner.1.gz
您可以看到包含了spec 文件 %files
部分中列出的所有文件。 另外,在`/usr/lib/.build-id下,有一个自动生成的文件。 它实际上是一个符号链接,将构建 ID 映射到 `banner
二进制文件以用于调试目的。
依赖
使用以下命令列出包的运行时依赖项:
$ rpm --query --package --requires results_banner/1.3.6/1.fc40/banner-1.3.6-1.fc40.x86_64.rpm libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.34)(64bit) libc.so.6(GLIBC_2.4)(64bit) rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(PayloadIsZstd) <= 5.4.18-1 rtld(GNU_HASH)
要检查 Fedora 存储库中的哪些包提供这些依赖项,您可以使用 dnf repoquery
:
$ dnf -C repoquery --whatprovides 'libc.so.6()(64bit)' glibc-0:2.38-16.fc40.x86_64 glibc-0:2.38-7.fc40.x86_64
您将看到 banner 的唯一依赖项是 glibc
,它提供了 libc.so.6
以及 rtld(GNU_HASH)
中的符号。
rpmlib
要求很特殊。 这些指定了 rpm 软件包本身使用的各种 rpm 功能,限制了可用于安装软件包的 rpm
版本。
Provides
相反,要检查包提供的功能,您可以执行以下操作:
$ rpm --query --package --provides results_banner/1.3.6/1.fc40/banner-1.3.6-1.fc40.x86_64.rpm banner = 1.3.6-1.fc40 banner(x86-64) = 1.3.6-1.fc40
这个包的提供非常简单。 它只是以简单且特定于架构的形式提供自己的名称。
安装
作为最终检查,可以安装并运行该包:
$ sudo dnf -C -y install ./results_banner/1.3.6/1.fc40/banner-1.3.6-1.fc40.x86_64.rpm $ banner success ##### # # ##### ##### ####### ##### ##### # # # # # # # # # # # # # # # # # # # # # ##### # # # # ##### ##### ##### # # # # # # # # # # # # # # # # # # # # # ##### ##### ##### ##### ####### ##### ##### ..
要清理系统,请撤消安装:
$ sudo dnf -C -y history undo last
在 Fedora 基础设施中构建
即使该包还不是 Fedora 发行版的一部分,也可以执行 scratch build 以确保该包在 Fedora 的 Koji 构建系统中成功构建,并且可以在 Fedora 支持的所有体系结构中成功构建。这种构建是通过将源 rpm 包传递给 fedpkg scratch-build
来启动的。
请注意,Koji 使用 Kerberos 进行身份验证。 有关详细信息,请参阅 Acquiring Kerberos Ticket。
$ fedpkg --release f40 scratch-build --srpm results_banner/1.3.6/1.fc40/banner-1.3.6-1.fc40.src.rpm Building banner-1.3.6-1.fc40.src.rpm for f40-candidate Created task: 92465688 Task info: https://koji.fedoraproject.org/koji/taskinfo?taskID=92465688 Watching tasks (this may be safely interrupted)...
您可以在浏览器中打开任务信息链接来查看构建进度、日志和结果。 命令行程序还会报告发生的进度。 成功执行看起来像这样:
92465688 build (f40-candidate, banner-1.3.6-1.fc40.src.rpm): free 92465688 build (f40-candidate, banner-1.3.6-1.fc40.src.rpm): free -> open (buildvm-ppc64le-25.iad2.fedoraproject.org) 92465698 rebuildSRPM (noarch): open (buildvm-s390x-24.s390.fedoraproject.org) 92465745 buildArch (banner-1.3.6-1.fc40.src.rpm, x86_64): free 92465748 buildArch (banner-1.3.6-1.fc40.src.rpm, s390x): open (buildvm-s390x-19.s390.fedoraproject.org) 92465746 buildArch (banner-1.3.6-1.fc40.src.rpm, aarch64): open (buildvm-a64-26.iad2.fedoraproject.org) 92465747 buildArch (banner-1.3.6-1.fc40.src.rpm, ppc64le): open (buildvm-ppc64le-11.iad2.fedoraproject.org) 92465744 buildArch (banner-1.3.6-1.fc40.src.rpm, i686): open (buildhw-x86-12.iad2.fedoraproject.org) 92465698 rebuildSRPM (noarch): open (buildvm-s390x-24.s390.fedoraproject.org) -> closed 1 free 5 open 1 done 0 failed 92465745 buildArch (banner-1.3.6-1.fc40.src.rpm, x86_64): free -> open (buildhw-x86-06.iad2.fedoraproject.org) 92465745 buildArch (banner-1.3.6-1.fc40.src.rpm, x86_64): open (buildhw-x86-06.iad2.fedoraproject.org) -> closed 0 free 5 open 2 done 0 failed 92465748 buildArch (banner-1.3.6-1.fc40.src.rpm, s390x): open (buildvm-s390x-19.s390.fedoraproject.org) -> closed 0 free 4 open 3 done 0 failed 92465746 buildArch (banner-1.3.6-1.fc40.src.rpm, aarch64): open (buildvm-a64-26.iad2.fedoraproject.org) -> closed 0 free 3 open 4 done 0 failed 92465744 buildArch (banner-1.3.6-1.fc40.src.rpm, i686): open (buildhw-x86-12.iad2.fedoraproject.org) -> closed 0 free 2 open 5 done 0 failed 92465688 build (f40-candidate, banner-1.3.6-1.fc40.src.rpm): open (buildvm-ppc64le-25.iad2.fedoraproject.org) -> closed 0 free 1 open 6 done 0 failed 92465747 buildArch (banner-1.3.6-1.fc40.src.rpm, ppc64le): open (buildvm-ppc64le-11.iad2.fedoraproject.org) -> closed 0 free 0 open 7 done 0 failed 92465688 build (f40-candidate, banner-1.3.6-1.fc40.src.rpm) completed successfully
Want to help? Learn how to contribute to Fedora Docs ›