文章目录
一、简介与快速使用
1.1 简介
- PyInstaller将Python应用程序及其所有依赖项打包到一个package中。用户可以在不安装Python解释器或任何模块的情况下运行打包后的应用,这样可以方便传递。PyInstaller支持Python 3.7及更新的版本,并可以正确打包了许多主要的Python包,如numpy、matplotlib、PyQt、wxPython等(但有些Python的第三方库打包过程中可能存在问题,详见问题汇总)。
- Pyinstaller可以在Windows、Mac OS X和Linux上使用,但是并不是跨平台的,也就是说要打包为windows应用(.exe文件),需要在Windows系统上使用Pyinstaller。
1.2 安装与快速使用
- 安装:
pip install pyinstaller
- 基本使用:打开command prompt/shell window,并通过cd命令定位到PyQt5的主程序所在的位置,然后通过以下命令构建,那么打包后的应用可以在dist文件中使用
pyinstaller your_program.py
二、基础命令
2.1 概述
- 在这里,我们介绍多文件打包:Pyinstaller将多个py文件打包为一个exe文件和其他的依赖。
- Pyinstaller有很多不同的命令选项用于自定义打包的过程(更多细节可以在官方文档查看:https://pyinstaller.org/en/stable/index.html):
pyinstaller options.. myscript.py
- 运行上述命令后,首先会产生一个.spec文件,即规范化文件:它会告知Pyinstaller如何对你的script进行打包。它编码了你的script name和你给出的命令选项options。spec文件实际上是可执行的Python代码。PyInstaller通过执行spec文件的内容来构建应用程序。以下是spec文件的内容:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None #设置 加密,需要安装tinyaes第三方库,最多16位字符,此处在使用--key= 会有变化
a = Analysis(
['main.py'], # 运行的所有py文件,包括依赖的py文件
pathex=[], # 搜索导入的路径列表(此列表为项目绝对路径),包括选项给出的路径--paths,项目需要从什么地方导入自定义库
binaries=[], # 脚本需要的非python模块,包括--add-binary选项给出的名称,二进制数据
datas=[], # 应用程序中包含的非二进制文件,包括--add-data选项给出的名称,项目需要用到什么数据,比如图片,视频等。里面格式为tuple,第一个参数是文件路径,第二个是打包后所在的路径,其为一个元组:('image/*.png','data/image')
hiddenimports=[], # 假如打包后打开exe显示module not found,就要把该库添加到hiddenimports里面了
hookspath=[],
hooksconfig={}, # 挂钩配置选项由一个字典组成
runtime_hooks=[],
excludes=[], # 假如你用的python有很多库,但是你不需要用到某个,那么就把它添加到里面去,可以压缩文件大小
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, # 打包成EXE的脚本文件
# a.binaries, # 如果是单文件模式,则需要添加;多文件也可以添加
# a.zipfiles,
# a.datas,
[],
exclude_binaries=True, # 是否排除二进制文件,为True时,为排除二进制的文件,当文件交大时包含二进制文件运行较快,如果是单文件,则没有这个选项
name='main', # 打包程序的名字
debug=False, # 是否启用调试功能
bootloader_ignore_signals=False,
# runtime_tmpdir=None, # 生成单文件时需要这个参数,定义运行时的临时文件夹
strip=False,
upx=True, # 打包的时候进行压缩,False表示不压缩;要用到一个压缩程序UPX,用于压缩文件,需要单独下载
console=True, # 打包后的可执行文件双击运行时屏幕会出现一个cmd窗口,不影响原程序运行,等于是是否加-w参数
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
"""添加选项,初始化时没有的"""
icon="", # 指定应用程序的图标,传入路径,可以相对路径
)
coll = COLLECT(
"""
如果是单文件模式,不需要这个COLLECT类,同时需要将:
a.binaries,
a.zipfiles,
a.datas,
这些数据文件添加到EXE中
"""
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main',
)
2.2 基础的命令
- 常用的命令如下:
- 可以通过pyinstaller -h的命令来查看更具体的命令选项的帮助信息,在此我复制到下面:
usage: pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME]
[--add-data <SRC;DEST or SRC:DEST>]
[--add-binary <SRC;DEST or SRC:DEST>] [-p DIR]
[--hidden-import MODULENAME]
[--collect-submodules MODULENAME]
[--collect-data MODULENAME] [--collect-binaries MODULENAME]
[--collect-all MODULENAME] [--copy-metadata PACKAGENAME]
[--recursive-copy-metadata PACKAGENAME]
[--additional-hooks-dir HOOKSPATH]
[--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES]
[--splash IMAGE_FILE]
[-d {all,imports,bootloader,noarchive}]
[--python-option PYTHON_OPTION] [-s] [--noupx]
[--upx-exclude FILE] [-c] [-w]
[-i <FILE.ico or FILE.exe,ID or FILE.icns or Image or "NONE">]
[--disable-windowed-traceback] [--version-file FILE]
[-m <FILE or XML>] [--no-embed-manifest] [-r RESOURCE]
[--uac-admin] [--uac-uiaccess] [--win-private-assemblies]
[--win-no-prefer-redirects] [--argv-emulation]
[--osx-bundle-identifier BUNDLE_IDENTIFIER]
[--target-architecture ARCH] [--codesign-identity IDENTITY]
[--osx-entitlements-file FILENAME] [--runtime-tmpdir PATH]
[--bootloader-ignore-signals] [--distpath DIR]
[--workpath WORKPATH] [-y] [--upx-dir UPX_DIR] [-a]
[--clean] [--log-level LEVEL]
scriptname [scriptname ...]
positional arguments:
scriptname Name of scriptfiles to be processed or exactly one
.spec file. If a .spec file is specified, most options
are unnecessary and are ignored.
optional arguments:
-h, --help show this help message and exit
-v, --version Show program version info and exit.
--distpath DIR Where to put the bundled app (default: ./dist)
--workpath WORKPATH Where to put all the temporary work files, .log, .pyz
and etc. (default: ./build)
-y, --noconfirm Replace output directory (default:
SPECPATH\dist\SPECNAME) without asking for
confirmation
--upx-dir UPX_DIR Path to UPX utility (default: search the execution
path)
-a, --ascii Do not include unicode encoding support (default:
included if available)
--clean Clean PyInstaller cache and remove temporary files
before building.
--log-level LEVEL Amount of detail in build-time console messages. LEVEL
may be one of TRACE, DEBUG, INFO, WARN, DEPRECATION,
ERROR, FATAL (default: INFO). Also settable via and
overrides the PYI_LOG_LEVEL environment variable.
What to generate:
-D, --onedir Create a one-folder bundle containing an executable
(default)
-F, --onefile Create a one-file bundled executable.
--specpath DIR Folder to store the generated spec file (default:
current directory)
-n NAME, --name NAME Name to assign to the bundled app and spec file
(default: first script's basename)
What to bundle, where to search:
--add-data <SRC;DEST or SRC:DEST>
Additional non-binary files or folders to be added to
the executable. The path separator is platform
specific, ``os.pathsep`` (which is ``;`` on Windows
and ``:`` on most unix systems) is used. This option
can be used multiple times.
--add-binary <SRC;DEST or SRC:DEST>
Additional binary files to be added to the executable.
See the ``--add-data`` option for more details. This
option can be used multiple times.
-p DIR, --paths DIR A path to search for imports (like using PYTHONPATH).
Multiple paths are allowed, separated by ``';'``, or
use this option multiple times. Equivalent to
supplying the ``pathex`` argument in the spec file.
--hidden-import MODULENAME, --hiddenimport MODULENAME
Name an import not visible in the code of the
script(s). This option can be used multiple times.
--collect-submodules MODULENAME
Collect all submodules from the specified package or
module. This option can be used multiple times.
--collect-data MODULENAME, --collect-datas MODULENAME
Collect all data from the specified package or module.
This option can be used multiple times.
--collect-binaries MODULENAME
Collect all binaries from the specified package or
module. This option can be used multiple times.
--collect-all MODULENAME
Collect all submodules, data files, and binaries from
the specified package or module. This option can be
used multiple times.
--copy-metadata PACKAGENAME
Copy metadata for the specified package. This option
can be used multiple times.
--recursive-copy-metadata PACKAGENAME
Copy metadata for the specified package and all its
dependencies. This option can be used multiple times.
--additional-hooks-dir HOOKSPATH
An additional path to search for hooks. This option
can be used multiple times.
--runtime-hook RUNTIME_HOOKS
Path to a custom runtime hook file. A runtime hook is
code that is bundled with the executable and is
executed before any other code or module to set up
special features of the runtime environment. This
option can be used multiple times.
--exclude-module EXCLUDES
Optional module or package (the Python name, not the
path name) that will be ignored (as though it was not
found). This option can be used multiple times.
--splash IMAGE_FILE (EXPERIMENTAL) Add an splash screen with the image
IMAGE_FILE to the application. The splash screen can
display progress updates while unpacking.
How to generate:
-d {all,imports,bootloader,noarchive}, --debug {all,imports,bootloader,noarchive}
Provide assistance with debugging a frozen
application. This argument may be provided multiple
times to select several of the following options.
- all: All three of the following options.
- imports: specify the -v option to the underlying
Python interpreter, causing it to print a message
each time a module is initialized, showing the
place (filename or built-in module) from which it
is loaded. See
https://docs.python.org/3/using/cmdline.html#id4.
- bootloader: tell the bootloader to issue progress
messages while initializing and starting the
bundled app. Used to diagnose problems with
missing imports.
- noarchive: instead of storing all frozen Python
source files as an archive inside the resulting
executable, store them as files in the resulting
output directory.
--python-option PYTHON_OPTION
Specify a command-line option to pass to the Python
interpreter at runtime. Currently supports "v"
(equivalent to "--debug imports"), "u", and "W
<warning control>".
-s, --strip Apply a symbol-table strip to the executable and
shared libs (not recommended for Windows)
--noupx Do not use UPX even if it is available (works
differently between Windows and *nix)
--upx-exclude FILE Prevent a binary from being compressed when using upx.
This is typically used if upx corrupts certain
binaries during compression. FILE is the filename of
the binary without path. This option can be used
multiple times.
Windows and Mac OS X specific options:
-c, --console, --nowindowed
Open a console window for standard i/o (default). On
Windows this option has no effect if the first script
is a '.pyw' file.
-w, --windowed, --noconsole
Windows and Mac OS X: do not provide a console window
for standard i/o. On Mac OS this also triggers
building a Mac OS .app bundle. On Windows this option
is automatically set if the first script is a '.pyw'
file. This option is ignored on *NIX systems.
-i <FILE.ico or FILE.exe,ID or FILE.icns or Image or "NONE">, --icon <FILE.ico or FILE.exe,ID or FILE.icns or Image or "NONE">
FILE.ico: apply the icon to a Windows executable.
FILE.exe,ID: extract the icon with ID from an exe.
FILE.icns: apply the icon to the .app bundle on Mac
OS. If an image file is entered that isn't in the
platform format (ico on Windows, icns on Mac),
PyInstaller tries to use Pillow to translate the icon
into the correct format (if Pillow is installed). Use
"NONE" to not apply any icon, thereby making the OS
show some default (default: apply PyInstaller's icon).
This option can be used multiple times.
--disable-windowed-traceback
Disable traceback dump of unhandled exception in
windowed (noconsole) mode (Windows and macOS only),
and instead display a message that this feature is
disabled.
Windows specific options:
--version-file FILE Add a version resource from FILE to the exe.
-m <FILE or XML>, --manifest <FILE or XML>
Add manifest FILE or XML to the exe.
--no-embed-manifest Generate an external .exe.manifest file instead of
embedding the manifest into the exe. Applicable only
to onedir mode; in onefile mode, the manifest is
always embedded, regardless of this option.
-r RESOURCE, --resource RESOURCE
Add or update a resource to a Windows executable. The
RESOURCE is one to four items,
FILE[,TYPE[,NAME[,LANGUAGE]]]. FILE can be a data file
or an exe/dll. For data files, at least TYPE and NAME
must be specified. LANGUAGE defaults to 0 or may be
specified as wildcard * to update all resources of the
given TYPE and NAME. For exe/dll files, all resources
from FILE will be added/updated to the final
executable if TYPE, NAME and LANGUAGE are omitted or
specified as wildcard *. This option can be used
multiple times.
--uac-admin Using this option creates a Manifest that will request
elevation upon application start.
--uac-uiaccess Using this option allows an elevated application to
work with Remote Desktop.
Windows Side-by-side Assembly searching options (advanced):
--win-private-assemblies
Any Shared Assemblies bundled into the application
will be changed into Private Assemblies. This means
the exact versions of these assemblies will always be
used, and any newer versions installed on user
machines at the system level will be ignored.
--win-no-prefer-redirects
While searching for Shared or Private Assemblies to
bundle into the application, PyInstaller will prefer
not to follow policies that redirect to newer
versions, and will try to bundle the exact versions of
the assembly.
Mac OS specific options:
--argv-emulation Enable argv emulation for macOS app bundles. If
enabled, the initial open document/URL event is
processed by the bootloader and the passed file paths
or URLs are appended to sys.argv.
--osx-bundle-identifier BUNDLE_IDENTIFIER
Mac OS .app bundle identifier is used as the default
unique program name for code signing purposes. The
usual form is a hierarchical name in reverse DNS
notation. For example:
com.mycompany.department.appname (default: first
script's basename)
--target-architecture ARCH, --target-arch ARCH
Target architecture (macOS only; valid values: x86_64,
arm64, universal2). Enables switching between
universal2 and single-arch version of frozen
application (provided python installation supports the
target architecture). If not target architecture is
not specified, the current running architecture is
targeted.
--codesign-identity IDENTITY
Code signing identity (macOS only). Use the provided
identity to sign collected binaries and generated
executable. If signing identity is not provided, ad-
hoc signing is performed instead.
--osx-entitlements-file FILENAME
Entitlements file to use when code-signing the
collected binaries (macOS only).
Rarely used special options:
--runtime-tmpdir PATH
Where to extract libraries and support files in
`onefile`-mode. If this option is given, the
bootloader will ignore any temp-folder location
defined by the run-time OS. The ``_MEIxxxxxx``-folder
will be created here. Please use this option only if
you know what you are doing.
--bootloader-ignore-signals
Tell the bootloader to ignore signals rather than
forwarding them to the child process. Useful in
situations where for example a supervisor process
signals both the bootloader and the child (e.g., via a
process group) to avoid signalling the child twice.
三、问题汇总
3.1 打包后的main.exe出现闪退的现象
- 可能是因为缺少必要的数据和文件引发的(因为除了.py之外,其他格式不会编译),解决方案就是添加–add-data命令把所使用的数据、模型和文件等都添加到dist路径中。其实该命令就是修改了spec文件中的Analysis(datas=[])的内容
--add-data="源地址;目标地址" # 例如:--add-data="./config/*;./config"
a = Analysis(
datas=[], # 应用程序中包含的非二进制文件,包括–add-data选项给出的名称,项目需要用到什么数据,比如图片,视频等。里面格式为tuple,第一个参数是文件路径,第二个是打包后所在的路径,其为一个元组:(‘image/*.png’,‘data/image’))
3.2 ModuleNotFoundError: No module named ‘mmcv._ext’
- 这种问题一般出现在该模块在打包过程中未被包含进来,解决方案就是修改spec文件中的hiddenimports。
a = Analysis(
hiddenimports=[], # 假如打包后打开exe显示module not found,就要把该库添加到hiddenimports里面了)
- 命令为:
--hidden-import MODULENAME, --hiddenimport MODULENAME
Name an import not visible in the code of the
script(s). This option can be used multiple times.