working windows module

This commit is contained in:
ske087
2026-07-31 15:40:59 +03:00
parent d0ea94447a
commit 5c2b3f545f
4 changed files with 556 additions and 181 deletions
+70 -25
View File
@@ -153,37 +153,78 @@ source_tree = Tree(str(SRC_DIR), prefix='', excludes=['*.pyc', '__pycache__', '*
import importlib.util
from pathlib import Path as _Path
def _find_share_dlls(package_path, subdir='bin'):
"""Find .dll files under a package's share/ directory."""
if not package_path:
def _site_packages_dir(package_path):
"""Climb up from a package's __init__.py to its site-packages dir."""
d = _Path(package_path).parent
while d.name != 'site-packages' and d.parent != d:
d = d.parent
return d
def _find_share_dlls(package_name, share_name=None):
"""Find .dll files under venv_root/share/<share_name>/.
kivy_deps.sdl2/angle/glew and ffpyplayer install their DLLs into
<venv>/share/<pkg>/... NOT inside the package dir. The share folder is
named after the *short* dep name (e.g. 'sdl2', 'angle', 'glew'), not the
dotted package name ('kivy_deps.sdl2'), so pass share_name explicitly.
"""
if share_name is None:
share_name = package_name
spec = importlib.util.find_spec(package_name)
if spec is None or not spec.origin:
return []
base = _Path(package_path).parent
# Check: share/<pkg>/bin/ relative to parent
share = base / 'share'
if share.is_dir():
sp = _site_packages_dir(spec.origin)
# Climb from site-packages up until we find a sibling 'share' dir
# (site-packages -> Lib -> venv, where venv/share lives).
d = sp
while d.parent != d:
if (d.parent / 'share').is_dir():
share = d.parent / 'share' / share_name
break
d = d.parent
else:
return []
if not share.is_dir():
return []
results = []
for root, dirs, files in os.walk(share):
for f in files:
if f.endswith('.dll'):
results.append((os.path.join(root, f), '.'))
return results
def _find_ffpyplayer_bins():
"""Return ffpyplayer's own dependency DLL dirs (FFmpeg + bundled SDL).
ffpyplayer ships a `dep_bins` list that already points at the correct
share/ffpyplayer/ffmpeg/bin and share/ffpyplayer/sdl/bin directories.
"""
try:
import ffpyplayer
bins = getattr(ffpyplayer, 'dep_bins', None)
if not bins:
return []
results = []
for root, dirs, files in os.walk(share):
for f in files:
if f.endswith('.dll'):
results.append((os.path.join(root, f), '.'))
for b in bins:
bpath = _Path(b)
if bpath.is_dir():
for f in bpath.glob('*.dll'):
results.append((str(f), '.'))
return results
return []
except Exception:
return []
# SDL2 DLLs
_sdl2_spec = importlib.util.find_spec('kivy_deps.sdl2')
_sdl2_dlls = _find_share_dlls(_sdl2_spec.origin if _sdl2_spec else None)
# ANGLE DLLs
_angle_spec = importlib.util.find_spec('kivy_deps.angle')
_angle_dlls = _find_share_dlls(_angle_spec.origin if _angle_spec else None)
# SDL2 / ANGLE / GLEW DLLs (kivy_deps share dirs)
_sdl2_dlls = _find_share_dlls('kivy_deps.sdl2', 'sdl2')
_angle_dlls = _find_share_dlls('kivy_deps.angle', 'angle')
_glew_dlls = _find_share_dlls('kivy_deps.glew', 'glew')
# GLEW DLLs
_glew_spec = importlib.util.find_spec('kivy_deps.glew')
_glew_dlls = _find_share_dlls(_glew_spec.origin if _glew_spec else None)
# ffpyplayer FFmpeg DLLs
_ffpy_spec = importlib.util.find_spec('ffpyplayer')
_ffpy_dlls = _find_share_dlls(_ffpy_spec.origin if _ffpy_spec else None)
# ffpyplayer FFmpeg + bundled SDL DLLs (via dep_bins)
_ffpy_dlls = _find_ffpyplayer_bins()
_all_binaries = _sdl2_dlls + _angle_dlls + _glew_dlls + _ffpy_dlls
@@ -194,6 +235,10 @@ if not _all_binaries:
print("fails with 'SDL2.dll not found' or similar, you will need")
print("to manually add the DLL paths to the spec file.")
print("=" * 70)
else:
print(f"[spec] Bundling {len(_all_binaries)} DLLs:")
for _p, _t in sorted(_all_binaries):
print(f" {_Path(_p).name} <- {_p}")
# --- Build the .exe --------------------------------------------------
a = Analysis(