python -m pip install pyinstaller
先cd到需要打包的工程内部(工程主文件所在的文件夹地址),然后执行打包命令pyinstaller -选项 xxx.py
选项详解:
用法: 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 ...]
位置参数:
scriptname 要处理的脚本文件的名称或者一个.spec文件。如果指定了.spec文件,则大多数选项都是不必要的,会被忽略。
可选参数:
-h, --help 显示帮助信息并退出
-v, --version 显示程序版本信息并退出。
--distpath DIR 指定打包应用的目录(默认为./dist)
--workpath WORKPATH 指定所有临时工作文件(.log, .pyz等)的目录(默认为./build)
-y, --noconfirm 替换输出目录(默认为SPECPATH/dist/SPECNAME)而不需要确认
--upx-dir UPX_DIR UPX工具的路径(默认为搜索执行路径)
-a, --ascii 不包含Unicode编码支持(默认情况下如果可用则包含)
--clean 在构建之前清理PyInstaller缓存和临时文件。
--log-level LEVEL 构建时控制台消息的详细程度。LEVEL可以是TRACE、DEBUG、INFO、WARN、DEPRECATION、ERROR、FATAL之一(默认为INFO)。也可以通过PYI_LOG_LEVEL环境变量进行设置。
生成内容:
-D, --onedir 创建一个包含可执行文件的单文件夹捆绑包(也就是一个主文件夹里面有很多文件,但是有一个xxx.exe的程序入口文件,一般大部分应用都是这样的形态,默认为此模式)
-F, --onefile 创建一个单文件捆绑的可执行文件(也就是生成一个exe后缀的文件,所有的依赖啥的都在exe文件中包含,所以这个exe文件可能会很大)。
--specpath DIR 存储生成的.spec文件的文件夹(默认为当前目录)
-n NAME, --name NAME 分配给捆绑应用和.spec文件的名称(默认为第一个脚本的基本名称)
捆绑什么,搜索什么:
--add-data <SRC;DEST or SRC:DEST>
添加到可执行文件的附加非二进制文件或文件夹。路径分隔符是平台特定的,使用``os.pathsep``(在Windows上为``;``,在大多数Unix系统上为``:``)。此选项可以多次使用。
--add-binary <SRC;DEST or SRC:DEST>
添加到可执行文件的附加二进制文件。有关详细信息,请参见``--add-data``选项。此选项可以多次使用。
-p DIR, --paths DIR 搜索导入的路径(类似于使用PYTHONPATH)。可以使用多个路径,用``':'``分隔,或多次使用此选项。相当于在.spec文件中提供``pathex``参数。
--hidden-import MODULENAME, --hiddenimport MODULENAME
指定在脚本代码中不可见的导入模块。此选项可以多次使用。
--collect-submodules MODULENAME
收集指定包或模块的所有子模块。此选项可以多次使用。
--collect-data MODULENAME, --collect-datas 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
忽略的可选模块或包(Python名称,而不是路径名称)。此选项可以多次使用。
--splash IMAGE_FILE (实验性功能) 向应用程序添加一个带有图像IMAGE_FILE的启动画面。启动画面可以在解压过程中显示进度更新。
如何生成:
-d {all,imports,bootloader,noarchive}, --debug {all,imports,bootloader,noarchive}
提供用于调试冻结应用程序的帮助。此参数可以多次提供以选择以下选项之一。
- all: 以下所有选项。
- imports: 指定-v选项给底层Python解释器,导致它在每次初始化模块时打印一条消息,显示加载模块的位置(文件名或内置模块)。参见
https://docs.python.org/3/using/cmdline.html#id4。
- bootloader: 告诉引导加载程序在初始化和启动捆绑应用程序时发出进度消息。用于诊断缺少导入的问题。
- noarchive: 将所有冻结的Python源文件存储为结果可执行文件内的存档,而不是文件存储在结果输出目录中。
--python-option PYTHON_OPTION
指定要在运行时传递给Python解释器的命令行选项。目前支持"v"(等效于"--debug imports")、"u"和"W" 。
-s, --strip 对可执行文件和共享库应用符号表剥离(不推荐在Windows上使用)
--noupx 即使可用,也不使用UPX(在Windows和*nix之间的工作方式不同)
--upx-exclude FILE 使用upx时防止对二进制文件进行压缩。如果upx在压缩过程中破坏某些二进制文件,通常会使用此选项。FILE是二进制文件的文件名,不包含路径。此选项可以多次使用。
仅适用于Windows和Mac OS X的选项:
-c, --console, --nowindowed
为标准输入/输出打开控制台窗口(默认)。在Windows上,如果第一个脚本是'.pyw'文件,则此选项无效。
-w, --windowed, --noconsole
Windows和Mac OS X:不为标准输入/输出提供控制台窗口。在Mac OS上,这还会触发构建Mac OS .app包。在Windows上,如果第一个脚本是'.pyw'文件,则此选项会自动设置。在*NIX系统上,此选项将被忽略。
-i <FILE.ico或FILE.exe,ID或FILE.icns或Image或"NONE">, --icon <FILE.ico或FILE.exe,ID或FILE.icns或Image或"NONE">
FILE.ico:将图标应用于Windows可执行文件。FILE.exe,ID:从exe中提取具有ID的图标。FILE.icns:将图标应用于Mac OS上的.app包。如果输入的图像文件不是平台格式(Windows上的ico,Mac上的icns),PyInstaller将尝试使用Pillow将图标转换为正确的格式(如果安装了Pillow)。使用"NONE"来不应用任何图标,从而使操作系统显示一些默认图标(默认:应用PyInstaller的图标)。此选项可以多次使用。
--disable-windowed-traceback
禁用窗口模式(noconsole)下未处理异常的回溯转储(仅适用于Windows和macOS),并显示一个消息,说明此功能已禁用。
Windows特定选项:
--version-file FILE 从FILE中添加版本资源到exe。
-m <FILE或XML>, --manifest <FILE或XML>
将manifest FILE或XML添加到exe。
--no-embed-manifest 生成外部的.exe.manifest文件,而不是将manifest嵌入到exe中。仅适用于onedir模式;在onefile模式下,无论此选项如何,manifest始终被嵌入。
-r RESOURCE, --resource RESOURCE
向Windows可执行文件添加或更新资源。RESOURCE是一个到四个项目,FILE[,TYPE[,NAME[,LANGUAGE]]]。FILE可以是数据文件或exe/dll。对于数据文件,至少必须指定TYPE和NAME。LANGUAGE默认为0,或可以指定为通配符*以更新给定TYPE和NAME的所有资源。对于exe/dll文件,如果省略了或指定为通配符*,则将添加/更新来自FILE的所有资源到最终的可执行文件中。此选项可以多次使用。
--uac-admin 使用此选项创建一个Manifest,将在应用程序启动时请求提升。
--uac-uiaccess 使用此选项允许提升的应用程序与远程桌面一起工作。
Windows并行程序集搜索选项(高级):
--win-private-assemblies
将任何捆绑到应用程序中的共享程序集更改为私有程序集。这意味着始终使用这些程序集的确切版本,并忽略用户机器上系统级安装的任何更新版本。
--win-no-prefer-redirects
在搜索要捆绑到应用程序中的共享或私有程序集时,PyInstaller将不倾向于遵循重定向到更新版本的策略,并尝试捆绑程序集的确切版本。
Mac OS特定选项:
--argv-emulation 启用macOS应用程序包的argv模拟。如果启用,启动时的初始打开文档/URL事件将由引导加载程序处理,并将传递的文件路径或URL附加到sys.argv。
--osx-bundle-identifier BUNDLE_IDENTIFIER
Mac OS .app包标识符用作默认的唯一程序名称,用于代码签名目的。通常的形式是反向DNS表示法中的分层名称。例如:com.mycompany.department.appname(默认值:第一个脚本的基本名称)
--target-architecture ARCH, --target-arch ARCH
目标架构(仅适用于macOS;有效值:x86_64,arm64,universal2)。启用在冻结应用程序的universal2和单架构版本之间切换(前提是Python安装支持目标架构)。如果未指定目标架构,则针对当前运行的架构。
--codesign-identity IDENTITY
代码签名身份(仅适用于macOS)。使用提供的身份对收集的二进制文件和生成的可执行文件进行签名。如果未提供签名身份,则执行自动签名。
--osx-entitlements-file FILENAME
用于在签署收集的二进制文件时使用的权限文件(仅适用于macOS)。
很少使用的特殊选项:
--runtime-tmpdir PATH
在`onefile`模式下提取库和支持文件的位置。如果给出此选项,引导加载程序将忽略运行时操作系统定义的任何临时文件夹位置。在此处将创建``_MEIxxxxxx``文件夹。请仅在您知道自己在做什么的情况下使用此选项。
--bootloader-ignore-signals
告诉引导加载程序忽略信号而不是将其转发给子进程。在某些情况下很有用,例如监督进程通过进程组向引导加载程序和子进程发送信号,以避免向子进程发送两次信号。
————————————————
版权声明:本文为CSDN博主「Dontla」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Dontla/article/details/131474870
-D与 -F 相反用法,默认是-D模式,会生成一个文件目录包含可执行exe文件和相关动态链接库和资源文件等,整体是一个大文件夹,里面有可执行的exe文件,对于打包结果较大的项目,选用-D生成目录相比-F的打包方式,执行速度更快,但包含更加多的文件
-F 表示在 dist 文件夹下只生成单个可执行文件也就是一个.exe文件(内部包含所有依赖),不加的话就相当于是指定的-D参数,此时会在 dist 生成一大堆依赖文件+可执行的exe文件。
-w 表示去掉控制台窗口,如果你的程序是有界面的,可以不写这个参数,
-c 表示去掉窗框,使用控制台,推荐使用,会打印各种信息和log到控制台,加上这个参数生成的spec中的console=True,表示执行程序时会有一个cmd的控制台,反之执行程序时无控制台,除了脚本的动作再无其他动作。
-p 表示自己定义需要加载的类路径,项目中包含多个自建模块的时候需要加上 -p aaa.py -p bbb.py -p ccc.py
-i 表示可执行文件的图标,后面跟图标的路径,可以自定义exe文件的图标,我尝试了好多次没成功
打包完毕后会在同级生成dist文件夹,打包成功的工程就在dist文件夹下面,在 dist 文件夹下双击项目启动文件就可以执行了
其他选项参考此博客
假设有个python工程在D:\dev_test_project文件夹下,整个工程的启动文件是test_main.py
则打包如下(打包默认形态,不传任何参数)
# cd D:\dev_test_project
# D:\dev_tools\dev\python\Python37\Scripts\pyinstaller.exe test_main.py
此时pyinstaller整个打包步骤分为两步(此三步用户不会感知,对于用户来说执行完打包命令后就已经打包完成了,等待软件包生成即可)
1.先在D:\dev_test_project文件夹下生成默认的test_main.spec文件
2.底层直接根据默认的main.spec文件进行执行pyinstaller test_main.spec完成默认的打包
3.在D:\dev_test_project创建dist文件夹和其他一些文件夹,打包生成的包就在dist文件夹下面,直接拷贝取用即可。
此方法推荐,因为当工程中有一些资源文件或者其他非python文件时,编辑.spec文件后在执行命令打包比较靠谱, 否则打包完成运行时可能出现某些资源文件无法找到的情况,之前碰到过打包完成后执行时报错pyecharts模块的某些资源无法找到的报错,最后看了下是因为工程用到了一个第三方绘图模块pyecharts模块,它里面有一些非python的资源文件没有打进去包,所以报错了,这些文件如下图,这种情况就要编辑.spec文件的Analysis的datas,在datas里面修改信息加上这些文件包在打包
如果你没有.spec文件的话则可以随便找个工程或者py文件现场生成一个.spec文件,然后编辑他,之后执行即可打包(在方法一中的第一步就会生成.spec文件),相当于执行方法一之后,清理掉(删除)方法一里面第三步的生成文件(dist文件夹等),然后修改.spec文件,然后执行.spec文件的打包命令打包工程
# cd D:\dev_test_project
# D:\dev_tools\dev\python\Python37\Scripts\pyinstaller.exe test_main.py
则在D:\dev_test_project下面会生成test_main.spec文件对她编辑即可
spec文件当中的语法就是python语法,你可以认为他就是一个python文件,只不过后缀是.spec而已,其默认的结构如下:
spec文件中主要包含4个class: Analysis, PYZ, EXE和COLLECT.
Analysis以py文件为输入,它会分析py文件的依赖模块,并生成相应的信息,修改的主要是这个部分
PYZ是一个.pyz的压缩包,包含程序运行需要的所有依赖,一般不需要修改
EXE根据上面两项生成,里面包含图标、版本(如果命令有会自动生成,命令没传也可以手动修改),可以设置生成的exe的名字
COLLECT生成其他部分的输出文件夹,COLLECT也可以没有,一般不需要更改,可以设置生成的项目文件夹名称
.spec文件样例
# -*- mode: python ; coding: utf-8 -*-
# 本质是Py文件所有有些包可以在这个里面导出
import sys
import os
sys.setrecursionlimit(5000)
block_cipher = None
project_dir_path = os.path.abspath(os.curdir)
a = Analysis(
# 项目主程序,工程启动入口py文件的地址(可以绝对路径也可以相对路径,取决于.spec文件执行的地址),应为是一个列表,所以可以填写多个文件
['weihang_test_py.py'],
# pathex定义了打包的主目录路径(工程文件夹路径),对于在此目录下的py文件可以只写文件名不写路径也是在列表中填写元素
pathex=[project_dir_path],
binaries=[],
# 一些非python的资源文件配置,因为是非python文件,但是工程中又需要这些文件,所以在这里配置,打包的时候会将这些文件或文件夹一并打包到工程中,不然的话,运行的时候会报错,格式为列表包元组格式,添加对应的元组即可,元组的第一个元素为打包之前的资源文件地址(最好填绝对路径),第二个元素为打包之后的资源文件地址(相对打包好好的工程的相对路径,如打包好的工程的主文件夹路径为D:\\project_dir_path\dist\exe_project_path, 那么这里填的地址就是从D:\\project_dir_path\dist\exe_project_path开始往下走的相对地址)
datas=[(r"D:\xxxxxxxx\dev\python\Python37\Lib\site-packages\pyecharts\pyecharts\render\templates", r"pyecharts\render\templates"),(project_dir_path + "project_img_dir\\img_file", "project_img_dir\\img_file"), (project_dir_path + "lib2\\img_file2", "lib2\\img_file2")],
# hiddenimports配置隐式调用的包信息,包括自己定义的一些隐式包,我的理解就是python导包的时候 import xxxxx或者 import xxxxx.sssss,如果给里面配置的话就是["xxxxx", "xxxxx.sssss"], 如果在打包之后执行时报no module named xxxx,而打包机器中有安装此模块,则可以试试将这些模块写到hiddenimports中
hiddenimports=["pandas", "pandas._libs", "xxxxx", "xxxxx"],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
# 打包的时候排除哪些包的导入,也就是不打包哪些模块
excludes=["need_not_model1", "need_not_model2"],
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,
[],
exclude_binaries=True,
# 打包的exe名字
name='weihang_test_py',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
# 打包完成的工程执行时是否需要展示控制台以及控制台上的打印,True就是有控制台和控制台打印,False就是没有控制台以及打印,无感知运行(运行的时候除了脚本触发的动作没有任何其他感知)
console=True,
disable_windowed_traceback=False,
target_arch=None,
# 打包之后如果想要exe文件的图表显示为特定图片的话可以配置此参数,指定图标的地址,打包时就会用那个图生成exe,一般都是.ico文件
icon='D:\\logo\\python.ico',
codesign_identity=None,
entitlements_file=None )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
# 是否剥离调试符号
strip=False,
# 是否使用UPX压缩
upx=True,
# 需要排除的UPX压缩文件
upx_exclude=[],
# 打包的工程名字
name='weihang_test_py')
修改后在命令行执行即可打包,打包的工程也会在dist目录中生成
D:\dev_tools\dev\python\Python37\Scripts\pyinstaller.exe test_project_main.spec
详细情况也可参照此博客