首页 > 解决方案 > 如何在基于 Linux 的操作系统上分发基于 python 的软件

问题描述

我想要实现的压缩版本:从我的 source.py 源代码创建 .rpm 和 .deb 包,并确保在基于 deb/rpm 的 Linux 发行版上安装它们时解决所有依赖项。

更多细节:假设我创建了一个软件,它位于这样的文件夹结构中:

---MyProgram          Folder
   ---MyProgram       Folder
       ---img         Folder
          ---logo.ico File
       ---media       Folder
          ---head.txt File
       ---__init__.py File
       ---source.py   File
       ---a.py        File
   ---LICENSE         File
   ---README.md       File
   ---setup.py        File

文件 setup.py 包含以下内容:

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="MyProgram",
    version="0.0.1",
    author="First Last",
    author_email="email@memore.com",
    description="A tool to create nice things",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://google.com",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.7',
    data_files=[
    ('.../MyProgram/img/logo.ico'),
    ('.../MyProgram/media/head.txt'),
],
)

我现在跑

python setup.py sdist bdist_rpm

从“.../MyProgram”下的 cmd 行。创建了两个文件夹“dist”和“build”以及“MyProgram.tar.gz”和两个 rpm 的“MyProgram-noarch.rpm”和“MyProgram-src.rpm”。当我尝试在 fedora 31 下安装“noarch.rpm”时,进程成功结束,但没有创建“快捷方式”,当我在 cmd 行中键入 MyProgram 时,找不到它。

rpm -ql MyFilter

确实找到它并输出一堆路径:

/usr/lib/python3.7/site-packages/MyProgram/...
/usr/lib/python3.7/site-packages/MyProgram/source.py
/usr/lib/python3.7/site-packages/MyProgram/a.py
....

这告诉我,我的安装至少复制了基本文件系统。但我也看到所有原始 .py 文件仍然是 .py 文件。

我的问题:

如果这个解决方案是微不足道的,我只是忽略了它,我真的很抱歉打扰你,但 atm 我只是看不到它。有相关信息并且我已经查看过的网站:

https://docs.python.org/2.0/dist/creating-rpms.html

https://github.com/AppImage/AppImageKit/wiki/Bundling-Python-apps

Python 3.5 使用 pyinstaller 生成的可执行文件创建 .rpm

https://github.com/junaruga/rpm-py-installer

https://www.pyinstaller.org/

https://packaging.python.org/overview/#python-source-distributions

https://packaging.python.org/overview/

https://pyinstaller.readthedocs.io/en/stable/usage.html

https://pyinstaller.readthedocs.io/en/stable/installation.html

https://python-packaging-tutorial.readthedocs.io/en/latest/setup_py.html

标签: python-3.xlinuxrpmdeb

解决方案


只是我的两分钱,而不是一个完整的答案。主要涉及 RPM 包装。

bdist_rpm选项似乎很简单,但是您几乎无法控制.spec它生成/使用的文件的逻辑,并且无法执行诸如脚本等花哨的东西。

也就是说,除非您采用让它生成.spec文件并退出的方法(而不是构建最终 RPM)。从文档

如果您愿意,可以将这三个步骤分开。您可以使用 --spec-only 选项使 bdist_rpm 只创建 .spec 文件并退出;在这种情况下,.spec 文件将被写入“分发目录”——通常是 dist/,但可以使用 --dist-dir 选项进行自定义。(通常,.spec 文件在 bdist_rpm 创建的临时目录中的“构建树”深处结束。)

但出于偏好和一致性的考虑,我建议遵循特定于发行版的指南来打包 Python 应用程序。

这样,您将更符合您正在构建的发行版。

虽然这不是最简单的方法。您将不得不翻阅一些文档。基本上,如果你正在为 CentOS/RHEL 构建任何东西,那么应该遵守 Fedora 的打包指南。

您可以在此处找到额外的参考资料,其中.spec包含用于构建同一应用程序的 Python 2 和 3 版本的示例文件。

对于这整个“像发行版一样构建”的东西,您肯定会想要考虑使用mock这项工作,在 chroot 中构建您的包。

至于“快捷方式”问题,您必须setup.py声明一些控制台脚本,以便在安装软件包时创建一个。例如来自lastversion 的 setup.py

entry_points={"console_scripts": ["lastversion = lastversion:main"]},

This entry will result in a "binary" lastversion created/installed (which runs the defined function) when you install your Python package.

Subsequently, in the spec files, the macro %py2_install will make use of setup.py to create the same launcher program.

And you will then be able to ensure that launcher is packaged by placing it in the files section of the spec file:

%files -n python3-myapp
%license COPYING
%doc README.rst
%{python3_sitelib}/%{srcname}/
%{python3_sitelib}/%{srcname}-*.egg-info/
%{_bindir}/myapp

推荐阅读