# Python to .exe

I build a Serial Tool for developing serial communication and custom protocols. Than I wish to share it with my friends and than there was a problem.

Originally, Serial Tool was written in python v2.7 and pyqt4. My first windows distribution was created with py2exe with no problem. I followed simple online tutorial and voila, there it was, my first .exe. Awesome.

The problem is, PyQt4 is “out of date”. There are some unofficial distributions, but all developement is focused on Qt5. Python v2.7 is not outdated, but v3.x is where long-term Python milestones are set. So I switched to Python v3.6 and port complete project in few hours without any problems. Until I tried to build my second .exe, than the nightmare began.

This are my conclusions. I tried with py2exe, PyInstaller and Cx_freeze. My main goal was to create a script, that I could simply copy and run with my other projects.

py2exe is not compatible with Python v3.6. OK for v2.7. and official page reports success with v3.4, but certanly not v3.6. There is a little more work (aka. google knows) with PyQt and including all possible dependecies.

PyInstaller is partly compatible with v3.6, even though official site says it is fully compatible. I didn’t test it with v3.5 (which should work according to the other forum questions asked online). It is capable of producing single-file executable and can work for pyqt and other libraries out of the box, but the problem is, it is buggy (for v3.6). Sometimes everything works OK, than you add some options like –onefile or –noconsole and nothing happens or a faulty .exe is produced. I gave up after few hours of testing since I just couldn’t create a reliable solution that would work with v3.6.

cx_Freeze seems to be the only one really working with v3.6. It can’t produce single file executable, but at least options in the docs works and overall it is the only one that gave me reliable builds.
It has an option to create a single file installer that can be used to create start menu shortcut and uninstaller if that is what you are after (but you can to this later with other tools like Windows IExpress). It is cross-platform, but I only tested it with Windows.

# Conclusion

I chose cx_Freeze. I longed for one file feature, but at the end reliability and funcionality wins over non-working features. I also created a python and win script that you can re-run when developing and building your projects.

to_exe.zip
(2 files, 2KB)

This zip includes 2 files. to_exe.py and to_exe.bat. Copy both of this files to your project (the same folder where your python script is.
Don’t forget to install cx_Freeze.

### to_exe.py

This is the file you must edit before you run to_exe.bat. Open it and edit fields to # cx_freeze stuff.

# EDIT according to your project
SCRIPT = "main.pyw" # main script to build to .exe
APP_NAME = "Serial Tool" # also output name of .exe file
DESCRIPTION = "Serial port communication tool"
VERSION = "1.2"
GUI = True # if true, this is GUI based app - no console is displayed
ICON = 'damogranlabs.ico' # your icon or None

CREATE_ZIP = True # set to True if you wish to create a zip once build is generated

executable_options = {
'build_exe': {
# pyqt5 (from official cx_freeze examples)
'includes': ['atexit'],

# exclude all other GUIs except Pyqt5
'excludes': ['wx', 'gtk', 'PyQt4', 'Tkinter'],

'include_files': ['damogranlabs.png'],

# amount of data displayed while freezing
'silent': [True]
}
}


cx_Freeze creates \build subfolder and it places your platform specific build folder in there (for example exe.win23-3.6 folderwhere actual build and and all dependencies are placed. There is an CREATE_ZIP option – if enabled, it zips your content of a newly created \build subfolder after completition (simplyfies sharing your software).

### to_exe.bat

This is just a windows script to run your to_exe.py script with python. It assumes python cmd command belongs to v3.6. Modify it to py v3.6 path if this is not true.
Also, uncommend/comment (remove/add “REM” to appropriate line) if you wish to create windows installer instead of usual \build directory structure with dependencies.

When you are ready, just run this file with double click and check terminal to see what is going on.

## OMG, look at the size of this build!

Yep. For console based scripts that just do stuff, print results or do simple tasks, this is not a problem. .exe includes python interpreter, and other critical components, usually sized around 10MB or so. But, when you use PyQt, Numpy, Matplotlib or other large libraries, executables can become very large. For instance, my Serial Tool is based on PyQt5. Code itself is around 100kB, but the executable is 200MB. This is due Qt (176MB) and all other dependecies. It is hard to find out what is really necessary and what is there just because modules import other libs. You can always delete, try, …. or you say f*** it and share a zip-ed version of this 200MB build, which is around 70MB. At the end of the day, transfering 70MB is a matter of a minute or so on a decent internet link.