1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# calendar_gui.spec
# -*- mode: python ; coding: utf-8 -*-
import os
from PyInstaller.utils.hooks import collect_all
# Collect reportlab barcode data as you already did
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'], # keep your existing excludes
noarchive=False,
optimize=0,
)
# ---- Helper: drop specific native libs / plugin files we listed ----
# IMPORTANT: do NOT drop essential Qt runtime libs needed for your platform.
ESSENTIAL_QT_NAMES = [
'libQt5Core.so', 'libQt5Gui.so', 'libQt5Widgets.so', 'libQt5XcbQpa.so',
'libpython3.12.so', 'libstdc++.so.6', 'libc.so.6'
]
DROP_PATTERNS = [
# Pillow image codec libs you identified
'libavif-', 'libwebp-', 'liblcms2-',
'libsharpyuv', 'libwebpdemux', 'libwebpmux',
# Qt optional subsystems you listed (Quick, Qml, QmlModels, Svg, WebSockets)
'libQt5Quick.so', 'libQt5Qml.so', 'libQt5QmlModels.so',
'libQt5Svg.so', 'libQt5WebSockets.so', 'libQt5EglFSDeviceIntegration.so',
]
def should_drop_path(path_str):
s = str(path_str)
# never drop critical essentials
for ess in ESSENTIAL_QT_NAMES:
if ess in s:
return False
# drop if pattern matches
for p in DROP_PATTERNS:
if p in s:
return True
# also drop QML/translations directories
if '/qml/' in s or '\\qml\\' in s:
return True
if '/translations/' in s or '\\translations\\' in s:
return True
return False
# ---------- robust filtering for a.binaries / a.datas ----------
def _entry_src(obj):
"""
Return the 'source' part of a TOC entry for binaries/datas.
PyInstaller entries may be (src, dest) or (src, dest, type) etc.
"""
try:
# sequence-like entries (tuple/list)
return obj[0]
except Exception:
# fallback: maybe it's already a path-like object
return obj
filtered_binaries = []
for entry in a.binaries:
src = _entry_src(entry)
if should_drop_path(src):
# drop it
# print("Dropping binary:", src) # uncomment for debugging
continue
filtered_binaries.append(entry)
a.binaries = filtered_binaries
filtered_datas = []
for entry in a.datas:
src = _entry_src(entry)
if should_drop_path(src):
# print("Dropping data:", src) # uncomment for debugging
continue
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=True, # on Linux: strip Python bootstrap (saves some MB)
upx=True,
console=False,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=True, # strip shared objects where safe
upx=True,
upx_exclude=[], # leave empty; PyInstaller will avoid known-bad files
name='azrechner-trimmed',
)
|