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

327 阅读2分钟

当你安装一个应用程序时,你通常是在安装一个软件包,其中包含应用程序的可执行代码和重要文件,如文档、图标等。在 Linux 上,应用程序通常被打包成 RPM 或 DEB 文件,用户用dnfapt 命令安装它们,这取决于 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.生成规格文件

任何RPM包的基础都是一个叫做规格文件的文件。这个文件包含了所有关于如何构建软件包的信息,它需要哪些依赖,它提供的应用程序的版本,它安装了哪些文件,等等。当指向一个Python模块时,pyp2rpm 会为它生成一个spec文件,你可以用它来构建一个RPM。

用 python-concentration 作为一个任意的例子,这里是如何生成一个规格文件的。

$ 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

为了确保规格文件符合标准,对该文件运行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包,你必须下载你要打包的代码。做到这一点的简单方法是解析你的规格文件,在互联网上找到源代码的位置。

首先,用dnf 安装spectool 命令。

$ sudo dnf install spectool

然后用它来下载源代码。

$ 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.构建源码包

现在你有了一个有效的规范文件,所以是时候用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 选项代表构建源代码。这个选项给你一个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 ,这个过程是快速、简单和可自动的。