diff --git a/CHANGELOG.md b/CHANGELOG.md index ea3f702..401e6e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # 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 ### Changed diff --git a/README.md b/README.md index a2597de..a34bdda 100644 --- a/README.md +++ b/README.md @@ -82,9 +82,14 @@ incrémentaux. Sur une machine Windows, `packaging/build_windows.bat` fait le même travail nativement. -> Le `.exe` s'appuie sur l'ICU fourni par le système (`icuuc.dll` dans -> `System32`), présent depuis Windows 10 1703 et Windows Server 2019. Il ne -> peut pas être testé sous Wine, qui ne fournit pas cette bibliothèque. +La build Wine épingle **Qt 6.9** (`PySide6<6.10`) : à partir de Qt 6.10, +`Qt6Core.dll` dépend de l'ICU fourni par Windows (`icuuc.dll` dans `System32`), +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 diff --git a/packaging/build_windows_wine.sh b/packaging/build_windows_wine.sh index 18cc4d2..d402c4e 100755 --- a/packaging/build_windows_wine.sh +++ b/packaging/build_windows_wine.sh @@ -11,6 +11,13 @@ set -euo pipefail cd "$(dirname "$0")/.." 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}" export WINEPREFIX export WINEARCH=win64 @@ -52,13 +59,30 @@ if [ ! -f "$PY_DIR/Scripts/pip.exe" ]; then fi # 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. -if [ ! -d "$PY_DIR/Lib/site-packages/PyInstaller" ] || [ "${FORCE_DEPS:-0}" = "1" ]; then +# reinstalle que si requirements.txt ou la contrainte ont change (FORCE_DEPS=1 +# 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)" + 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 \ - -r requirements.txt pyinstaller + -c c:\\python\\constraints.txt -r requirements.txt pyinstaller + echo "$WANT_HASH" > "$DEPS_STAMP" 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 echo ">> Compilation du .exe" @@ -73,6 +97,13 @@ wine "$WPY" -m PyInstaller \ main.py 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 "Binaire produit : dist/windows/JoinDomainGUI.exe" echo "Lancement : clic droit -> Executer en tant qu'administrateur"