L'application ne demarrait pas du tout : gui/app.py importait pyqtSignal, qui est le nom PyQt du signal, absent de PySide6. Trois autres defauts bloquaient juste derriere, une fois celui-ci leve : - MPLBACKEND etait fixe a 'module://backend_interagg', le backend interne de PyCharm, indisponible hors de cet IDE ; - gui/app.py et monitor/monitor.py utilisaient des imports relatifs remontant au-dela du paquet racine charge par main.py ; - core/ n'avait pas de __init__.py. Corrige aussi get_statistics(), dont le retour anticipe "historique vide" omettait connection_loss_count et uptime_percentage : le KeyError qui en resultait cassait silencieusement tout l'onglet Statistiques a chaque rafraichissement. Les deux chemins renvoient desormais les memes cles. Ajoute le build Windows (StabilityTester.spec + make build-windows), qui produit un .exe autonome depuis Linux via Wine. PySide6 y est epingle a 6.9.3 : a partir de 6.10, Qt6Core.dll depend de l'ICU systeme de Windows que Wine n'implemente pas. La sortie standard est reconfiguree en UTF-8 dans main.py, les emojis des messages faisant echouer cp1252 sous Windows. make test etait casse par la meme confusion de paquet et passe a nouveau. Makefile : libgl1-mesa-glx, retire des depots Debian/Ubuntu recents, remplace par libgl1 et les dependances Qt6 manquantes.
196 lines
7.5 KiB
Makefile
196 lines
7.5 KiB
Makefile
# Makefile for StabilityTester
|
||
# Version: 1.0.1
|
||
# Interface: PySide6 (Qt for Python)
|
||
|
||
.PHONY: help install run test clean all check-python venv prerequis clean-venv info build-windows
|
||
|
||
# Variables
|
||
VENV_DIR := .venv
|
||
PYTHON := python3
|
||
PIP := pip
|
||
REQUIREMENTS := requirements.txt
|
||
|
||
# Build Windows (croise, via Wine)
|
||
WINE_PREFIX := $(HOME)/.wine-stabilitytester
|
||
WIN_PYTHON_VERSION := 3.13.15
|
||
WIN_PYTHON := C:\\Python313\\python.exe
|
||
# PySide6 est epingle pour le build Windows : a partir de 6.10, Qt6Core.dll
|
||
# depend de icuuc.dll (ICU systeme de Windows 10+) que Wine n'implemente pas,
|
||
# ce qui rend l'analyse PyInstaller impossible. 6.9.3 s'en passe.
|
||
WIN_PYSIDE6 := PySide6==6.9.3
|
||
|
||
# Detect OS
|
||
UNAME := $(shell uname -s)
|
||
|
||
# Default target
|
||
help:
|
||
@echo "🌐 StabilityTester - Makefile"
|
||
@echo "============================"
|
||
@echo ""
|
||
@echo "Targets:"
|
||
@echo " prerequis - 📋 Install system prerequisites"
|
||
@echo " venv - 🐍 Create Python virtual environment"
|
||
@echo " install - 📦 Install Python dependencies"
|
||
@echo " run - 🚀 Run the application"
|
||
@echo " test - 🧪 Run basic tests"
|
||
@echo " build-windows - 🪟 Build the Windows .exe (via Wine)"
|
||
@echo " clean - 🧹 Clean build artifacts"
|
||
@echo " clean-venv - 🧹 Remove virtual environment"
|
||
@echo " all - 🔄 Install prerequisites, venv, dependencies and run"
|
||
@echo " info - 📊 Show environment info"
|
||
@echo " check-py - 🐍 Check Python version"
|
||
@echo ""
|
||
|
||
# Check Python version
|
||
check-python:
|
||
@$(PYTHON) --version
|
||
|
||
# Install system prerequisites
|
||
prerequis:
|
||
@echo "📋 Installing system prerequisites..."
|
||
@echo "Detected OS: $(UNAME)"
|
||
ifeq ($(UNAME),Linux)
|
||
@echo "🐧 Linux detected - Installing required packages..."
|
||
@if [ -f /etc/os-release ]; then \
|
||
. /etc/os-release && \
|
||
if [ "$$ID" = "ubuntu" ] || [ "$$ID" = "debian" ] || [ "$$ID_LIKE" = "debian" ]; then \
|
||
sudo apt-get update -qq && \
|
||
sudo apt-get install -y -qq python3 python3-pip python3-venv libgl1 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor0 || echo "⚠️ Some packages may have failed to install"; \
|
||
fi; \
|
||
fi
|
||
@echo "✅ System prerequisites installed!"
|
||
else ifeq ($(UNAME),Darwin)
|
||
@echo "🍎 macOS detected"
|
||
@echo "✅ macOS prerequisites are typically pre-installed!"
|
||
@echo "If you have issues, install: brew install pythonqt"
|
||
else
|
||
@echo "🪟 Windows detected"
|
||
@echo "✅ Windows prerequisites are typically pre-installed!"
|
||
@echo "Make sure Python is in your PATH"
|
||
endif
|
||
|
||
# Create virtual environment
|
||
venv:
|
||
@echo "🐍 Creating Python virtual environment..."
|
||
@if [ ! -d "$(VENV_DIR)" ]; then \
|
||
$(PYTHON) -m venv $(VENV_DIR) && \
|
||
echo "✅ Virtual environment created at $(VENV_DIR)"; \
|
||
else \
|
||
echo "ℹ️ Virtual environment already exists at $(VENV_DIR)"; \
|
||
fi
|
||
@echo ""
|
||
@echo "To activate the virtual environment, run:"
|
||
@echo " source $(VENV_DIR)/bin/activate"
|
||
|
||
# Install dependencies
|
||
install:
|
||
@echo "📦 Installing Python dependencies..."
|
||
@if [ -d "$(VENV_DIR)" ]; then \
|
||
echo "Using virtual environment at $(VENV_DIR)"; \
|
||
$(VENV_DIR)/bin/pip install -r $(REQUIREMENTS) && \
|
||
echo "✅ Dependencies installed in virtual environment!"; \
|
||
else \
|
||
$(PIP) install -r $(REQUIREMENTS) && \
|
||
echo "✅ Dependencies installed globally!"; \
|
||
fi
|
||
|
||
# Run the application
|
||
run:
|
||
@echo "🚀 Starting StabilityTester with PySide6..."
|
||
@if [ -d "$(VENV_DIR)" ]; then \
|
||
$(VENV_DIR)/bin/python main.py; \
|
||
else \
|
||
$(PYTHON) main.py; \
|
||
fi
|
||
|
||
# Run basic tests
|
||
test:
|
||
@echo "🧪 Running basic tests..."
|
||
@if [ -d "$(VENV_DIR)" ]; then \
|
||
$(VENV_DIR)/bin/python -c "from core.network_tester import NetworkTester; t = NetworkTester(); r = t.connection_test(); print(f'✅ Connection test: {r.success}')" && \
|
||
$(VENV_DIR)/bin/python -c "from monitor.monitor import StabilityMonitor; m = StabilityMonitor(); print(f'✅ StabilityMonitor created successfully')" && \
|
||
$(VENV_DIR)/bin/python -c "from gui.app import StabilityTesterWindow; print(f'✅ PySide6 GUI loaded successfully')"; \
|
||
else \
|
||
$(PYTHON) -c "from core.network_tester import NetworkTester; t = NetworkTester(); r = t.connection_test(); print(f'✅ Connection test: {r.success}')" && \
|
||
$(PYTHON) -c "from monitor.monitor import StabilityMonitor; m = StabilityMonitor(); print(f'✅ StabilityMonitor created successfully')" && \
|
||
$(PYTHON) -c "from gui.app import StabilityTesterWindow; print(f'✅ PySide6 GUI loaded successfully')"; \
|
||
fi
|
||
@echo "🎉 All basic tests passed!"
|
||
|
||
# Build de l'executable Windows depuis Linux.
|
||
# PyInstaller ne sait pas cross-compiler : on execute un Python Windows sous
|
||
# Wine. Le prefixe est provisionne une seule fois puis reutilise.
|
||
build-windows:
|
||
@echo "🪟 Building Windows executable via Wine..."
|
||
@command -v wine >/dev/null 2>&1 || { echo "❌ wine is required (apt install wine winetricks)"; exit 1; }
|
||
@if [ ! -f "$(WINE_PREFIX)/drive_c/Python313/python.exe" ]; then \
|
||
echo "📥 Provisioning Wine prefix (one-time, downloads ~1 GB)..."; \
|
||
WINEPREFIX=$(WINE_PREFIX) WINEARCH=win64 wineboot --init >/dev/null 2>&1; \
|
||
echo "📥 Installing native UCRT (Wine's builtin lacks the C99 complex math NumPy needs)..."; \
|
||
WINEPREFIX=$(WINE_PREFIX) winetricks -q -f vcrun2022 ucrtbase2019 >/dev/null 2>&1; \
|
||
curl -sL -o /tmp/python-win.exe \
|
||
https://www.python.org/ftp/python/$(WIN_PYTHON_VERSION)/python-$(WIN_PYTHON_VERSION)-amd64.exe && \
|
||
WINEPREFIX=$(WINE_PREFIX) wine /tmp/python-win.exe /quiet InstallAllUsers=1 \
|
||
PrependPath=1 Include_test=0 TargetDir='C:\\Python313' && \
|
||
rm -f /tmp/python-win.exe; \
|
||
else \
|
||
echo "ℹ️ Wine prefix already provisioned at $(WINE_PREFIX)"; \
|
||
fi
|
||
@echo "📦 Installing Windows dependencies..."
|
||
@WINEPREFIX=$(WINE_PREFIX) WINEDEBUG=-all wine $(WIN_PYTHON) -m pip install --no-input \
|
||
--disable-pip-version-check -q -r $(REQUIREMENTS) "$(WIN_PYSIDE6)" pyinstaller
|
||
@echo "🔨 Running PyInstaller..."
|
||
@WINEPREFIX=$(WINE_PREFIX) wineserver -k 2>/dev/null || true
|
||
@rm -f dist/StabilityTester.exe
|
||
@WINEPREFIX=$(WINE_PREFIX) WINEDEBUG=-all wine $(WIN_PYTHON) -m PyInstaller \
|
||
--noconfirm --clean --distpath dist --workpath build StabilityTester.spec
|
||
@WINEPREFIX=$(WINE_PREFIX) wineserver -k 2>/dev/null || true
|
||
@echo "✅ Windows executable: dist/StabilityTester.exe"
|
||
@ls -lh dist/StabilityTester.exe
|
||
|
||
# Clean build artifacts
|
||
clean:
|
||
@echo "🧹 Cleaning build artifacts..."
|
||
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||
find . -name "*.pyc" -delete 2>/dev/null || true
|
||
find . -name "*.pyo" -delete 2>/dev/null || true
|
||
@echo "✅ Cleanup complete!"
|
||
|
||
# Remove virtual environment
|
||
clean-venv:
|
||
@echo "🧹 Removing virtual environment..."
|
||
@if [ -d "$(VENV_DIR)" ]; then \
|
||
rm -rf $(VENV_DIR) && \
|
||
echo "✅ Virtual environment removed!"; \
|
||
else \
|
||
echo "ℹ️ No virtual environment found"; \
|
||
fi
|
||
|
||
# Install everything and run
|
||
all: prerequis venv install run
|
||
|
||
# Show environment info
|
||
info:
|
||
@echo "📊 StabilityTester - Environment Info"
|
||
@echo "================================="
|
||
@echo ""
|
||
@echo "Python version:"
|
||
@$(PYTHON) --version
|
||
@echo ""
|
||
@echo "Pip version:"
|
||
@$(PIP) --version 2>/dev/null || echo "pip not found"
|
||
@echo ""
|
||
@echo "Virtual environment:"
|
||
@if [ -d "$(VENV_DIR)" ]; then \
|
||
ls -la $(VENV_DIR)/bin/python* 2>/dev/null | head -1 || echo "$(VENV_DIR) exists"; \
|
||
else \
|
||
echo "No virtual environment"; \
|
||
fi
|
||
@echo ""
|
||
@echo "Installed packages:"
|
||
@if [ -d "$(VENV_DIR)" ]; then \
|
||
$(VENV_DIR)/bin/pip list 2>/dev/null | grep -E "(PySide6|requests|matplotlib|speedtest|ping3)" || echo "No packages in venv"; \
|
||
else \
|
||
$(PIP) list 2>/dev/null | grep -E "(PySide6|requests|matplotlib|speedtest|ping3)" || echo "No packages found"; \
|
||
fi
|