直接安装:pip install pyinstaller
或者源码安装:https://pypi.org/project/PyInstaller/#files
tar zxvf PyInstaller-3.6.tar.gz PyInstaller-3.6
cd PyInstaller-3.6
sudo python3 setup.py build
sudo python3 setup.py install
更多可以参考:http://www.pyinstaller.org
参考手册:https://pyinstaller.readthedocs.io/en/v3.6/
关于打包瘦身:https://www.jianshu.com/p/a4339550d7c1
【官方使用文档】
pyinstaller [-F/-D] [-w/-c] [-i xxx.ico] xxx.py/xxx.spec
–add-data SRC;DEST:指定需要添加非二进制文件路径或者文件夹路径,比如图片和pdf文件等,这个选项可以使用多次。这个命令其实就是将需要的文件或者文件夹拷贝到指定的路径下,在-D模式下,可以看情况在程序打包完成后自己手动拷贝过去。
–add-binary SRC;DEST:指定需要添加的二进制文件路径,比如DLL文件、动态链接库或者共享文件对象等,这个选项可以使用多次。同-add-data命令一样,是一个拷贝数据的功能。
-p DIR/–paths DIR:指定import语句的查找路径(与PYTHONPATH一样),多个路径之间可以使用分号“;”连接,或者多次使用这个选项来进行指定。
–hidden-import MODULENAME/–hiddenimport MODULENAME:指定脚本中需要隐式导入的模块,比如在__import__、imp.find_module()、exec、eval等语句中导入的模块,这些模块PyInstaller是找不到的,需要手动指定导入,这个选项可以使用多次。
–additional-hooks-dir HOOKSPATH:指定额外hook文件(可以是py文件)的查找路径,这些文件的作用是在PyInstaller运行时改变一些Python或者其他库原有的函数或者变量的执行逻辑(并不会改变这些库本身的代码),以便能顺利的打包完成,这个选项可以使用多次。
–runtime-hook RUNTIME_HOOKS:指定自定义的运行时hook文件路径(可以是py文件),在打好包的exe程序中,在运行这个exe程序时,指定的hook文件会在所有代码和模块之前运行,包括main文件,以满足一些运行环境的特殊要求,这个选项可以使用多次。
–exclude-module EXCLUDES:指定可以被忽略的可选的模块或包,因为某些模块只是PyInstaller根据自身的逻辑去查找的,这些模块对于exe程序本身并没有用到,但是在日志中还是会提示“module not found”,这种日志可以不用管,或者使用这个参数选项来指定不用导入,这个选项可以使用多次。
–key KEY:指定用于Python字节码加密的key,key是一个16个字符的字符串。
-D
模式程序的运行:-F
模式程序的运行:__file__
: 所有基于模块的使用到__file__
属性的代码,在源码运行时表示的是当前脚本的绝对路径,但是打包后就是当前模块的模块名(即文件名xxx.py)。
sys.frozen
:源码运行时没有这个属性,打包后的程序添加了这个属性,值为True。
sys._MEIPASS
: 源码运行时没有这个属性,打包后的程序添加了这个属性,表示程序运行的绝对路径。对于-D模式程序,表示的是这个exe程序所在文件夹的绝对路径,对于-F模式程序表示的是_MEIxxxxxx的文件夹绝对路径,_MEIxxxxxx为exe解压后创建的临时运行环境的文件夹名称,对于exe程序每一次运行来说,它是唯一的。
sys.excutable
:代码运行时表示运行的解释器绝对路径,如C:\Python36\python.exe,在打包的程序中就是exe程序文件的绝对路径,这个是用来定位用户运行该程序的真实位置。
sys.argv[0]
:一般来说就是运行程序的绝对路径,但是在不同平台或者不同的方式启`动程序时,会有所不同,比如通过符号链接运行的程序sys.argv[0]就是符号名称,而不是真实的程序路径。
–add-data这种通过拷贝形式的数据文件,在-D模式下如果在运行时修改了,那么对应的数据文件是真的被修改了,但是在-F模式下,由于每次运行会单独创建一个临时运行环境,修改的内容也是临时运行环境中的内容,并且运行完后会自动删除临时运行环境,所以这种数据文件是无法直接更改exe中的数据文件的,也就意味着每次运行程序,数据文件都会是exe程序中原来的那一份,修改的内容会随着临时运行环境的关闭而删除了,不会同步到exe程序中的。
Analysis参数scripts:也是第一个参数,它是一个脚本列表,可以传入多个py脚本,效果与命令行中指定多py文件相同,即py文件不止一个时,比如“pyinstaller xxx1.py xxx2.py”,pyinstaller会依次分析并执行,并把第一个py名称作为spec和dist文件下的文件夹和程序的名称。
Analysis参数pathex:同命令“-p DIR/–paths DIR”,其实默认就有一个spec的目录,如果使用命令添加的话,会首先添加命令中指定的目录,再添加默认的路径。
Analysis参数datas:即添加数据文件,命令是–add-data,spec文件中是Analysis的datas=[]参数,datas是一个元素为元组的列表,每个元组有两个元素,都必须是字符串类型,元组的第一个元素为数据文件或文件夹,元组的第二个元素为运行时这些文件或文件夹的位置。例如:datas=[(‘src/README.txt’, ‘.’), ],也可以在命令行中这样写:pyinstaller --add-data ‘src/README.txt;.’ myscript.py,表示打包时将文件src/README.txt添加(copy)到相对于spec文件的根目录下,指定文件时是相对于spec来进行寻找的,而不是要打包的exe程序路径。也可以使用通配符:datas= [ (’/mygame/sfx/*.mp3’, ‘sfx’ ) ],表示将/mygame/sfx/目录下的所有.mp3文件都copy到sfx文件夹中。也可以添加整个文件夹:datas= [ (’/mygame/data’, ‘data’ ) ],表示将/mygame/data文件夹下所有的文件都copy到data文件夹下。
Analysis参数binaries:添加二进制文件,效果同命令–add-binary,也是一个列表,定义方式与datas参数一样。
Analysis参数hiddenimports:同命令“–hidden-import MODULENAME/–hiddenimport MODULENAME”。
Analysis参数hookspath:同命令“–additional-hooks-dir HOOKSPATH”。
Analysis参数runtime_hooks:同命令“–runtime-hook RUNTIME_HOOKS”。
Analysis参数excludes:同命令“–exclude-module EXCLUDES”。
exe参数console:设置是否显示命令行窗口,和命令-w/-c作用一样。
exe参数icon:设置程序图标,和命令-i/–icon作用一样。某些情况,直接执行“pyinstaller xxx.py”时生成的spec中没有这个参数,需要手动添加,参数值就是图片路径的字符串。
PyInstaller全局变量:这些全局变量可以在spec文件使用。
指定了相同的参数:当命令行和spec中指定了相同的参数选项,那么命令行的参数选项会被忽略。
pyinstaller 打包报错:
RecursionError: maximum recursion depth exceeded
在 filename.spec 文件头添加下面语句:
import sys
sys.setrecursionlimit(5000)
再次执行:pyinstaller filename.spec
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 110: invalid continuation byte
Unicode解码错误:“UTF-8”编解码器无法解码位置130中的字节0xCE:无效的继续字节
1.首先尝试将中文解释都去掉
2.控制台中输入 chcp 65001,然后执行打包
来源:https://blog.csdn.net/qq_41185868/article/details/80599390
3.[17260] Error loading Python lib '/home/wangsp/ocr_server_multi_file2/dist/ocr_server/libpython3.6m.so': dlopen: /home/wangsp/ocr_server_multi_file2/dist/ocr_server/libpython3.6m.so: cannot open shared object file: No such file or directory
重新编译或重命名
报错 ERROR: Tcl/Tk improperly installed on this system
打包时报错
93126 INFO: Loading module hook "hook-_tkinter.py"...
Traceback (most recent call last):
File "" , line 1, in <module>
File "/home/xxx/anaconda3/lib/python3.6/tkinter/__init__.py", line 36, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libX11.so.6: cannot open shared object file: No such file or directory
Traceback (most recent call last):
File "" , line 1, in <module>
ImportError: libX11.so.6: cannot open shared object file: No such file or directory
93201 ERROR: Tcl/Tk improperly installed on this system.
运行时时报错
[90854] Failed to execute script pyi_rth__tkinter
Traceback (most recent call last):
File "site-packages/PyInstaller/loader/rthooks/pyi_rth__tkinter.py", line 30, in <module>
FileNotFoundError: Tcl data directory "/home/xxx/ocr_server_files/dist/ocr_server/tcl" not found.
方法:suod yum -y install tk-devel
参考:https://blog.csdn.net/qq_43173257/article/details/89189842(使用了这个方法)
参考:https://blog.csdn.net/weixin_30756499/article/details/98635721
参考:https://www.cnblogs.com/liyongjian5179/p/10683301.html
关于隐藏导入:https://zhuanlan.zhihu.com/p/35338321
cx_Freeze是一个跨平台的将python转换成可执行程序的项目。
项目主页:http://cx-freeze.sourceforge.net/
可以下载rpm包安装。
安装完以后只需要运行:cxfreezeyourprogram.py
就会在当前目录生成一个dist的目录,里面包含了可执行程序以及依赖模块的库文件。
项目主页上说可以通过distutils的build_exe命令生成单一的可执行程序,不过貌似不行…所以这个相对于pyinstaller可能还是稍有不便。
更多可以参考:http://cx-freeze.sourceforge.net/cx_Freeze.html
一个Python应用程序,其中添加了Cython模块。需要使用cx_Freeze构建的可执行版本。
该可执行文件会引发ImportError并试图导入.pyx模块。
我进行了修改setup.py,以查看是否可以先编译.pyx以便cx_Freeze可以成功打包,但是报错:No module named fx
from cx_Freeze import setup, Executable
from Cython.Build import cythonize
setup(name='projectname',
version='0.0',
description=' ',
options={"build_exe": {"packages":["pygame","fx"]},'build_ext': {'compiler': 'mingw32'}},
ext_modules=cythonize("fx.pyx"),
executables=[Executable('main.py',targetName="myproject.exe",base = "Win32GUI")],
requires=['pygcurse','pyperclip','rsa','dill','numpy']
)
解决的办法是有两个单独的调用setup();一个fx.pyx用Cython 构建,然后一个用cx_Freeze打包exe。这是修改后的setup.py:
from cx_Freeze import Executable
from cx_Freeze import setup as cx_setup
from distutils.core import setup
from Cython.Build import cythonize
setup(options={'build_ext': {'compiler': 'mingw32'}},
ext_modules=cythonize("fx.pyx"))
cx_setup(name='myproject',
version='0.0',
description='',
options={"build_exe": {"packages":["pygame","fx"]}},
executables=[Executable('main.py',targetName="myproject.exe",base = "Win32GUI")],
requires=['pygcurse','pyperclip','rsa','dill','numpy']
)
先执行:python setup-cython.py build_ext --inplace
后执行:python setup-cython.py build