python项目使用setuptools和rpmbuild构建rpm包
文章目录
- python项目使用setuptools和rpmbuild构建rpm包
- 一、setuptools
- 二、使用rpmbuild,编写.spec文件构建rpm包
- 三、使用pyinstaller
- 四、参考文献:
一、setuptools
作为 Python 标准的打包及分发工具,setuptools 可以说相当地简单易用。它会随着 Python 一起安装在你的机器上。你只需写一个简短的 setup.py 安装文件,就可以将你的 Python 应用打包。
1、setuptools的关键就是setup.py的编写了,这是我的setuptools使用的一些配置。
import setuptoolsdesktop_path = '/usr/share/applications/'
icon_path = '/usr/share/icons/hicolor/scalable/apps/'setuptools.setup(name='pw-policy',version='1.0',description='pam config tool',author='',author_email='',url='',packages=['pw'],#启用清单文件MANIFEST.ininclude_package_data=True,#install_requires=['PyQt5'],entry_points={'console_scripts':['pw_policy = pw.pam_main:run']},data_files=[(desktop_path,['pw/pw-policy.desktop']),(icon_path,['pw/pw-policy.png']),],
)
只列举几个重点吧:
(1)packages=[‘’]
需要处理的包目录(包含
__init__.py
的文件夹),这里通常使用 find_packages(),它默认在和setup.py同一目录下搜索各个含有__init__.py
的目录。 但我没用到find_packages(),项目比较简单,直接写了我py文件在的目录名。
(2)include_package_data=True,
功能为引入非 Python 文件。默认情况下只会对 Python 源码进行打包,但是如果我们想要将其他静态文件,例如 css 文件,或是 qt 的一些 ui 文件打包进去,就需要使用这个参数。
在setup.py同一目录下建一个清单文件
MANIFEST.in
,在清单文件中列出想引入的非py文件的目录,该目录下的所有非py文件都会被引入。(3)entry_points 可以用来创建控制台脚本。我们看上面的例子就会非常好理解:
entry_points = {'console_scripts': ['test = test.help:main'] }
这样在安装完毕之后,我们可以直接在控制台输入
test
,这样是可以运行test.help
模块下的main
函数。就把test放在了/usr/bin/目录下。(4) data_files=[ ],
看到有这样描述:如果数据文件存在于项目外,则可以使用 data_files 参数或者 MANIFEST.in 文件进行管理。如果用于源码包,则使用 MANIFEST.in;如果用于 wheel,则使用 data_files。
data_files=[(‘mydata’, [‘data/conf.yml’])]
即为上述设置将在打包 wheel 时,将 data/conf.yml 文件添加至 mydata 目录。 在之后打包rpm时,data_files参数和MANIFEST.in 文件都起作用了。我这里是要把应用放到桌面,所以要创建.desktop文件放到/usr/share/applications/,应用图标放到/usr/share/icons/hicolor/scalable/apps/。这个路径什么时候起作用?
.desktop文件可以百度下,关键在参数Exec= ,表示程序执行路径。
2、之后执行编译(本质上是新建了一个build目录,而后将指定的packages列表包下的所有".py"文件和MANIFEST.in 文件指定目录下的所有非py文件拷贝过去),同时生成.egg-info文件夹,存放打包中间结果。
python setup.py build
3、打包操作,文件名为 应用名-版本号.tar.gz。也是保存在 dist 文件夹下。
python setup.py sdist --formats=gztar
有了上面的 setup.py 文件,我们就可以打出各种安装包,主要分为两类:sdist 和 bdist。
bdist可打包whl和egg格式、rpm包、windows下的安装包。
4、之后可以安装:下面的安装命令会将当前的 Python 应用安装到当前 Python 环境的 site-packages
目录下,这样其他程序就可以像导入标准库一样导入该应用的代码了。
pip install dist/devops-0.1.1.tar.gz
或不打包直接
python setup.py install
这里我们如果想要删除安装的包,可以使用 pip uninstall xxx
来完成删除。
二、使用rpmbuild,编写.spec文件构建rpm包
为什么还要用这种方式构建rpm包。
原生 Python 软件包的打包格式由 Python Packaging Authority (PyPA) 规范定义。大多数 Python 项目使用
distutils
或setuptools
实用程序进行打包,并在setup.py
文件中定义的软件包信息。然而,创建原生 Python 软件包可能会随着时间而有新的演变。有关新兴打包标准的更多信息,请参阅 pyproject-rpm-macros。本章论述了如何将
setup.py
的 Python 项目打包到一个 RPM 软件包中。与原生 Python 软件包相比,此方法提供以下优点:
- 可以对 Python 和非 Python 软件包的依赖项,并严格由
DNF
软件包管理器强制执行。- 您可以用加密的方式为软件包签名。使用加密签名,您可以验证、集成和测试 RPM 软件包的内容与操作系统的其余部分。
- 您可以在构建过程中执行测试。
1、安装rpmbuild及生成相关目录
yum install rpmdevtools
yum install -y rpm-build
rpmdev-setuptree
–BUILD #编译之前,如解压包后存放的路径
–BUILDROOT #编译后存放的路径
–RPMS #打包完成后rpm包存放的路径
–SOURCES #源包所放置的路径
–SPECS #spec文档放置的路径
–SPRMS #源码rpm包放置的路径
2、源码打包放入SOURCES 。编写spec文件,我的.spec文件
Name: pw-policy
Version: 1.0
Release: 1
Summary: A pam config tool
License: MulanPSL-2.0
URL: ??
Source0: %{name}-%{version}.tar.gz
BuildArch: noarchBuildRequires: python3-devel python3-setuptools
Requires: python3 python3-PyQt5-base%description
A pam config tool%prep
%autosetup -p1 -n %{name}-%{version}%build
%py3_build%install
%py3_install%files
%{_bindir}/pw_policy
%{_datadir}/icons/hicolor/scalable/apps/pw-policy.png
%{_datadir}/applications/pw-policy.desktop
%{python3_sitelib}/pw/
%{python3_sitelib}/pw_policy-*.egg-info/%changelog
* ???
- Package init
主要参考Redhat官方文档第 3 章 打包 Python 3 RPM中给的spec和写好setup.py的python项目,非常棒。
文档没提到的点:
BuildArch: noarch
noarch表示你的应用会独立于操作系统架构
个人觉得spec后面就是对源码的一系列操作、
%prep
%autosetup -p1 -n %{name}-%{version}就是解压源码压缩包%build
%py3_build%install
%py3_install
%py3_build 和 %py3_install 宏会分别运行
setup.py build
和setup.py install
命令。%files
指明哪些需要打包。打包.desktop和图标文件,%{python3_sitelib}中python包文件,
pw_policy在/usr/bin中,也要打包。
3、.spec文件写完,打包:
rpmbuild -ba SPECS/xxx.spec
构建时无python3-devel:yum install python3-devel
进入 RPMS就可以发现rpm包了。
4、安装rpm包
rpm -qpi xxx.rpm查看包信息rpm -ivh xxx.rpm安装
5、效果
三、使用pyinstaller
1、pyinstaller介绍
pyinstaller可以把python项目打包为windows的exe、macos的包和linux下的各种包(Ubuntu的deb,Redhat的rpm,Arch的pacman)。
使用PyInstaller会将应用程序与相关数据文件绑定到Linux可执行文件中。此绑定过程的输出是一个文件夹。制作Linux下的包,还需要fpm工具
windows下制作Windows installer,还需要工具InstallForge 。
2、pyinstaller输出可执行文件
简单地使用demo
pyinstaller --add-data "penguin.svg:." --name "hello-world" app.py
–add-data:数据文件,如图标,css、qss文件等。可以多次使用。注意格式
–name:应用名字
-F:会输出一个文件,但打开时间会变慢
pyinstaller输出dist文件夹、build文件夹和一个.spec文件。
dist文件夹中包含可执行文件,build文件夹中为构建过程中的文件,.spec是这次构建生成后记录的配置文件。
3、使用fpm打rpm包,并实现桌面应用
之后按文档使用fpm可以进一步打包成各种Linux包,可以看教程。fpm和sepc是两个构建rpm包的方式。
前面使用pyinstaller生成的可执行文件和用fpm打包为rpm形成桌面应用,都可以成功。
4、使用spec打rpm包
但当我使用spec构建时,编写如下spec:
%global debug_package %{nil}AutoReqProv: no
Name: pw-policy
Version: 1.0
Release: 1
Summary: A pam config tool
License: MulanPSL-2.0
URL: ??
Source0: %{name}.tar
BuildRequires: python3 python-pip%description
A pam config tool%prep
%setup -c -n %{name}-%{version}%build
%py3_build
python3 -m pip install pyinstallerpyinstaller --add-data "./pw-policy.png:." --add-data "./pw-policy.qss:." --name "pw-policy" ./pam_main.py %install
%{__mkdir_p} %{buildroot}/opt
%{__mkdir_p} %{buildroot}%{_datadir}/applications/
%{__mkdir_p} %{buildroot}%{_datadir}/icons/hicolor/scalable/appscp -r ./dist/pw-policy %{buildroot}/optinstall -m 644 ./pw-policy.png %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/
install -m 644 ./pw-policy.desktop %{buildroot}%{_datadir}/applications/%files
%{_datadir}/icons/hicolor/scalable/apps/pw-policy.png
%{_datadir}/applications/pw-policy.desktop
/opt/pw-policy/%changelog
* ???
- Package init
rpmbuild 打包rpmbuild -ba SPECS/xxx.spec能成功,但pyinstaller输出的dist文件夹中可执行文件一直报某个模块找不到,发现网上很多人用pyinstaller在很多情况下都有遇到某个模块找不到的情况。可以使用–hidden-import 找不到的模块,但我第一个模块找不到时成功了,第二个模块再用–hidden-import便不成功。遂使用了setuptools配合spec文件打包。
四、参考文献:
-
Redhat官方setuptools加spec打包rpm。第 3 章 打包 Python 3 RPM
-
setuptool教程:
Python的打包工具(setup.py)实战篇https://www.cnblogs.com/yinzhengjie/p/14124623.html
Python打包之setuptoolshttps://www.cnblogs.com/Zzbj/p/11535625.html
Python 打包分发工具 setuptools 简介https://mathpretty.com/13655.html#%E5%AE%89%E8%A3%85%E5%BA%94%E7%94%A8
-
spec教程:
使用spec与fpm 2种方式进行rpm打包https://developer.aliyun.com/article/417304
How to create an RPM package/zh-cnhttps://fedoraproject.org/wiki/How_to_create_an_RPM_package/zh-cn#%E6%96%B0%E5%BB%BA%E4%B8%80%E4%B8%AA_.spec_%E6%96%87%E4%BB%B6
-
pyinstaller
Packaging PyQt5 applications for Linux with PyInstaller & fpmhttps://www.pythonguis.com/tutorials/packaging-pyqt5-applications-linux-pyinstaller/
How to create an RPM package/zh-cnhttps://fedoraproject.org/wiki/How_to_create_an_RPM_package/zh-cn#%E6%96%B0%E5%BB%BA%E4%B8%80%E4%B8%AA_.spec_%E6%96%87%E4%BB%B6
-
pyinstaller
Packaging PyQt5 applications for Linux with PyInstaller & fpmhttps://www.pythonguis.com/tutorials/packaging-pyqt5-applications-linux-pyinstaller/