summaryrefslogtreecommitdiff
path: root/azrechner-trimmed-v2.spec
diff options
context:
space:
mode:
Diffstat (limited to 'azrechner-trimmed-v2.spec')
-rw-r--r--azrechner-trimmed-v2.spec208
1 files changed, 208 insertions, 0 deletions
diff --git a/azrechner-trimmed-v2.spec b/azrechner-trimmed-v2.spec
new file mode 100644
index 0000000..e77e619
--- /dev/null
+++ b/azrechner-trimmed-v2.spec
@@ -0,0 +1,208 @@
+# calendar_gui.spec
+# -*- mode: python ; coding: utf-8 -*-
+import os
+import sys
+import collections
+from pathlib import Path
+from PyInstaller.utils.hooks import collect_all
+
+DEBUG_FILTER = False
+
+# Collect reportlab barcode data (same as before)
+datas = []
+binaries = []
+hiddenimports = []
+tmp_ret = collect_all('reportlab.graphics.barcode')
+datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
+
+# ---- Analysis ----
+a = Analysis(
+ ['calendar_gui.py'],
+ pathex=[os.getcwd()],
+ binaries=binaries,
+ datas=datas,
+ hiddenimports=hiddenimports,
+ hookspath=[],
+ hooksconfig={},
+ runtime_hooks=[],
+ excludes=['scipy','numpy'], # keep your existing excludes
+ noarchive=False,
+ optimize=0,
+)
+
+# Platform-aware essential names & drop patterns
+IS_WINDOWS = sys.platform.startswith('win')
+IS_MAC = sys.platform == 'darwin'
+IS_UNIX = not IS_WINDOWS and not IS_MAC
+
+# Lowercase names will be used for case-insensitive matching
+if IS_WINDOWS:
+ ESSENTIAL_QT_NAMES = [
+ 'qt5core.dll', 'qt5gui.dll', 'qt5widgets.dll',
+ # the platform plugin folder & plugin name on Windows
+ os.path.join('platforms', 'qwindows.dll'),
+ # Python runtime dlls that are critical
+ f'python{sys.version_info.major}{sys.version_info.minor}.dll', # e.g. python312.dll
+ ]
+ DROP_PATTERNS = [
+ # Qt optional DLLs you listed (Windows names)
+ 'Qt5Quick.dll', 'qt5qml.dll', 'qt5qmlmodels.dll',
+ 'qt5svg.dll', 'qt5websockets.dll', 'qt5eglfsdeviceintegration.dll',
+ # Pillow / image codec dll patterns (windows)
+ 'libavif', 'libwebp', 'lcms2', 'sharpyuv', 'openjp2', 'webpdemux', 'webpmux',
+ # qml/translations directories
+ ]
+ STRIP_ON_BUILD = False
+else:
+ # Linux / other UNIX
+ ESSENTIAL_QT_NAMES = [
+ 'libQt5Core.so', 'libQt5Gui.so', 'libQt5Widgets.so', 'libQt5XcbQpa.so',
+ 'libpython{major}.{minor}.so'.format(major=sys.version_info.major, minor=sys.version_info.minor),
+ 'libstdc++.so.6', 'libc.so.6'
+ ]
+ DROP_PATTERNS = [
+ # Pillow image codecs & windows variants too
+ 'libavif-', 'libwebp-', 'liblcms2-', 'libsharpyuv', 'libopenjp2',
+ # Qt optional subsystems you listed
+ 'libQt5Quick.so', 'libQt5Qml.so', 'libQt5QmlModels.so',
+ 'libQt5Svg.so', 'libQt5WebSockets.so', 'libQt5EglFSDeviceIntegration.so',
+ ]
+ STRIP_ON_BUILD = True
+
+# Normalize patterns to lowercase for case-insensitive comparisons
+ESSENTIAL_QT_NAMES = [p.lower() for p in ESSENTIAL_QT_NAMES]
+DROP_PATTERNS = [p.lower() for p in DROP_PATTERNS]
+
+# filter block
+def _iter_strings_in_entry(entry):
+ """
+ Yield all string-like parts found inside a PyInstaller TOC entry.
+ Handles:
+ - simple strings / Paths
+ - tuples/lists like (src, dest) or (src, dest, type)
+ - objects that have .path or similar (best-effort)
+ """
+ if entry is None:
+ return
+ # primitive string / Path
+ if isinstance(entry, (str, Path)):
+ yield str(entry)
+ return
+ # sequence-like: iterate
+ if isinstance(entry, collections.abc.Sequence) and not isinstance(entry, (str, bytes, bytearray)):
+ for el in entry:
+ # recurse
+ yield from _iter_strings_in_entry(el)
+ return
+ # fallback: try to cast to string
+ try:
+ s = str(entry)
+ if s:
+ yield s
+ except Exception:
+ return
+
+def _entry_has_any(entry, substring):
+ """Return True if any string part of the entry contains substring (case-insensitive)."""
+ sub = substring.lower()
+ for s in _iter_strings_in_entry(entry):
+ if sub in s.lower():
+ return True
+ return False
+
+def entry_basename_set(entry):
+ """
+ Return set of basenames (lowercased) found in the entry.
+ Useful to match bare filenames like 'Qt5Quick.dll' or 'libQt5Quick.so'.
+ """
+ names = set()
+ for s in _iter_strings_in_entry(entry):
+ try:
+ p = Path(s)
+ names.add(p.name.lower())
+ except Exception:
+ names.add(str(s).lower())
+ return names
+
+def should_drop_entry(entry):
+ """
+ Decide whether to drop this TOC entry.
+ Uses:
+ - ESSENTIAL_QT_NAMES (substrings) to never drop essentials
+ - DROP_PATTERNS (substrings) to drop matches
+ - qml/translations directory substrings
+ Matches case-insensitively against all string parts of the entry.
+ """
+ # never drop if any essential name substring appears in entry
+ for ess in ESSENTIAL_QT_NAMES:
+ if _entry_has_any(entry, ess):
+ return False
+
+ # drop if any drop-pattern matches
+ for p in DROP_PATTERNS:
+ if _entry_has_any(entry, p):
+ return True
+
+ # drop QML or translations paths
+ for s in _iter_strings_in_entry(entry):
+ sl = s.lower().replace('\\', '/')
+ if '/qml/' in sl or '/translations/' in sl:
+ return True
+
+ # Bonus: drop Pillow codec names if entry mentions 'pillow.libs' AND codec names
+ low_all = " ".join(s.lower() for s in _iter_strings_in_entry(entry))
+ if 'pillow.libs' in low_all and any(p in low_all for p in DROP_PATTERNS):
+ return True
+
+ # no reason to drop
+ return False
+
+
+# Now filter a.binaries and a.datas using should_drop_entry
+filtered_binaries = []
+for entry in a.binaries:
+ drop = should_drop_entry(entry)
+ if DEBUG_FILTER:
+ print(("DROP" if drop else "KEEP"), "binary:", list(_iter_strings_in_entry(entry)))
+ if not drop:
+ filtered_binaries.append(entry)
+a.binaries = filtered_binaries
+
+filtered_datas = []
+for entry in a.datas:
+ drop = should_drop_entry(entry)
+ if DEBUG_FILTER:
+ print(("DROP" if drop else "KEEP"), "data:", list(_iter_strings_in_entry(entry)))
+ if not drop:
+ filtered_datas.append(entry)
+a.datas = filtered_datas
+# ----------------------------------------------------------------
+
+
+# ---- Build steps: PYZ, EXE, COLLECT ----
+pyz = PYZ(a.pure, a.zipped_data, cipher=None)
+
+exe = EXE(
+ pyz,
+ a.scripts,
+ [],
+ exclude_binaries=True,
+ name='azrechner',
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=STRIP_ON_BUILD, # only strip on unix-like systems
+ upx=True,
+ console=False,
+)
+
+coll = COLLECT(
+ exe,
+ a.binaries,
+ a.zipfiles,
+ a.datas,
+ strip=STRIP_ON_BUILD, # only strip on unix-like systems
+ upx=True,
+ # if you know specific DLLs that break with UPX you can list them here
+ upx_exclude=[],
+ name='azrechner-trimmed-v2',
+)