DiddiLeija's website

My personal website.

View on GitHub

Creating standalone Windows executables from Python code, using cx_Freeze

Diddi Freezing Python

Overview

Python is a great programming language. It is flexible, easy to understand, and powerful. But, in most of the cases, you have to install it from somewhere (most of the times, from the Python website).

So, you may ask: “Can I create applications made in Python that run without Python?” Yes! We can create executables. There are several tools for doing this, but let’s talk about cx_Freeze, a Python package to “freeze” Python scripts into standalone executables.

On this article, we’ll talk about how to use cx_Freeze on Windows, to create portable .exe applications. To reproduce the instructions, you’ll need a Python installation on your Windows computer (the Python version should be 3.6 or newer).

NOTE: cx_Freeze also works excellent under macOS, Linux, or any other platform compatible with Python. However, this article only talks about how to use it on Windows, since the commands and the setup may be a bit different.

Getting cx_Freeze using Pip

To install cx_Freeze, you can use pip, the standard package installer for Python:

pip install cx_Freeze

You can also use conda, it is available there too.

Build your Python application

On this article, we are going to use a Python GUI named gui.py:

# Use the standard Tkinter library to
# build a simple GUI with Python.

from tkinter import *

root = Tk()

frame = Frame(root)
frame.grid()

label = Label(frame, text="Hello world", bg="whitesmoke", fg="black", font=("Calibri", "13", "bold"))
label.grid(row=0, column=0, sticky="ew")

exit_btn = Button(frame, text="Exit", bg="red", fg="white", font=("Calibri", "13", "normal"), command=root.quit)
exit_btn.grid(row=1, column=0, sticky="ew")

root.mainloop()

and a command-line Python app named command-line.py:

# ask for a name, and return a message

import getpass

name = input("Enter your name: ")
print(f"\nHello {name}!\n")

# This is a trick to hide the characters and simulate a "Press Enter to exit"
getpass.getpass("Press Enter to exit... ")

Write a cx_Freeze setup file

# setup.py - cx_Freeze setup file

import sys

from cx_Freeze import Executable, setup

GUI_BASE = None

if sys.platform == "win32":
    # The "Win32GUI" base should be available,
    # so we'll take it
    GUI_BASE = "Win32GUI"

executables = [Executable("gui.py",
                          target_name="GUI sample.exe",
                          base=GUI_BASE),
               Executable("command-line.py",
                          target_name="Command-line sample.exe")]

setup("Our cx_Freeze example",
      version="1.0",
      description="""A simple Windows example of building
executables from Python code, using cx_Freeze.""",
      executables=executables)

cx_Freeze uses a setup.py file to build your executable. It provides a setup() function to specify how to do the conversion. In our example, we are going to convert the 2 Python files into 2 executables.

First, we have to import the cx_Freeze stuff we need. Also, we need the standard module sys:

import sys

from cx_Freeze import Executable, setup

Now, before defining the executables to create, we are going to use a trick to delete the annoying “console” on the GUI executable (that way, we’ll only see the GUI). cx_Freeze provides some “bases”, written in C, to modify the aspect of our executables. We are going to look for “Win32GUI” (which makes just what we want):

GUI_BASE = None

if sys.platform == "win32":
    # The "Win32GUI" base should be available,
    # so we'll take it
    GUI_BASE = "Win32GUI"

After that, we have to determine the executables using cx_Freeze.Executable. I personally like to define them in a separate variable, outside the setup():

executables = [Executable("gui.py",
                          target_name="GUI sample.exe",
                          base=GUI_BASE),
               Executable("command-line.py",
                          target_name="Command-line sample.exe")]

Finally, we run the setup() function (something that is commonly used on setup.py files):

setup("Our cx_Freeze example",
      version="1.0",
      description="""A simple Windows example of building
executables from Python code, using cx_Freeze.""",
      executables=executables)

And that’s it! Our setup.py file is ready!

Making the conversion

After we wrote our setup.py, we only have to run on console:

setup.py build

That will print a giant log, and then, our executables are done!

You can find the executables on a recently created build/ folder. On that folder, there should be another folder, that may vary depending on each Python installation. For example, on a Windows computer that uses Python 3.9 and has an amd64 arch, it will be build/exe.win-amd-64-3.9/. On a win32 computer with Python 3.7, it will be build/exe.win32-3.7/.

Anyway, if you open that folder, you will find your executables, a lib folder (that supplies the “frozen” Python library), and some DLLs. Suggestion: Don’t touch that stuff! They are essential for the executables.

Transporting your executable

You only have to move the build folder. After you create the .exe files, you won’t need a Python installation to enjoy your apps, so you can share the code to more users!

Note: If the computer where you run the executables has installed Python, the executable will take the native Python library, instead of its own library (take a look on that!).

Next steps

If you want to learn more cx_Freeze options, or how to freeze Python files with other platform, go to the cx_Freeze documentation or visit the GitHub repository.


And this is where the article ends. I hope you like it, and maybe share this with more people. To go back to the main page of my website, press here.