用 4 步打包一个新的 Python 模块

`pyp2rpm` 命令使得创建 RPM 包和自动化这个过程成为可能。
1 位读者喜欢这篇文章。
Hands on a keyboard with a Python book

WOCinTech Chat。由 Opensource.com 修改。CC BY-SA 4.0

当你安装一个应用程序时,你通常安装的是一个包含应用程序的可执行代码和重要文件(例如文档、图标等)的软件包。在 Linux 上,应用程序通常打包为 RPM 或 DEB 文件,用户可以使用 `dnf` 或 `apt` 命令安装它们,具体取决于 Linux 发行版。然而,新的 Python 模块几乎每天都在发布,因此你很容易遇到尚未打包的模块。而这正是 `pyp2rpm` 命令存在的原因。

最近,我尝试安装一个名为 python-concentration 的模块。但结果不太顺利。

$ sudo dnf install python-concentration
Updating Subscription Management repositories.
Last metadata expiration check: 1:23:32 ago on Sat 11 Jun 2022 06:37:25.
No match for argument: python-concentration
Error: Unable to find a match: python-concentration

这是一个 PyPi 包,但它尚未作为 RPM 包提供。好消息是,你可以使用 `pyp2rpm` 通过一个相对简单的过程自己构建 RPM。

你需要两个目录才能开始。

$ mkdir rpmbuild
$ cd rpmbuild && mkdir SPECS

你还需要安装 `pyp2rpm`。

$ sudo dnf install pyp2rpm

1. 生成 spec 文件

任何 RPM 包的基础是一个名为 spec 文件 的文件。此文件包含有关如何构建软件包的所有信息,包括它需要的依赖项、它提供的应用程序版本、它安装的文件等等。当指向 Python 模块时,`pyp2rpm` 会为其生成一个 spec 文件,你可以使用它来构建 RPM。

以 python-concentration 为例,以下是如何生成 spec 文件:

$ pyp2rpm concentration > ~/rpmbuild/SPECS/concentration.spec

这是它生成的文件:

# Created by pyp2rpm-3.3.8
%global pypi_name concentration
%global pypi_version 1.1.5

Name:           python-%{pypi_name}
Version:        %{pypi_version}
Release:        1%{?dist}
Summary:        Get work done when you need to, goof off when you don't

License:        None
URL:            None
Source0:        %{pypi_source}
BuildArch:      noarch

BuildRequires:  python3-devel
BuildRequires:  python3dist(setuptools)

%description
Concentration [![PyPI version]( [![Test Status]( [![Lint Status]( [![codecov](

%package -n     python3-%{pypi_name}
Summary:        %{summary}
%{?python_provide:%python_provide python3-%{pypi_name}}

Requires:       (python3dist(hug) >= 2.6.1 with python3dist(hug) < 3~~)
Requires:       python3dist(setuptools)
%description -n python3-%{pypi_name}
Concentration [![PyPI version]( [![Test Status]( [![Lint Status]( [![codecov](


%prep
%autosetup -n %{pypi_name}-%{pypi_version}

%build
%py3_build

%install
%py3_install

%files -n python3-%{pypi_name}
%license LICENSE
%doc README.md
%{_bindir}/concentration
%{python3_sitelib}/%{pypi_name}
%{python3_sitelib}/%{pypi_name}-%{pypi_version}-py%{python3_version}.egg-info

%changelog
*  - 1.1.5-1
- Initial package.

2. 运行 rpmlint

为了确保 spec 文件符合标准,请在该文件上运行 `rpmlint` 命令。

$ rpmlint ~/rpmbuild/SPEC/concentration.spec
error: bad date in %changelog: - 1.1.5-1
0 packages and 1 specfiles checked; 0 errors, 0 warnings.

看起来变更日志条目需要一个日期。

%changelog
* Sat Jun 11 2022 Tux <tux@example.com> - 1.1.5-1

再次尝试 `rpmlint`

$ rpmlint ~/rpmbuild/SPEC/concentration.spec
0 packages and 1 specfiles checked; 0 errors, 0 warnings.

成功!

3. 下载源代码

要构建 RPM 包,你必须下载你要打包的代码。简单的方法是解析你的 spec 文件,找到源代码在 Internet 上的位置。

首先,使用 `dnf` 安装 `spectool` 命令。

$ sudo dnf install spectool

在某些发行版上,`spectool` 在 `rpmdevtools` 包中分发。

然后使用它下载源代码。

$ cd ~/rpmbuild
$ spectool -g -R SPEC/concentration.spec
Downloading: https://files.pythonhosted.org/...concentration-1.1.5.tar.gz
   6.0 KiB / 6.0 KiB    [=====================================]
Downloaded: concentration-1.1.5.tar.gz

这将创建一个 SOURCES 目录并将源代码归档文件放入其中。

4. 构建源软件包

现在你已经有了一个有效的 spec 文件,是时候使用 `rpmbuild` 命令构建源软件包了。如果你还没有 `rpmbuild`,请使用 `dnf` 安装 rpm-build 软件包(或者在尝试使用 `rpmbuild` 命令时接受终端提供的安装该软件包的建议)。

$ cd ~/rpmbuild
$ spectool -g -R SPEC/concentration.spec
Downloading: https://files.pythonhosted.org/...concentration-1.1.5.tar.gz
   6.0 KiB / 6.0 KiB    [=====================================]
Downloaded: concentration-1.1.5.tar.gz

`-bs` 选项代表 build source(构建源)。此选项为你提供一个 `src.rpm` 文件,这是一个必须为特定架构重建的通用软件包。

$ rpmbuild -bs SPECS/concentration.spec 
Wrote: ~/rpmbuild/SRPMS/python-concentration-1.1.5-1.el9.src.rpm

为你的系统构建一个可安装的 RPM。

$ rpmbuild --rebuild SRPMS/python-concentration-1.1.5-1.el9.src.rpm
error: Failed build dependencies:
	python3-devel is needed by python-concentration-1.1.5-1.el9.noarch

看起来这个软件包需要 Python 的开发库。安装它们以继续构建。这次构建成功并呈现更多输出(为了清晰起见,我在这里进行了缩写)

$ sudo dnf install python3-devel -y
$ rpmbuild --rebuild SRPMS/python-concentration-1.1.5-1.el9.src.rpm
[...]
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.TYA7l2
+ umask 022
+ cd /home/bogus/rpmbuild/BUILD
+ rm -rf concentration-1.1.5
+ RPM_EC=0
++ jobs -p
+ exit 0

你的 RPM 包已在 RPMS 子目录中构建完成。像往常一样使用 `dnf` 安装它。

$ sudo dnf install RPMS/noarch/python3-concentration*rpm

为什么不直接使用 PyPi?

将 Python 模块制作为 RPM 并非绝对必要。使用 PyPi 安装模块也是可以接受的,但 PyPi 会在你的个人检查和更新列表中添加另一个包管理器。当你使用 `dnf` 安装 RPM 时,你可以获得系统上安装的所有内容的完整列表。感谢 `pyp2rpm`,这个过程快速、简单且可自动化。

接下来阅读
标签
User profile image.
嘿,开源爱好者们!我是 Sumantro,来自印度(东部地区 - 英国统治时期的前首都,又名加尔各答)。我喜欢分享知识,撰写关于技术和经验的文章(主要是那些我每天尝试的)。

6 条评论

本教程似乎有缺陷。你提到了 -bs 选项,但它从未被使用。
我无法成功完成本教程。

哇,多么精彩的解释!我被逗乐了!

感谢这篇信息丰富的文章

知识共享许可协议本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.