171 lines
5.6 KiB
RPMSpec
171 lines
5.6 KiB
RPMSpec
|
|
# whisper_local.spec
|
||
|
|
# PyInstaller-Build-Konfiguration für whisper-local (Windows 64-bit, onedir)
|
||
|
|
#
|
||
|
|
# Ausführen: uv run pyinstaller whisper_local.spec --noconfirm
|
||
|
|
# Oder via: .\build.ps1
|
||
|
|
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
from PyInstaller.utils.hooks import collect_data_files
|
||
|
|
|
||
|
|
block_cipher = None
|
||
|
|
|
||
|
|
SP = Path(".venv/Lib/site-packages")
|
||
|
|
|
||
|
|
# ── Binaries ──────────────────────────────────────────────────────────────────
|
||
|
|
# ctranslate2: Haupt-DLL, CUDA (cudnn) und Intel OpenMP
|
||
|
|
# DLLs landen in ctranslate2/, damit ctranslate2's os.add_dll_directory() greift
|
||
|
|
binaries_list = [
|
||
|
|
(str(SP / "ctranslate2/ctranslate2.dll"), "ctranslate2"),
|
||
|
|
(str(SP / "ctranslate2/cudnn64_9.dll"), "ctranslate2"),
|
||
|
|
(str(SP / "ctranslate2/libiomp5md.dll"), "ctranslate2"),
|
||
|
|
|
||
|
|
# pywin32: COM- und WinTypes-DLLs müssen neben der EXE liegen
|
||
|
|
(str(SP / "pywin32_system32/pythoncom313.dll"), "."),
|
||
|
|
(str(SP / "pywin32_system32/pywintypes313.dll"), "."),
|
||
|
|
|
||
|
|
# sounddevice / PortAudio
|
||
|
|
(str(SP / "_sounddevice_data/portaudio-binaries/libportaudio64bit.dll"),
|
||
|
|
"_sounddevice_data/portaudio-binaries"),
|
||
|
|
(str(SP / "_sounddevice_data/portaudio-binaries/libportaudio64bit-asio.dll"),
|
||
|
|
"_sounddevice_data/portaudio-binaries"),
|
||
|
|
|
||
|
|
# onnxruntime (für Silero VAD in faster-whisper)
|
||
|
|
(str(SP / "onnxruntime/capi/onnxruntime.dll"),
|
||
|
|
"onnxruntime/capi"),
|
||
|
|
(str(SP / "onnxruntime/capi/onnxruntime_providers_shared.dll"),
|
||
|
|
"onnxruntime/capi"),
|
||
|
|
]
|
||
|
|
|
||
|
|
# av/FFmpeg: DLL-Namen enthalten Hashes — per Glob gesammelt
|
||
|
|
av_libs_dir = SP / "av.libs"
|
||
|
|
binaries_list += [(str(dll), "av.libs") for dll in av_libs_dir.glob("*.dll")]
|
||
|
|
|
||
|
|
# ── Datas ─────────────────────────────────────────────────────────────────────
|
||
|
|
datas_list = [
|
||
|
|
# Silero VAD ONNX-Modell (benötigt von faster-whisper)
|
||
|
|
(str(SP / "faster_whisper/assets/silero_vad_v6.onnx"),
|
||
|
|
"faster_whisper/assets"),
|
||
|
|
|
||
|
|
# sv_ttk Theme (TCL-Skripte + PNG-Spritesheets)
|
||
|
|
(str(SP / "sv_ttk/sv.tcl"), "sv_ttk"),
|
||
|
|
(str(SP / "sv_ttk/theme"), "sv_ttk/theme"),
|
||
|
|
|
||
|
|
# Beispiel-Konfiguration als Referenz
|
||
|
|
("config.example.toml", "."),
|
||
|
|
]
|
||
|
|
|
||
|
|
# certifi CA-Bundle für HTTPS (huggingface_hub Modell-Download)
|
||
|
|
datas_list += collect_data_files("certifi")
|
||
|
|
|
||
|
|
# ── Hidden Imports ────────────────────────────────────────────────────────────
|
||
|
|
# Alle Module hinter sys.platform-Guards oder lazy imports (importlib, __import__)
|
||
|
|
hidden_imports_list = [
|
||
|
|
# Eigene Windows-Backends (hinter sys.platform == "win32" Guards)
|
||
|
|
"whisper_local.hotkey._pynput",
|
||
|
|
"whisper_local.inserter._win32",
|
||
|
|
"whisper_local.tray._tray",
|
||
|
|
"whisper_local.tray._icon",
|
||
|
|
"whisper_local.tray._settings",
|
||
|
|
"whisper_local.tray._theme",
|
||
|
|
|
||
|
|
# pynput: Backend wird per importlib dynamisch gewählt
|
||
|
|
"pynput.keyboard._win32",
|
||
|
|
"pynput.mouse._win32",
|
||
|
|
"pynput._util",
|
||
|
|
"pynput._util.win32",
|
||
|
|
"pynput._util.win32_vks",
|
||
|
|
|
||
|
|
# pywin32
|
||
|
|
"win32api",
|
||
|
|
"win32con",
|
||
|
|
"win32gui",
|
||
|
|
"win32clipboard",
|
||
|
|
"pywintypes",
|
||
|
|
|
||
|
|
# pystray Windows-Backend + Utility-Unterpaket (relative imports)
|
||
|
|
"pystray._win32",
|
||
|
|
"pystray._util",
|
||
|
|
"pystray._util.win32",
|
||
|
|
|
||
|
|
# tkinter: lazy import in tray/_settings.py
|
||
|
|
"tkinter",
|
||
|
|
"tkinter.ttk",
|
||
|
|
|
||
|
|
# sv_ttk und darkdetect
|
||
|
|
"sv_ttk",
|
||
|
|
"darkdetect",
|
||
|
|
|
||
|
|
# onnxruntime Inference Collection
|
||
|
|
"onnxruntime.capi.onnxruntime_inference_collection",
|
||
|
|
|
||
|
|
# huggingface_hub für Modell-Download zur Laufzeit
|
||
|
|
"huggingface_hub",
|
||
|
|
"huggingface_hub.file_download",
|
||
|
|
"huggingface_hub.utils",
|
||
|
|
]
|
||
|
|
|
||
|
|
# ── Excludes ──────────────────────────────────────────────────────────────────
|
||
|
|
excludes_list = [
|
||
|
|
# Linux-only (nicht installiert auf Windows)
|
||
|
|
"evdev",
|
||
|
|
"whisper_local.hotkey._evdev",
|
||
|
|
"whisper_local.inserter._wayland",
|
||
|
|
# Build- und Test-Infrastruktur
|
||
|
|
"pytest",
|
||
|
|
"pytest_asyncio",
|
||
|
|
"hatchling",
|
||
|
|
# Nicht benötigt im gebündelten Binary
|
||
|
|
"unittest",
|
||
|
|
"doctest",
|
||
|
|
"pdb",
|
||
|
|
]
|
||
|
|
|
||
|
|
# ── Analysis ──────────────────────────────────────────────────────────────────
|
||
|
|
a = Analysis(
|
||
|
|
["whisper_local/__main__.py"],
|
||
|
|
pathex=["."],
|
||
|
|
binaries=binaries_list,
|
||
|
|
datas=datas_list,
|
||
|
|
hiddenimports=hidden_imports_list,
|
||
|
|
hookspath=[],
|
||
|
|
hooksconfig={},
|
||
|
|
runtime_hooks=[],
|
||
|
|
excludes=excludes_list,
|
||
|
|
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=True, # onedir-Modus: DLLs bleiben separat
|
||
|
|
name="whisper-local",
|
||
|
|
debug=False,
|
||
|
|
bootloader_ignore_signals=False,
|
||
|
|
strip=False,
|
||
|
|
upx=False, # UPX mit CUDA-DLLs deaktiviert
|
||
|
|
console=False, # kein Konsolenfenster (Tray-App)
|
||
|
|
disable_windowed_traceback=False,
|
||
|
|
argv_emulation=False,
|
||
|
|
target_arch=None,
|
||
|
|
codesign_identity=None,
|
||
|
|
entitlements_file=None,
|
||
|
|
)
|
||
|
|
|
||
|
|
coll = COLLECT(
|
||
|
|
exe,
|
||
|
|
a.binaries,
|
||
|
|
a.zipfiles,
|
||
|
|
a.datas,
|
||
|
|
strip=False,
|
||
|
|
upx=False,
|
||
|
|
upx_exclude=[],
|
||
|
|
name="whisper-local",
|
||
|
|
)
|