0x00 前言
之前都是使用py2exe
将Python程序打包成可执行文件,但是最近需要打包成Macos
上的可执行程序。于是,选择了py2app
,但是使用下来发现坑比较多,最终还是放弃了。
于是,将目光转向了PyInstaller
,它可以同时支持Windows和Macos,并且使用方法差异也很小。
PyInstaller与py2exe的主要差异(Windows):
PyInstaller打包出来的是一个正常的exe;py2exe打包出来的既是exe,也是zip文件,可以进行解压
PyInstaller打包出来的程序在运行后会创建一个临时目录,把dll等文件解压到临时目录中;py2exe使用了内存加载dll的技术,可以在不解压dll的情况下直接加载,看上去更优雅一些
0x01 环境准备
测试过程使用了virtualenv
创建的虚拟环境,可以保证测试过程不会影响到系统的Python环境。
$ virtualenv .env
$ .env\Scripts\activate.bat(Windows)
$ source .env/bin/activate (类Unix)
$ pip install PyInstaller
$ pyinstaller
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]
[--additional-hooks-dir HOOKSPATH]
[--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES]
[--key KEY] [-d [{all,imports,bootloader,noarchive}]] [-s]
[--noupx] [-c] [-w]
[-i <FILE.ico or FILE.exe,ID or FILE.icns>]
[--version-file FILE] [-m <FILE or XML>] [-r RESOURCE]
[--uac-admin] [--uac-uiaccess] [--win-private-assemblies]
[--win-no-prefer-redirects]
[--osx-bundle-identifier BUNDLE_IDENTIFIER]
[--runtime-tmpdir PATH] [--bootloader-ignore-signals]
[--distpath DIR] [--workpath WORKPATH] [-y]
[--upx-dir UPX_DIR] [-a] [--clean] [--log-level LEVEL]
scriptname [scriptname ...]
pyinstaller: error: too few arguments
0x02 PyInstaller参数说明
官方文档地址为:https://pyinstaller.readthedocs.io/en/stable/usage.html
常用参数含义如下:
+--------------+----------------------------------------------+
|-h, --help | 帮助信息 |
+-------------------------------------------------------------+
|-v, --version | 版本信息 |
+-------------------------------------------------------------+
|--distpath DIR| 打包文件的保存目录(默认:dist) |
+-------------------------------------------------------------+
|--workpath WORKPATH| 临时文件的保存目录(默认:build) |
+-------------------------------------------------------------+
|-y, --noconfirm | 替换文件时无需确认 |
+-------------------------------------------------------------+
|--upx-dir UPX_DIR | UPX程序所在目录 |
+-------------------------------------------------------------+
|-a, --ascii | 不包含unicode编码支持 |
+-------------------------------------------------------------+
|--clean | 编译前先清理缓存和临时文件 |
+-------------------------------------------------------------+
|--log-level LEVEL | 编译时的日志等级:TRACE, DEBUG, INFO, |
| | WARN, ERROR, CRITICAL,默认是:INFO |
+-------------------------------------------------------------+
|-D, --onedir | 生成的所有文件保存到一个目录(默认) |
+-------------------------------------------------------------+
|-F, --onefile | 只生成一个文件(exe) |
+-------------------------------------------------------------+
|–specpath | .spec文件保存目录(默认是当前目录) |
+-------------------------------------------------------------+
|-n | 生成的文件名(默认是指定的Python脚本名称) |
+-------------------------------------------------------------+
|-i | 指定程序图标 Windows: *.ico Macos: *.icns|
+-------------------------------------------------------------+
|-w | 不显示命令行窗口 |
+-------------------------------------------------------------+
一般可以使用以下命令行创建一个GUI的可执行文件:
pyinstaller -F -w main.py -n demo
执行后,可以在dist
目录下创建demo.exe
(Windows)或demo.app
(Macos)
0x03 指定程序图标
一般可执行程序都会包含个性化的图标,但是Windows和Macos使用了不同的图标格式。Windows上一般是常见的*.ico
格式;而Macos上则是*.icns
ico图标的制作可以使用一些在线网站或小工具
制作icns图标可以使用如下方法(Macos):
准备好一张长宽相等的png图片(最好背景透明),重命名为
pic.png
创建目录
tmp.iconset
执行以下命令,生成图标集
sips -z 16 16 pic.png --out tmp.iconset/icon_16x16.png
sips -z 32 32 pic.png --out tmp.iconset/icon_16x16@2x.png
sips -z 32 32 pic.png --out tmp.iconset/icon_32x32.png
sips -z 64 64 pic.png --out tmp.iconset/icon_32x32@2x.png
sips -z 128 128 pic.png --out tmp.iconset/icon_128x128.png
sips -z 256 256 pic.png --out tmp.iconset/icon_128x128@2x.png
sips -z 256 256 pic.png --out tmp.iconset/icon_256x256.png
sips -z 512 512 pic.png --out tmp.iconset/icon_256x256@2x.png
sips -z 512 512 pic.png --out tmp.iconset/icon_512x512.png
sips -z 1024 1024 pic.png --out tmp.iconset/icon_512x512@2x.png
- 执行以下命令创建icns图标文件
$ iconutil -c icns tmp.iconset -o pic.icns
指定程序图标只要在命令行后面增加参数:
-i pic.icon/pic.icns
0x04 添加数据文件
程序中有时需要用到一些数据文件,可以使用--add-data=src;dst
(Windows)或--add-data=src:ds
(类Unix)参数将src
路径对应的文件(夹)
拷贝到dst
指向的路径,程序中可以使用dst
路径进行访问。
由于PyInstaller打包出来的程序在运行时会解压数据文件到临时目录中,因此程序中可以直接访问这些数据文件;而py2exe则需要手动将数据文件从程序体中解压出来使用。
0x05 添加版本信息(Windows)
PyInstaller允许在Windows上给程序添加版本信息,使用--version-file version_file.txt
参数进行添加。
version_file.txt
文件的制作方法如下:
- 根据已有的exe文件生成版本文件模版
$ pyi-grab_version demo.exe version_file.txt
- 修改
version_file.txt
中的文件名、厂商、版本等信息,并保存
为了动态修改版本信息,也可以使用脚本动态生成版本文件
0x06 打包成app( Macos)
在Macos上使用PyInstaller打包出来的是一个目录,可以直接压缩成zip文件给其他人使用,但更多的是打包成dmg
格式。这可以使用App2Dmg
这款应用完成。
选择应用目录和要保存的目录后,就会生成.dmg
文件了