Skip to content

Instantly share code, notes, and snippets.

@jiankaiwang
Created January 20, 2021 10:10
Show Gist options
  • Save jiankaiwang/5c1aa39346268fd95b4bb32272c41635 to your computer and use it in GitHub Desktop.
Save jiankaiwang/5c1aa39346268fd95b4bb32272c41635 to your computer and use it in GitHub Desktop.
In the following, we are going to show how to compile the python scripts into a binary executor running on different platforms via the package `pyinstaller`.

Python in Binary Executor

In the following, we are going to show how to compile the python scripts into a binary executor running on different platforms via the package pyinstaller.

Python-Side

In the python side, you can keep the way of developing. For example, you can create a virtual environment via virtualenv and then install lots of packages via the pip command. The similar approach is also available for the conda environment.

virtualenv -p python3 binary
source ./binary/bin/activate

# pip install from a python package list
pip install --no-cache-dir -r ./requirements.txt

pyinstaller

Now you have the python scripts and are ready for compiling them. Before you compile the script, you have to install the package for compile. After you install the pyinstaller, you can compile the script of entry.

pip install --no-cache-dir pyinstaller

# start to compile the scripts
pyinstaller main.py

After the compile is complete, you would find two folders, build and dist, and one file, *.spec were generated at your current path. The dist is the target folder what you can compressed and transfer to different machines.

However there are several issues that you have to check.

  • The necessary components: If your scripts require external resources, for example, the file or the configuration, you have to copy them into the dist folder as well. The pyinstaller helps you to prepare the necessary modules or shared libraries for the execution, but not resources you defined in the body.

  • The relative path issue: If you access the external resources, you would access it in a way of the relative or absolute path. However, you might encounter the error while using the __file__ attribute to get the absolute path. You have to judge the current execution type and then get the path.

The origin script:

# ...
currentPath = pathlib.Path(__file__)
absPath = currentPath.absolute()
# ...

The modified one:

# ...
import sys

if getter(sys, 'frozen', False):
  currentPath = pathlib.Path(sys.executable)
else:
  currentPath = pathlib.Path(__file__)
absPath = currentPath.absolute()
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment