I'm making a pygame program that is designed to be modular. I am building an exe with pygame2exe of the file main.py, which basically just imports the real main game and runs it. What I'm hoping for is a sort of launcher that will execute Python scripts from an EXE, rather than a single program containing all immutable files.
What is the best way to go about this? I've tried using imp to dynamically import all modules at runtime instead of implicitly importing them, but that seems to break object inheritance.
Underneath the GUI is PyInstaller, a terminal based application to create Python executables for Windows, Mac and Linux. Veteran Pythonistas will be familiar with how PyInstaller works, but with auto-py-to-exe any user can easily create a single Python executable for their system.
In PyInstaller it is easy to create one exe, By default both create a bunch of exes & dlls. In py2exe its easier to embed manifest file in exe, useful for run as administrator mode in windows vista and beyond. Pyinstaller is modular and has a feature of hooks to include files in the build that you like.
There are five alternatives to PyInstaller for Windows, Linux and Mac. The best alternative is nuitka, which is both free and Open Source. Other great apps like PyInstaller are py2exe, cx_Freeze, Shed Skin and bbfreeze.
After some experiments I've found a solution.
Create a separate folder source
in the main folder of the application. Here will be placed source files. Also place file __init__.py
to the folder. Lets name a main file like main_module.py
.
Add all of its contents as a data files to the py2exe configuration setup.py
. Now after compiling the program, these files will be placed in the dist folder.
data_files += [('source', glob('source/*.py'),)]
setup(
data_files=data_files,
.... # other options
windows=[
{
"script": "launcher.py",
"icon_resources": [(0, "resources/favicon.ico")]
}
)
Make launcher.py
- it's task is to import all system and required libraries like pygame, pyqt and so on. Then run you program:
import sys, time, os, hashlib, atexit # std modules
import PyQt5, ... # foreign libraries
sys.path.insert(0, 'source')
exec('import main_module')
Now main_module.py
will be imported, if it imports your modules, they will be imported too in their places in hierarchy. For example head of the main_module.py
can be like this:
import user_tweaks
from user_data import parser
These files user_tweaks.py
and user_data.py
should be located in source
folder at appropriate paths relative to main_module.py
.
You may change contents of source
folder without recompilation program itself. Any time program runs it uses fresh contents of source
.
As a result you have an application folder with:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With