I\'m trying to build a one-file EXE with PyInstaller which is to include an image and an icon. I cannot for the life of me get it to work with --onefile
.
I have been dealing with this issue for a long(well, very long) time. I've searched almost every source but things were not getting in a pattern in my head.
Finally, I think I have figured out exact steps to follow, I wanted to share.
Note that, my answer uses informations on the answers of others on this question.
Assume, we have a project_folder and the file tree is as follows:
project_folder/ main.py xxx.py # modules xxx.py # modules sound/ # directory containing the sound files img/ # directory containing the image files venv/ # if using a venv
First of all, let's say you have defined your paths to sound/
and img/
folders into variables sound_dir
and img_dir
as follows:
img_dir = os.path.join(os.path.dirname(__file__), "img")
sound_dir = os.path.join(os.path.dirname(__file__), "sound")
You have to change them, as follows:
img_dir = resource_path("img")
sound_dir = resource_path("sound")
Where, resource_path()
is defined in the top of your script as:
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
Activate virtual env if using a venv,
Install pyinstaller if you didn't yet, by: pip3 install pyinstaller
.
Run: pyi-makespec --onefile main.py
to create the spec file for the compile and build process.
This will change file hierarchy to:
project_folder/ main.py xxx.py # modules xxx.py # modules sound/ # directory containing the sound files img/ # directory containing the image files venv/ # if using a venv main.spec
Open(with an edior) main.spec
:
At top of it, insert:
added_files = [
("sound", "sound"),
("img", "img")
]
Then, change the line of datas=[],
to datas=added_files,
For the details of the operations done on main.spec
see here.
Run pyinstaller --onefile main.spec
And that is all, you can run main
in project_folder/dist
from anywhere, without having anything else in its folder. You can distribute only that main
file. It is now, a true standalone.