Files
PyQt6_LaTaniere/La Tanière Launcher.spec
T

319 lines
7.0 KiB
RPMSpec

# -*- mode: python ; coding: utf-8 -*-
import os
from pathlib import Path
# 🔥 Base path fiable (indépendant du dossier de lancement)
BASE_DIR = Path(os.getcwd()).resolve()
if not (BASE_DIR / "src").exists():
raise Exception("Lance PyInstaller depuis la racine du projet")
print("BASE_DIR =", BASE_DIR)
# ------------------------------------------------------------------
# Analysis
# ------------------------------------------------------------------
a = Analysis(
[str(BASE_DIR / 'src' / 'main.py')],
pathex=['src'],
binaries=[],
datas=[
# Assets critiques
(str(BASE_DIR / 'assets' / 'Icon.ico'), 'assets'),
# Styles
(str(BASE_DIR / 'styles' / 'styles.qss'), 'styles'),
# UI (tu peux ajouter d'autres .ui ici)
# (str(BASE_DIR / 'ui' / 'mainwindow_vertical_pager.ui'), 'ui'),
],
hiddenimports=[
"pypresence"
],
hookspath=[],
hooksconfig={
# 🔥 STRICT MINIMUM
"qt_plugins": ["platforms"]
},
runtime_hooks=[],
# 🔥 Exclusions
excludes=[
# PySide6 - modules non utilisés
'PySide6.Qt3DAnimation',
'PySide6.Qt3DCore',
'PySide6.Qt3DExtras',
'PySide6.Qt3DInput',
'PySide6.Qt3DLogic',
'PySide6.Qt3DRender',
'PySide6.QtAxContainer',
'PySide6.QtBluetooth',
'PySide6.QtCharts',
'PySide6.QtConcurrent',
'PySide6.QtDataVisualization',
'PySide6.QtDesigner',
'PySide6.QtHelp',
'PySide6.QtLocation',
'PySide6.QtMultimedia', # Nécessaire pour l'audio
'PySide6.QtMultimediaWidgets',
'PySide6.QtNetwork', # Dépendance à QtMultimedia
'PySide6.QtNetworkAuth',
'PySide6.QtNfc',
'PySide6.QtOpenGL',
'PySide6.QtOpenGLWidgets',
'PySide6.QtPdf',
'PySide6.QtPdfWidgets',
'PySide6.QtPositioning',
'PySide6.QtPrintSupport',
'PySide6.QtQml',
'PySide6.QtQuick',
'PySide6.QtQuick3D',
'PySide6.QtQuickControls2',
'PySide6.QtQuickWidgets',
'PySide6.QtRemoteObjects',
'PySide6.QtScxml',
'PySide6.QtSensors',
'PySide6.QtSerialBus',
'PySide6.QtSerialPort',
'PySide6.QtSpatialAudio',
'PySide6.QtSql',
'PySide6.QtStateMachine',
'PySide6.QtSvg',
'PySide6.QtSvgWidgets',
'PySide6.QtTest',
'PySide6.QtTextToSpeech',
'PySide6.QtWebChannel',
'PySide6.QtWebEngineCore',
'PySide6.QtWebEngineQuick',
'PySide6.QtWebEngineWidgets',
'PySide6.QtWebSockets',
'PySide6.QtXml',
# Tests / dev tools
"test",
"tests",
"unittest",
"doctest",
"pydoc",
"pydoc_data",
# Packaging / build tooling
"distutils",
"setuptools",
"pkg_resources",
"pip",
"ensurepip",
# GUI stdlib inutiles
"tkinter",
"turtle",
"idlelib",
"curses",
# Legacy / obsolete
"lib2to3",
"2to3",
"nis",
"ossaudiodev",
"spwd",
# RPC / servers non utilisés
"xmlrpc",
"wsgiref",
"cgi",
"cgitb",
# Data / DB non utilisés
"sqlite3",
"dbm",
"dbm.dumb",
"csv",
# Concurrency non utilisée dans ton code
"multiprocessing",
#"concurrent",
#"asyncio",
# REPL / terminal
"readline",
"code",
# "codeop", # Nécessaire
"cmd",
# mail / network protocols non utilisés
"mailbox",
"imaplib",
"poplib",
"smtplib",
"nntplib",
"telnetlib",
"ftplib",
"netrc",
# Docs / browsing / parsing non utilisés directement
"pydoc_data",
"mailbox",
"imaplib",
"poplib",
"smtplib",
"nntplib",
"telnetlib",
# XML optionnel : agressif mais plutôt safe ici
"xml.dom",
"xml.etree",
"xml.parsers",
"xml.sax",
# Compression / archive optionnelles si non utilisées
"bz2",
"lzma",
"gzip",
#"zipfile", # Nécessaire à cause de pyinstaller
"tarfile",
"zipapp",
# audio stdlib non utilisée
"aifc",
"wave",
"sunau",
"chunk",
# divers peu probables
"mailcap",
"xdrlib",
"tabnanny",
"getpass",
# Windows services non utilisés
"win32service",
"win32serviceutil",
],
noarchive=True,
optimize=2,
)
# ------------------------------------------------------------------
# 🔥 Nettoyage DLL Qt (SAFE)
# ------------------------------------------------------------------
unwanted_dlls = [
'Qt6Pdf',
'Qt6Quick',
'Qt6Qml',
'Qt6QmlModels',
'Qt6QmlWorkerScript',
'Qt6WebEngine',
'Qt6WebEngineCore',
'Qt63DCore',
'Qt63DRender',
'Qt63DAnimation',
'Qt63DExtras',
'Qt63DInput',
'Qt63DLogic',
'Qt6Charts',
'Qt6DataVisualization',
'Qt6Bluetooth',
'Qt6Nfc',
'Qt6Positioning',
'Qt6Location',
'Qt6RemoteObjects',
'Qt6Scxml',
'Qt6Sensors',
'Qt6SerialBus',
'Qt6SerialPort',
'Qt6SpatialAudio',
'Qt6StateMachine',
# 'Qt6Svg', # Dependance lecteur svg
'Qt6TextToSpeech',
'Qt6WebChannel',
'Qt6WebSockets',
'Qt6Sql',
'Qt6Test',
'Qt6OpenGL', # Dependance a Qt6UiTools
'Qt6PrintSupport',
'Qt6Xml', # Dependance fichier .ui
'Qt6Help',
'Qt6Designer',
'Qt6Concurrent',
]
new_binaries = []
for item in a.binaries:
name = item[0].lower()
# filtre 1 : tes unwanted_dlls
if any(u.lower() in name for u in unwanted_dlls):
continue
# filtre 2 : nettoyage Qt
if any(x in name for x in [
# "imageformats", # à activer seulement si sûr
# "iconengines", # à garder pour les svg dans l'app
"tls",
"printsupport",
"opengl", # <- ne pas mettre en exclude.
"qml",
"quick",
"webengine",
]):
continue
new_binaries.append(item)
a.binaries = new_binaries
# ------------------------------------------------------------------
# 🔥 Suppression traductions Qt (gain taille)
# ------------------------------------------------------------------
a.datas = [
f for f in a.datas
if "translations" not in f[0].lower() and not f[0].endswith('.qm')
]
pyz = PYZ(a.pure, a.zipped_data)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='La Tanière Launcher',
debug=False,
bootloader_ignore_signals=False,
strip=False, # pas de strip sous windows
# 🔥 Compression max
upx=True,
upx_exclude=[
"_uuid.pyd",
"Qt6Core.dll",
"Qt6Gui.dll",
"Qt6Widgets.dll",
"Qt6UiTools.dll",
"qwindows.dll",
"python3*.dll",
"vcruntime*.dll",
"msvcp*.dll",
"vcruntime140.dll",
"msvcp140.dll"
],
runtime_tmpdir=None,
console=True,
# 🔥 ONEFILE
onefile=True,
disable_windowed_traceback=True,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
# 🔥 Icône EXE (important mais pas suffisant seul)
icon=str(BASE_DIR / 'assets' / 'Icon.ico'),
)