Guide
install
pip3 install pywin32 pyinstaller
pip3 install --upgrade setuptools
pyinstall -F demo.py
error
pyinstaller AttributeError: 'str' object has no attribute 'items'
solution:
pip3 install --upgrade setuptools
usage
pyinstaller -h
params:
General Options
-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)
–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, ERROR, CRITICAL (default: INFO).
What to generate
-D, --onedir Create a one-folder bundle containing an executable (default) -F, --onefile Create a one-file bundled executable.
What to bundle, where to search
--add-data <SRC;DEST or SRC:DEST> This option can be used multiple times. --add-binary <SRC;DEST or SRC:DEST> 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 --hidden-import MODULENAME, --hiddenimport MODULENAME Name an import not visible in the code of the script(s). 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) -w, --windowed, --noconsole Windows and Mac OS X: do not provide a console window for standard i/o
Example
use pyd
path related source code
sys.path.append('./sdk/superdog/')
import superdog # superdog.pyd
pyinstaller commands
pyinstaller -y -D --path="sdk/superdog" demo.py
# pyinstaller -y -D --add-binary './sdk/superdog/superdog.pyd;.'
# --add-binary './sdk/superdog/dog_windows_x64.dll;.' demo.py
generate build
and dist
folder, plus demo.spec
output
78 INFO: Extending PYTHONPATH with paths
['E:\\git\\python\\helloworld',
'E:\\git\\python\\helloworld\\sdk\\superdog',
'E:\\git\\python\\helloworld']
demo.spec
# -*- mode: python -*-
block_cipher = None
a = Analysis(['demo.py'],
pathex=['sdk/superdog', 'E:\\git\\python\\helloworld'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
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,
name='demo',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='demo')
view build/demo/xref-demo.html
superdog found.
Tips:
if we usepyinstaller -y -D demo.py
don’t include--path="sdk/superdog"
,
package will be missing, and error occur when we run executable.
run executable
cd dist/demo
./demo.exe
# OK
all related dlls have been copied to
dist/demo/
folder,
eg.cublas64_80.dll,curand64_80.dll,cudart64_80.dll,cudnn64_6.dll
use ctype DLLs
path related source code
sys.path.append('./sdk/superdog/')
sys.path.append('./sdk/detect/')
import superdog # superdog.pyd
import detect # detect.py cuda80_detect.dll cuda90_detect.dll
CDLL related source code
lib = CDLL("./sdk/detect/cuda80_detect_cpp_dll.dll", RTLD_GLOBAL)
pyinstaller commands
pyinstaller -y -D --path="sdk/superdog;sdk/detect" demo.py
warning
93 INFO: Extending PYTHONPATH with paths
['E:\\git\\python\\helloworld',
'E:\\git\\python\\helloworld\\sdk\\superdog',
'E:\\git\\python\\helloworld\\sdk\\detect',
'E:\\git\\python\\helloworld']
...
WARNING: Ignoring ./sdk/detect/cuda80_detect_cpp_dll.dll imported
from E:\git\python\helloworld\sdk\detect\detect.py -
ctypes imports are only supported using bare filenames
fix
#lib = CDLL("./sdk/detect/cuda80_detect_cpp_dll.dll", RTLD_GLOBAL)
lib = CDLL("cuda80_detect_cpp_dll.dll", RTLD_GLOBAL)
Tips: for CDLL with pyinstaller, we must use bare filenames in python source.
see here
now we run pyintaller again
pyinstaller -y -D --path="sdk/superdog;sdk/detect" demo.py
view build/demo/xref-demo.html
superdog and detect.
run executable
cd dist/demo
./demo.exe
# OK
all related dlls have been copied to
dist/demo/
folder,
eg.cublas64_80.dll,curand64_80.dll,cudart64_80.dll,cudnn64_6.dll
andcuda80_detect_cpp_dll.dll
Version
get version
python grab_version.py "/path/to/xxx.exe"
C:\Users\zunli\AppData\Local\Programs\Python\Python35\Lib\site-packages\
PyInstaller\utils\cliutils\grab_version.py
file_version_info.txt
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(9, 0, 4, 23780),
prodvers=(9, 0, 4, 23780),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x40004,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'080404b0',
[StringStruct(u'CompanyName', u'Tencent'),
StringStruct(u'FileDescription', u'腾讯QQ'),
StringStruct(u'FileVersion', u'9.0.4.23780'),
StringStruct(u'LegalCopyright', u'Copyright (C) 1999-2018 Tencent. All Rights Reserved'),
StringStruct(u'ProductName', u'腾讯QQ'),
StringStruct(u'ProductVersion', u'9.0.4.23780')])
]),
VarFileInfo([VarStruct(u'Translation', [2052, 1200])])
]
)
set version
python pyinstaller.py \
--version-file=file_version_info.txt \
--icon=ico.ico \
-y -D \
--path="sdk/superdog;sdk/detect" \
demo.py
Advanced
Running PyInstaller with Python optimizations
Tips: be carefull with optimizations.
PyInstaller can be run with Python optimization flags (-O
or -OO
)
by executing it as a Python module, rather than using the pyinstaller
command:
python -O -m PyInstaller -y -D --path="sdk/superdog" demo.py
Or, by explicitly setting the PYTHONOPTIMIZE
environment variable to a non-zero value:
# Unix
PYTHONOPTIMIZE=1 pyinstaller myscript.py
# Windows
set PYTHONOPTIMIZE=1 && pyinstaller myscript.py
only import what you need
replace import os
with from os import path
to reduce final executable size.
Using UPX
see upx
Encrypting Python Bytecode
To encrypt the Python bytecode modules stored in the bundle, pass the --key=key-string
argument on the command line.
For this to work, you must have the PyCrypto
module installed. The key-string is a string of 16 characters which is used to encrypt each file of Python byte-code before it is stored in the archive inside the executable file.
pip install pycrypto
Other similar tools
- py2exe: pip install py2exe
- cx_freeze: pip install cx_freeze
- py2app: pip install py2app
- nuitka from here
Reference
History
- 20181213: created.