本文记录在Windows上,使用PyCharm打包Python项目的操作。
打开PyCharm的设置,File --> Settings --> Python Interpreter
,选择环境,点击+
,搜索pyinstaller
,点击安装。
pyinstaller [options] script [script …] | specfile
在PyCharm,打开终端Terminal,输入命令pyinstaller命令,举例:
pyinstaller --icon icon.ico --name "芝麻酱" -F main.py scrapyimages.py --add-data "fake_useragent_0.1.11.json;." --add-binary "C:\Anaconda3\Library\bin\mkl_intel_thread.1.dll;."
一些常用的选项:
-F, --onefile 打包成一个文件
-i, --icon 可执行程序的图标
-n, --name 可执行程序文件名
-w, --noconsole 不显示控制台
-d, --debug 带调试信息
--add-data 添加依赖文件
--add-binary 添加库
PyInstaller更多用法见:Using PyInstaller — PyInstaller documentation。另:
conda activate [myenv]
执行pyinstaller options.. myscript.py
,PyInstaller会创建一个规范说明文件name.spec
(specification file)。事实上,运行pyinstaller的参数都在这里。因此,更建议直接在name.spec
上修改,再打包。
可以使用pyinstaller -F main.py
生成main.spec
,再编辑该文件:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['main.py', 'scrapyimages.py'],
pathex=['D:\\workspace\\images_crawler\\src'],
binaries=[('C:\\Anaconda3\\Library\\bin\\mkl_intel_thread.1.dll', '.')],
datas=[('D:\\workspace\\images_crawler\\src\\fake_useragent_0.1.11.json', '.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='芝麻酱',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True , icon='icon.ico')
然后运行:
pyinstaller -F main.spec
关于规范说明文件说见:Using Spec Files — PyInstaller documentation。
(1)Cannot load mkl_intel_thread.1.dll
打包完,双击.exe
文件,控制台输出错误:
Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.1.dll
在电脑上找到mkl_intel_thread.1.dll
的位置,C:\Anaconda3\Library\bin\mkl_intel_thread.1.dll
,将该动态库添加到main.spec
(2)软件需要外部数据
我打包的这个应用,用到这个文件fake_useragent_0.1.11.json
,打包时,不能用相对路径,原因是[1]:
运行可执行文件时,会先将可执行文件进行压缩再执行,压缩的位置在 /tmp 下。因此,被打包进去的数据文件在被解压的路径下,而程序是在运行的路径下搜索,即可执行文件的目录下,所以找不到数据文件。
因此,我这样处理:
from fake_useragent import UserAgent
#ua = UserAgent(path='./fake_useragent_0.1.11.json')
cur_dir = os.path.dirname(os.path.abspath(__file__))
ua = UserAgent(path = os.path.join(cur_dir, 'fake_useragent_0.1.11.json'))
(3)运行完退出
程序运行完,控制台就关了。想让控制台在程序执行完不关闭,方法很多。
input('按任意键关闭窗口')
os.system('pause')
(4)程序运行一会,退出,没有错误信息
我将打包好的可执行文件放到其他电脑运行,双击后,运行一会,就退出,没有错误信息,也不是闪退。首先,加上-d
选项,重新打包成带有调试信息的可执行文件。再次运行,得到如下信息:
C:\Users\admin\Desktop>芝麻酱.exe
[11884] PyInstaller Bootloader 3.x
[11884] LOADER: executable is C:\Users\admin\Desktop\芝麻酱.exe
...
[4100] LOADER: Running pyi_rth_pyqt5.py
[4100] LOADER: Running pyi_rth_mplconfig.py
[4100] LOADER: Running pyi_rth_mpldata.py
[4100] LOADER: Running pyi_rth_certifi.py
[4100] LOADER: Running pyi_rth__tkinter.py
[4100] LOADER: Running main.py
[11884] LOADER: Back to parent (RC: -1066598274)
[11884] LOADER: Doing cleanup
[11884] LOADER: Freeing archive status for C:\Users\admin\Desktop\芝麻酱.exe
我估计问题出在tkinter
包,搜索了下,说是缺少libiomp5md.dll
[2]。在Anaconda目录搜索该文件,找到C:\Anaconda3\Library\bin\libiomp5md.dll
,将libiomp5md.dll
拷贝到main.py
同一个目录下,并添加到spec文件的datas
中,重新打包文件。
datas=[('libiomp5md.dll', '.')]
遗憾的是,问题依旧,知道方法的,烦请留言告知。
参考文献:
[1] Pyinstaller将外部数据文件打包到可执行文件中(onefolder or onefile)教程_m0_37477175的博客-CSDN博客
[2] python – PyInstaller .exe file terminates early without an error message – Stack Overflow