接触过的工具有pyinstaller,或者py2exe。感觉pyinstaller更简单易用。
真正将依赖的dll打包称一个安装包还需要借助windows打包工具
Inno Setup 或 NSIS
1、pyinstaller
官网:www.pyinstaller.org
两大步
(1)Install PyInstaller from PyPI:
pip install pyinstaller
(2)Go to your program’s directory and run:
pyinstaller yourprogram.py
就会在本地生成一个文件夹dist 里面有对应的exe
2、py2exe
官网:http://py2exe.org
需要写一些脚本
http://py2exe.org/index.cgi/Tutorial
写的简单易懂 需要创建一个setup.py 将需要打包的py写进去,就可以进行打包
-----------------------------------------------------------------
Tutorial
py2exe turns Python programs into packages that can be run on other Windows computers without needing to install Python on those computers. Python is needed on the computer where py2exe itself is run because py2exe is a Python program and it includes parts of Python in the package that is built.
To successfully complete this tutorial you‘ll need to know the basics of Python (you can get started at python.org‘s getting started page). You‘ll also need to know how to run Python programs from the command prompt.
There are a few simple steps needed to use py2exe once you‘ve installed it:
-
Providing the Microsoft Visual C runtime DLL
-
5.1. Python 2.4 or 2.5
-
5.2. Python 2.6, 2.7, 3.0, 3.1
-
5.2.1. Bundling the C runtime DLL
-
5.2.1.1 win32ui special case
-
-
-
1. Create/test your program
The biggest step is almost always the first one. The good news is that py2exe typically has little or no impact on this step. The vast majority of things you can do with Python will work with py2exe. Many modules just work seamlessly with py2exe, but some third party modules will require a little extra work. Luckily there is help available at WorkingWithVariousPackagesAndModules.
It‘s important that you make sure everything is working before you use py2exe. If py2exe fixes a broken program, then that‘s probably a bug in py2exe that needs to be fixed!
The first example we‘ll use here is our old friend...
We need to make sure it‘s working...
C:\Tutorial>python hello.py
Hello World!
C:\Tutorial>
Looks good!
2. Create your setup script (setup.py)
py2exe extends Distutils with a new "command". If you‘ve installed third party Python modules then there‘s a good chance you‘ve seen at least one distutils command:
C:\Tutorial>python setup.py install
"install" is a Distutils command that installs something (typically a Python module or package). The details Distutils needs to do that installation are contained in setup.py (and sometimes other associated files).
"py2exe" is a new Distutils command that is added when you import py2exe. To use py2exe you need to create a setup.py file to tell Distutils and py2exe what you want to do. Here‘s a setup.py whose simplicity is appropriate for our sample program...
from distutils.core import setup
import py2exe
setup(console=[‘hello.py‘])
Notice that this is ordinary Python. Let‘s go through it line by line...
- When working with py2exe the only part of Distutils we‘ll typically need to reference directly is the setup function, so that‘s all we‘ll import.
- Once Distutils is loaded, we need to load py2exe so that it can add its command.
- Whitespace is good!
- Call setup and tell it that we want a single console application and the main entry point is "hello.py".
3. Run your setup script
The next step is to run your setup script. Make sure to give the py2exe command and expect to see lots and lots of output:
C:\Tutorial>python setup.py py2exe
running py2exe
*** searching for required modules ***
*** parsing results ***
creating python loader for extension ‘zlib‘
creating python loader for extension ‘unicodedata‘
creating python loader for extension ‘bz2‘
*** finding dlls needed ***
*** create binaries ***
*** byte compile python files ***
byte-compiling C:\Tutorial\build\bdist.win32\winexe\temp\bz2.py to bz2.pyc
byte-compiling C:\Tutorial\build\bdist.win32\winexe\temp\unicodedata.py to unicodedata.pyc
byte-compiling C:\Tutorial\build\bdist.win32\winexe\temp\zlib.py to zlib.pyc
skipping byte-compilation of c:\Python24\lib\StringIO.py to StringIO.pyc
[skipping many lines for brevity]
skipping byte-compilation of c:\Python24\lib\warnings.py to warnings.pyc
*** copy extensions ***
*** copy dlls ***
copying c:\Python24\lib\site-packages\py2exe\run.exe -> C:\Tutorial\dist\hello.exe
*** binary dependencies ***
Your executable(s) also depend on these dlls which are not included,
you may or may not need to distribute them.
Make sure you have the license if you distribute any of them, and
make sure you don‘t distribute files belonging to the operating system.
ADVAPI32.dll - C:\WINDOWS\system32\ADVAPI32.dll
USER32.dll - C:\WINDOWS\system32\USER32.dll
SHELL32.dll - C:\WINDOWS\system32\SHELL32.dll
KERNEL32.dll - C:\WINDOWS\system32\KERNEL32.dll
C:\Tutorial>
Two directories will be created when you run your setup script, build and dist. The build directory is used as working space while your application is being packaged. It is safe to delete the build directory after your setup script has finished running. The files in the dist directory are the ones needed to run your application.
4. Test your executable
Now that the package has been created it is ready to test:
C:\Tutorial>cd dist
C:\Tutorial\dist>hello.exe
Hello World
Excellent, it works!!!
5. Providing the Microsoft Visual C runtime DLL
The Python interpreter was compiled using Microsoft Visual C, so your new program needs the Microsoft Visual C runtime DLL to run. If you have installed appropriate versions of Python or Visual Studio, then you will already have this DLL on your computer. If some of your users might not already have this DLL, then they will not be able to run your program. The methods you may use to solve this depend on the version of Python you are using:
5.1. Python 2.4 or 2.5
If you are using Python 2.4 or 2.5, then the DLL you need is called MSVCR71.dll. This DLL will probably already have been included in your dist directory, in which case you need do nothing more.
However, the copyright on this file is owned by Microsoft, and you need to check whether you have the legal right to redistribute it. If you have a copy of Visual Studio, check the file redist.txt provided within the installation to see whether you have redistribution rights for this DLL. Generally you have the right to redistribute it if you own a license for Microsoft Visual C++, but not if you use the Express Editions.
If you do not have the rights to redistribute MSVCR71.dll, then your users must install it for themselves, using the Microsoft Visual C++ 2005 Redistributable Package (vcredist_x86.exe).
Either you can instruct your users to download and run this themselves, or you could create an installer for your application (see Step 6 below), that includes vcredist_x86.exe (which is itself redistributable by anyone), and then run that as part of your application installation.
5.2. Python 2.6, 2.7, 3.0, 3.1
For Python 2.6, the DLL you need is called MSVCR90.dll. Py2exe is not able to automatically include this DLL in your dist directory, so you must provide it yourself.
To complicate things, there is more than one version of this DLL in existance, each with the same filename. You need the same version that the Python interpreter was compiled with, which is version 9.0.21022.8. Through the remainder of these instructions, hover your mouse over the dll file (or the vcredist_x86.exe installer executable) to confirm which version you‘ve got. You‘ll need the vcredist_x86.exe that contains the Microsoft Visual C++ 2008 Redistributable Package published 29-11-2007, so not the VS2008 SP1 one (tested with Python 2.7.1).
As for older versions of Python, you need to check redist.txt within your Visual Studio installation to see whether you have the legal right to redistribute this DLL. If you do have these rights, then you have the option to bundle the C runtime DLL with you application. If you don‘t have the rights, then you must have your users run the redistributable C runtime installer on their machines.
5.2.1. Bundling the C runtime DLL
If you do have the rights to redistribute MSVCR90.dll, there should be a copy of it in your Visual Studio install, under VC\redist\x86\Microsoft.VC90.CRT. Since Visual Studio 2008, you can‘t just copy this DLL file - you also need the manifest file that you‘ll find there. The redist.txt file states that you must distribute all three dlls and the unmodified manifest file and it is a violation of the license agreement to distribute only one of the dlls without the others (though py2exe only needs MSVCR90.dll.) The pertinent passage from the redist.txt file is as follows:
- "For your convenience, we have provided the following folders for use when redistributing VC++ runtime files. Subject to the license terms for the software, you may redistribute the folder (unmodified) in the application local folder as a sub-folder with no change to the folder name. You may also redistribute all the files (*.dll and *.manifest) within a folder, listed below the folder for your convenience, as an entire set."
You must make py2exe copy the three dlls and the manifest file into your project‘s dist directory, in a subdirectory called ‘Microsoft.VC90.CRT‘. To achieve this, add a data_files option to your project‘s setup.py:
from glob import glob
data_files = [("Microsoft.VC90.CRT", glob(r‘C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT\*.*‘))]
setup(
data_files=data_files,
etc
)
With this in place, running py2exe should put the files into your dist directory:
dist
|
+-Microsoft.VC90.CRT
| |
| +-Microsoft.VC90.CRT.manifest
| +-msvcm90.dll
| +-msvcp90.dll
| +-msvcr90.dll
|
|-etc
Now, simply copying the whole dist directory to your users machines should now allow your application to run, even on machines that don‘t have their own copy of the C++ runtime.
Note that this method of including the C runtime is used by several Visual C++ applications - if you search your Program Files folder for msvcr90.dll, you may find several applications that have this DLL and the associated manifest bundled alongside their executable like this.
Also note that despite all the above, py2exe will complain that it cannot find MSVCP90.dll. You must edit your setup.py to add the path to the dlls to the sys.path, e.g.
sys.path.append("C:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\redist\\x86\\Microsoft.VC90.CRT")
5.2.1.1 win32ui special case
win32ui needs MFC DLLs to run .exe, see Py2exeAndWin32ui for extra informations
5.2.2. Running the redistributable C runtime installer
If you don‘t have rights to redistribute MSVCR90.dll, then your users may install it on their machine by running the Microsoft Visual C++ 2008 Redistributable Package (vcredist_x86.exe). It is important not to use the SP1 version of this installer, which contains the wrong version of MSVCR90.dll.
Either you can instruct your users to download and run this themselves, or you could create an installer for your application (see step 6 below), that includes vcredist_x86.exe (which is itself redistributable by anyone), and then run that as part of your application installation.
The installer puts a copy of the DLLs in the directory C:\WINDOWS\WinSxS (XP), inside subdirectories with mangled names. The manifest file is in the ‘Manifests‘ subdirectory, again this will have a mangled filename. You can still discern the text ‘Microsoft.VC90.CRT‘ and ‘9.0.21022.8‘ within the mangled file and directory names, to find the files. It is possible to take a copy of these files and remove the filename mangling, to embed them in your application as described in 5.2.1.
6. Build an installer if applicable
py2exe is not an installer builder - it merely assembles the files needed to run your Python program. There are plenty of good installer builders out there including some that are open source (e.g., NSIS) and some that are free (e.g., Inno Setup).
-----------------------------------------------------------------------------
https://github.com/cycleuser/Kivy-CN/blob/master/13-Kivy-Pack-Windows.md
Title: Kivy Pack Windows Date: 2017-03-01 Category: Kivy Tags: Python,Kivy
Kivy中文编程指南:打包为 Windows 系统可执行文件
特别注意
本文档仅适用于1.9.1
以及更新版本的 Kivy。
要打包 Windows 平台的应用程序,只能在 Windows 操作系统下完成。另外一定要注意,本文后续内容中都是在 wheels 安装的 Kivy 下通过测试的,如果你用其他安装方法,参考结尾部分吧。
打包出来的程序是 32 位还是 64 位只取决于你打包使用的 Python,而不取决于 Windows 操作系统的版本。
依赖包
- 最新版本的Kivy (参考安装指南 Installation on Windows)
- PyInstaller 3.1或者更新的版本 (
pip install --upgrade pyinstaller
)。
(译者注:PyInstaller 目前(2017年03月01日)还不支持 Python 3.6 哦~,好多朋友都坑到这里了,所以推荐使用 3.5.2。)
PyInstaller 的基本用法
本节内容是要让 PyInstaller(3.1或者更新版本)包含 Kivy 的 Hook(钩子, Windows 消息处理机制的一个平台)。要覆盖默认的 Hook ,下面的样例代码需要稍微修改一下。参考 覆盖默认 Hook。
打包一个简单的 APP
这个例子里面,咱们要把样例中的 touchtracer 这个项目进行打包,并且添加一个自定义图标。这里 Kivy 的样例目录要注意,如果是用 wheels 安装的,在 python\\share\\kivy-examples
这个位置,如果从 github 上面下载的,就在 kivy\\examples
这个位置。为了避免混乱,这里就用 examples-path
来指代这个目录的完整路径。然后 touchtracer 这个样例在 examples-path\\demo\\touchtracer
这个文件夹里,代码文件是 main.py
。
###1 确保 Python 打开命令行确保 Python 包含在环境变量内,也就是说,输入 python
会出现解释器提示符。(译者注:cmd 或者 powershell 都可以,更推荐用后者,语法和 Bash 比较相似。)
###2 创建文件夹 在要打包 APP 的位置创建一个文件夹。比如咱们这次就创建一个名字为 TouchApp
的文件夹,然后用类似 cd TouchApp
这样的命令进入到这个新建目录内。之后输入:
python -m PyInstaller --name touchtracer examples-path\demo\touchtracer\main.py
还可以增加一个 icon.ico 文件到这个应用目录,这样就可以让程序有自己的图标了。如果没有自己的 .ico 图标文件,可以把你的 icon.png 文件转换成 ico,用这个 ConvertICO 在线的应用就可以了。保存 icon.ico 到 touchtracer 这个目录里面,然后输入:
python -m PyInstaller --name touchtracer --icon examples-path\demo\touchtracer\icon.ico examples-path\demo\touchtracer\main.py
更多其它选项,请参考 PyInstaller 官方说明。
###3 编辑配置文件 在 TouchApp
里面会有一个配置文件 touchtracer.spec
。咱们需要编辑修改一下这个文件,在里面增加一些依赖包的 hook,这样才能保证正确创建 exe。接下来就是打开编辑器了,爱用啥都行,然后在配置文件的开头添加上下面这句:(这里是假设用的是 sdl2, 现在 Kivy 默认使用这个)
from kivy.deps import sdl2, glew
然后,用搜索,找到 COLLECT()
这个位置,添加上 touchtracer 用到的其他文件(touchtracer.kv, particle.png,等等):修改示例中的行位置,添加一个 Tree()
对象,例如这里的是 Tree(‘examples-path\\demo\\touchtracer\\‘)
。这个 Tree()
会搜索在当前这个 touchtracer 文件夹的所有文件,并添加到你最终打包的程序中。
要添加额外的依赖包,就要在 COLLECT 的第一个关键词参数的前面,为每一个依赖包的路径添加一个 Tree 对象。例如下面的就是以 *[Tree(p) for p in(sdl2.dep_bins + glew.dep_bins)]
为例:
coll = COLLECT(exe, Tree(‘examples-path\\demo\\touchtracer\\‘),
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
strip=False,
upx=True,
name=‘touchtracer‘)
###4 进行构建 接下来就用 TouchApp
里面这个 spec 配置文件来进行构建了:
python -m PyInstaller touchtracer.spec
###5 生成位置 编译好的包会在 TouchApp\dist\touchtracer 这个目录。
使用 gstreamer 创建一个视频应用
接下来就是修改一下上面的这个样例了,这回要打包的 APP 是一个使用了 gstreamer 的视频应用。咱们这回用样例中的视频播放器的例子 videoplayer
,代码在examples-path\widgets\videoplayer.py
。另外创建一个名字为 VideoPlayer
的文件夹,然后在命令行中进入到这个文件夹,之后操作如下:
python -m PyInstaller --name gstvideo examples-path\widgets\videoplayer.py
这回要修改 gstvideo.spec
这个文件。跟上文的方法类似,也就是把 gstreamer 的依赖包放进去:
from kivy.deps import sdl2, glew, gstreamer
然后就是增加 Tree()
来包含好要用的视频文件,Tree(‘examples-path\\widgets‘)
和 gstreamer 依赖都得弄好,大概如下所示:
coll = COLLECT(exe, Tree(‘examples-path\\widgets‘),
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins + gstreamer.dep_bins)],
strip=False,
upx=True,
name=‘gstvideo‘)
接下来就是使用 VideoPlayer
文件夹中的这个 spec 配置文件来进行构建了:
python -m PyInstaller gstvideo.spec
然后你就能在 VideoPlayer\dist\gstvideo
这个位置找到 gstvideo.exe 这个文件了,运行一下就能播放视频了。
特别注意
如果你用了 Pygame,或者你打包的程序需要 Pygame,那在你的 spec 文件里面就还得添加如下的代码,在 import 导入语句的后面添加(详情参考 kivy issue #1638):
def getResource(identifier, *args, **kwargs):
if identifier == ‘pygame_icon.tiff‘:
raise IOError()
return _original_getResource(identifier, *args, **kwargs)
import pygame.pkgdata
_original_getResource = pygame.pkgdata.getResource
pygame.pkgdata.getResource = getResource
覆盖默认 Hook
包含/移除视频音频以及缩小应用体积
PyInstallers 默认会将 Kivy 用到的所有核心模块和这些模块的依赖包,全部都添加成 hook,比如音频,视频,拼写等等(然而 gstreamer 的 dll 还是需要你用 Tree()
来手动添加,参考上文)。有的 Hook 并没有用到或者想要缩小应用的体积,就都可以尝试着移除一些模块,比如如果没有用到音频和视频,就可以用自定义的 Hook了。
Kivy 在hookspath()
提供了可选的 Hook。
此外,当且仅当 PyInstaller 没有默认的 hook 的时候,就必须得提供一个runtime_hooks()
。 覆盖 hook的时候,这个runtime_hooks()
不需要覆盖。
可选自定义的hookspath()
hook不包含任何 Kivy 的 provider。要添加电话,就要用get_deps_minimal()
或者 get_deps_all()
来添加。可以看看相关的文档以及pyinstaller_hooks
来了解更多信息。不过get_deps_all()
跟默认的 hook一样,都是把所有 provider 都添加进去;而get_deps_minimal()
只添加在应用程序运行的时候加载了的内容。
这两个方法都提供了一个 Kivy 隐藏导入列表,以及排除的导入,可以传递出来给 Analysis
。
还可以生成一个自定义 hook,一个个列出每一个 kivy 的 provider 模块,然后把其中用不上的就注释掉就行了。
要在上面的例子中使用自定义 hook,要按照下面给出的范例来修改,以hookspath()
和 runtime_hooks
(必要情况下),然后是**get_deps_minimal()
或者 **get_deps_all()
来制定好各种 provider。
例如,增加了导入语句 from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal, get_deps_all, hookspath,runtime_hooks
,然后按照如下方式修改Analysis
:
a = Analysis([‘examples-path\\demo\\touchtracer\\main.py‘],
...
hookspath=hookspath(),
runtime_hooks=runtime_hooks(),
...
**get_deps_all())
上面这个实际上跟默认 hook 一样包含全部了。或者可以:
a = Analysis([‘examples-path\\demo\\touchtracer\\main.py‘],
...
hookspath=hookspath(),
runtime_hooks=runtime_hooks(),
...
**get_deps_minimal(video=None, audio=None))
这样就是移除了声音视频的 provider,这就只加载了用到的核心模块了。
关键就是要提供自定义的 hookspath()
,这个默认并不会列出全部的 kivy provider,而是手动的来设定隐藏导入的模块和需要用的 provider,通过get_deps_minimal()
来移除用不上的模块 (比如上面的是声音影像)。
其他安装方式
前面的这些例子都用到了 *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins + gstreamer.dep_bins)],
这样的语句来保证 PyInstaller 把所有依赖包用到的 dll 都添加进去。如果不是用 wheel 的方法安装的 Kivy,那么这些命令就很可能失败,比如 kivy.deps.sdl2
可能就无法导入。这时候,你就必须得找到这些 dll 文件的位置,然后手动地一个个传递给 Tree
类,传递方法和上面说的基本差不多了。
(译者注:Windows 平台还是推荐用 wheel 二进制安装,省心多了。)