fix: le .exe Windows demarrait sans plugin de plateforme Qt
Le hook PySide6 de PyInstaller importe QtCore pour localiser les plugins Qt. Depuis Qt 6.10, Qt6Core.dll est lie a l'ICU de Windows (icuuc.dll, System32), que Wine n'implemente pas : l'import echouait, le hook ne collectait aucun plugin, et le binaire produit refusait de demarrer sous Windows avec « could not initialize Qt platform plugin "windows" ». - La build Wine epingle PySide6<6.10 (PYSIDE6_CONSTRAINT pour surcharger). - Verification avant compilation que PySide6 s'importe reellement. - Verification apres compilation que qwindows.dll est embarque. - Reinstallation des dependances declenchee par empreinte de requirements.txt et de la contrainte, au lieu de la seule presence de PyInstaller. Binaire verifie sous Wine : GUI (fenetre a trois onglets) et CLI OK, 45 Mo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,21 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [Non publié]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Le binaire Windows produit sous Wine ne démarrait pas (« could not initialize
|
||||||
|
Qt platform plugin "windows" ») : le hook PySide6 de PyInstaller importe
|
||||||
|
QtCore pour localiser les plugins Qt, or Qt 6.10+ lie `Qt6Core.dll` à l'ICU
|
||||||
|
de Windows (`icuuc.dll`), absent de Wine. L'import échouait et aucun plugin
|
||||||
|
n'était embarqué. La compilation Windows épingle désormais `PySide6<6.10` et
|
||||||
|
vérifie explicitement l'import de PySide6 puis la présence de `qwindows.dll`.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `Makefile` avec aide auto-documentée par catégories (`make help`).
|
||||||
|
- `packaging/build_windows_wine.sh` : production du `.exe` Windows depuis Linux.
|
||||||
|
- `README.md`.
|
||||||
|
- `make publish` : pousse branche et tags vers tous les dépôts Gitea configurés.
|
||||||
|
|
||||||
## [0.1.2] - 2026-09-04
|
## [0.1.2] - 2026-09-04
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -82,9 +82,14 @@ incrémentaux.
|
|||||||
Sur une machine Windows, `packaging/build_windows.bat` fait le même travail
|
Sur une machine Windows, `packaging/build_windows.bat` fait le même travail
|
||||||
nativement.
|
nativement.
|
||||||
|
|
||||||
> Le `.exe` s'appuie sur l'ICU fourni par le système (`icuuc.dll` dans
|
La build Wine épingle **Qt 6.9** (`PySide6<6.10`) : à partir de Qt 6.10,
|
||||||
> `System32`), présent depuis Windows 10 1703 et Windows Server 2019. Il ne
|
`Qt6Core.dll` dépend de l'ICU fourni par Windows (`icuuc.dll` dans `System32`),
|
||||||
> peut pas être testé sous Wine, qui ne fournit pas cette bibliothèque.
|
que Wine n'implémente pas. PySide6 y devient inimportable — et le hook PySide6
|
||||||
|
de PyInstaller, qui importe QtCore pour localiser les plugins Qt, échoue alors
|
||||||
|
*silencieusement* et produit un `.exe` sans plugin de plateforme, qui refuse de
|
||||||
|
démarrer sous Windows (« could not initialize Qt platform plugin windows »). Le
|
||||||
|
script vérifie donc, avant compilation, que PySide6 s'importe, et après
|
||||||
|
compilation, que `qwindows.dll` est bien embarqué.
|
||||||
|
|
||||||
## Publication
|
## Publication
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ set -euo pipefail
|
|||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
PYTHON_VERSION="${PYTHON_VERSION:-3.12.10}"
|
PYTHON_VERSION="${PYTHON_VERSION:-3.12.10}"
|
||||||
|
# Depuis Qt 6.10, Qt6Core.dll est lie a l'ICU fourni par Windows (icuuc.dll dans
|
||||||
|
# System32, present depuis Win10 1703). Wine ne fournit pas cette DLL : PySide6
|
||||||
|
# y devient inimportable, et le hook PySide6 de PyInstaller -- qui importe QtCore
|
||||||
|
# pour localiser les plugins Qt -- echoue alors SILENCIEUSEMENT et produit un
|
||||||
|
# .exe depourvu de plugin de plateforme ("could not initialize Qt platform
|
||||||
|
# plugin windows" au lancement). On contraint donc cette build a Qt 6.9.
|
||||||
|
PYSIDE6_CONSTRAINT="${PYSIDE6_CONSTRAINT:-PySide6<6.10}"
|
||||||
WINEPREFIX="${WINEPREFIX:-$PWD/.build-wine}"
|
WINEPREFIX="${WINEPREFIX:-$PWD/.build-wine}"
|
||||||
export WINEPREFIX
|
export WINEPREFIX
|
||||||
export WINEARCH=win64
|
export WINEARCH=win64
|
||||||
@@ -52,13 +59,30 @@ if [ ! -f "$PY_DIR/Scripts/pip.exe" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# pip sous Wine est lent (plusieurs minutes pour le wheel PySide6) : on ne
|
# pip sous Wine est lent (plusieurs minutes pour le wheel PySide6) : on ne
|
||||||
# reinstalle que si le prefixe est neuf. FORCE_DEPS=1 pour forcer une mise a jour.
|
# reinstalle que si requirements.txt ou la contrainte ont change (FORCE_DEPS=1
|
||||||
if [ ! -d "$PY_DIR/Lib/site-packages/PyInstaller" ] || [ "${FORCE_DEPS:-0}" = "1" ]; then
|
# pour forcer).
|
||||||
|
DEPS_STAMP="$PY_DIR/.deps-stamp"
|
||||||
|
WANT_HASH="$(cat requirements.txt <(echo "$PYSIDE6_CONSTRAINT") | sha256sum | cut -d' ' -f1)"
|
||||||
|
if [ "${FORCE_DEPS:-0}" = "1" ] || [ "$(cat "$DEPS_STAMP" 2>/dev/null)" != "$WANT_HASH" ]; then
|
||||||
echo ">> Installation des dependances Windows (peut prendre plusieurs minutes)"
|
echo ">> Installation des dependances Windows (peut prendre plusieurs minutes)"
|
||||||
|
printf '%s\n' "$PYSIDE6_CONSTRAINT" > "$PY_DIR/constraints.txt"
|
||||||
|
# Desinstallation prealable : pip ne retrograde pas toujours un paquet deja
|
||||||
|
# installe qui viole une contrainte nouvellement ajoutee.
|
||||||
|
wine "$WPY" -m pip uninstall -q -y PySide6 PySide6-Essentials PySide6-Addons shiboken6 >/dev/null 2>&1 || true
|
||||||
wine "$WPY" -m pip install -q --no-warn-script-location \
|
wine "$WPY" -m pip install -q --no-warn-script-location \
|
||||||
-r requirements.txt pyinstaller
|
-c c:\\python\\constraints.txt -r requirements.txt pyinstaller
|
||||||
|
echo "$WANT_HASH" > "$DEPS_STAMP"
|
||||||
else
|
else
|
||||||
echo ">> Dependances Windows deja presentes (FORCE_DEPS=1 pour les mettre a jour)"
|
echo ">> Dependances Windows a jour (FORCE_DEPS=1 pour les reinstaller)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Garde-fou : si PySide6 ne s'importe pas ici, le hook PyInstaller ne collectera
|
||||||
|
# aucun plugin Qt et produira un .exe casse sans le signaler. Echouer tot.
|
||||||
|
echo ">> Verification de PySide6 sous Wine"
|
||||||
|
if ! wine "$WPY" -c "import PySide6.QtWidgets" 2>&1; then
|
||||||
|
echo "ERREUR : PySide6 n'est pas importable sous Wine — le .exe produit serait" >&2
|
||||||
|
echo " depourvu de plugins Qt. Verifiez PYSIDE6_CONSTRAINT." >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ">> Compilation du .exe"
|
echo ">> Compilation du .exe"
|
||||||
@@ -73,6 +97,13 @@ wine "$WPY" -m PyInstaller \
|
|||||||
main.py
|
main.py
|
||||||
|
|
||||||
wineserver -w
|
wineserver -w
|
||||||
|
|
||||||
|
# Garde-fou : sans qwindows.dll, l'application refuse de demarrer sous Windows.
|
||||||
|
if ! grep -qi 'qwindows.dll' build/windows/JoinDomainGUI/PKG-00.toc; then
|
||||||
|
echo "ERREUR : le plugin de plateforme qwindows.dll est absent du binaire." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Binaire produit : dist/windows/JoinDomainGUI.exe"
|
echo "Binaire produit : dist/windows/JoinDomainGUI.exe"
|
||||||
echo "Lancement : clic droit -> Executer en tant qu'administrateur"
|
echo "Lancement : clic droit -> Executer en tant qu'administrateur"
|
||||||
|
|||||||
Reference in New Issue
Block a user