PyInstaller¶
Package Windows binaries while running under Linux¶
Sample (sample.py) python code, It’s rest application that run with waitress wsgi server
$ cat ~/ws/wine/sample.py
from pycnic.core import WSGI, Handler
from waitress import serve
class Hello(Handler):
def get(self, name="World"):
return {"message": "Hello, %s!" % (name)}
class app(WSGI):
routes = [
('/', Hello()),
('/([\w]+)', Hello())
]
serve(app, host='0.0.0.0', port=9999)
Install Wine¶
$ sudo apt-get install wine
$ winecfg
Install Python¶
# note: Download 32bit of python from python.org
$ wine msiexec -i ~/ws/tools/windows/python/python-2.7.13.msi ALLUSERS=1
# @note: Install VCForPython27 if we want complie some python package from source code
$ wine msiexec /i ~/ws/tools/windows/python/VCForPython27.msi ALLUSERS=1
# Install python dependency of sample program by using pip
$ cd ~/ws/wine/
$ wine ~/.wine/drive_c/Python27/python.exe ~/.wine/drive_c/Python27/Scripts/pip.exe install waitress
$ wine ~/.wine/drive_c/Python27/python.exe ~/.wine/drive_c/Python27/Scripts/pip.exe install pycnic
# Install pyinstaller
$ wine ~/.wine/drive_c/Python27/python.exe ~/.wine/drive_c/Python27/Scripts/pip.exe install pyinstaller
$ cp ~/ws/wine/sample.py ~/.wine/drive_c/users/$USER/Desktop/sample.py
$ wine ~/.wine/drive_c/Python27/Scripts/pyinstaller.exe --onefile ~/.wine/drive_c/users/$USER/Desktop/sample.py
$ ls dist/
sample.exe
https://github.com/pyinstaller/pyinstaller/wiki/FAQ
https://github.com/paulfurley/python-windows-packager
https://www.paulfurley.com/packaging-python-for-windows-pyinstaller-wine/
https://stackoverflow.com/a/35605479
https://milkator.wordpress.com/2014/07/19/windows-executable-from-python-developing-in-ubuntu/
https://pythonhosted.org/PyInstaller/installation.html#installing-in-windows
Packaging a Python script into a Windows executable on Linux¶
# Install Wine
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install wine-stable
# Change Wine's emulated Windows version to Windows 10
WINEPREFIX=~/.wine64 winecfg
# Download and install Windows Python in Wine
wget https://www.python.org/ftp/python/3.9.0/python-3.9.0-amd64.exe
WINEPREFIX=~/.wine64 WINEARCH=win64 wine python-3.9.0-amd64.exe /quiet InstallAllUsers=1 PrependPath=1
# Verify Python installation and install pip
WINEPREFIX=~/.wine64 WINEARCH=win64 wine python -m ensurepip
WINEPREFIX=~/.wine64 WINEARCH=win64 wine python -m pip install --upgrade pip
# Install PyInstaller in Wine Python
WINEPREFIX=~/.wine64 WINEARCH=win64 wine python -m pip install pyinstaller
# Set up virtual environment (optional, but recommended)
python3 -m venv myenv
source myenv/bin/activate
# Install PyInstaller in your virtual environment
pip install pyinstaller
# Install requirements of project
WINEPREFIX=~/.wine64 WINEARCH=win64 wine python -m pip install -r requirements.txt
# Create a basic executable
WINEPREFIX=~/.wine64 WINEARCH=win64 wine pyinstaller --name=my_app --onefile my_app.py
# Modify the spec file if necessary (edit the .spec file generated by PyInstaller)
# Build the executable with Wine
WINEPREFIX=~/.wine64 WINEARCH=win64 wine pyinstaller my_app.spec
Modify the spec file to include necessary data files¶
# my_app_app.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['my_app/my_app.py'],
pathex=['/path/to/your/project_root'],
binaries=[],
datas=[
('config.json', '.'),
],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='my_app_app',
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,
upx_exclude=[],
name='my_app_app',
)
Build the Executable with Wine:¶
WINEPREFIX=~/.wine64 WINEARCH=win64 wine pyinstaller my_app.spec