I've read several similar posts, but have not found one describing the issue I am having.
I have a short python script referencing an external image and using pygame's freetype. I believe I've handled the configuration and code changes necessary to support both of these. The executables made by pyinstaller work well both locally and when moved to another computer, except when I try to build as a "onefile". Building as 'onefile' will really help for my use case.
When I attempt to configure it to use 'onefile' to build all dependencies into the .exe file. Every attempt at this is resulting in an error that it can't find python310.dll. Python310.dll should be built into the .exe and should not need to be found elsewhere.
Python script and .spec file are below. Can anyone see what I am doing wrong?
import os
import sys
import pygame
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([800, 600])
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
splash_image = pygame.image.load(resource_path("chef_full.png"))
screen.blit(splash_image, (5,5))
font = pygame.freetype.Font(None, 24)
text = "Press 'Esc' to quit."
text_rect = font.get_rect(text)
text_rect.center = (400, 450)
text_rect = font.render_to(screen, text_rect, text, "white")
pygame.display.flip()
playing = True
while playing:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
playing = False
elif event.type == pygame.QUIT:
playing = False
clock.tick(30)
pygame.quit()
The .spec file:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['splash.py'],
pathex=[],
binaries=[],
datas=[('chef_full.png', '.')], # A png we use.
hiddenimports=['pygame.freetype'], # For display on screen
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=False, # Don't exclude for onefile builds
name='splash',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
# Skip collect for onefile
#coll = COLLECT(
# exe,
# a.binaries,
# a.zipfiles,
# a.datas,
# strip=False,
# upx=True,
# upx_exclude=[],
# name='splash',
#)
Thanks in advance.
The issue lies in the .spec
file. The way that I got this to work, was to use the following pyinstaller
command to auto-generate a --onefile
.spec
file:
pyi-makespec --onefile splash.py
Then, I modified datas
and hiddenimports
variables in the recently created splash.spec
file to what you had in your original .spec
file:
datas=[('chef_full.png', '.')], # A png we use.
hiddenimports=['pygame.freetype'], # For display on screen
Finally, I ran the following command:
pyinstaller --clean splash.spec
The --clean
option ensures that the pyinstaller
cache is cleaned and temporary files are removed before building.
Now, a single splash.exe
should be located in the dist
folder that pyinstaller
outputted.
Here is the full splash.spec
file that I used. I highlighted the areas that were added:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['splash.py'],
pathex=[],
binaries=[],
datas=[('chef_full.png', '.')], # A png we use.
hiddenimports=['pygame.freetype'], # For display on screen
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries, # Added
a.zipfiles, # Added
a.datas, # Added
[],
name='splash',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[], # Added
runtime_tmpdir=None, # Added
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
Notice that the exclude_binaries
variable is not present here.