python-3.x - 如何在基于 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 文件。
我的问题:
- 我如何“制作” rpm 以便所有依赖项都包含在 rpm 中,或者至少在安装 rpm 时由 dnf/apt/yum 解决?换句话说:是否可以将所有依赖项捆绑到 rpm/deb 中,例如在 .exe 中?
- 如何指定像“/usr/bin”或“usr/share”这样的路径作为安装目标目录?
- 如何添加捆绑到 rpm/deb 中的启动器应用程序?
- 以上是这样做的好方法吗?
如果这个解决方案是微不足道的,我只是忽略了它,我真的很抱歉打扰你,但 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://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
解决方案
只是我的两分钱,而不是一个完整的答案。主要涉及 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
推荐阅读
- sql-server - 无法将 Excel 文件导入 Microsoft SQL Server Management Studio
- java - Java8中子列表的分区列表
- javascript - Node JS (Requests Loggin In Auth) 加密以及如何做?
- java - 为什么@DiscriminatorValue JPA 注释不能与抽象类一起使用?
- python-3.x - 这行在 Makefile 中是什么意思?
- amazon-web-services - 无法通过网络负载均衡器访问 Istio 插件
- python - Keras 中 Conv1D 层的输出大小
- node.js - Discordjs args 检查它是否是一个词
- web-scraping - 如何告诉Lua无限点击“加载按钮”?
- java - 方法之前的@Order (which =) 注释