# Compila jail-launcher con Nuitka y empaqueta un release para Windows. # - jail-launcher.exe (onefile, GUI sin consola, con icono) + games.toml + .zip. # Equivalente nativo de build.sh (que cubre Linux/macOS). # Requisitos del sistema (no los instala el script): # - Python 3.10+ (con el launcher «py» o «python» en el PATH). # - Un compilador C: Nuitka usa MSVC (Build Tools de Visual Studio) si existe; # si no, ofrece descargar MinGW automáticamente (-AssumeYesForDownloads). # - git en el PATH (lo usa la app en tiempo de ejecución, no el build). # # Uso: pwsh -File build.ps1 (o: .\build.ps1 desde PowerShell) $ErrorActionPreference = 'Stop' Set-StrictMode -Version Latest # Situarnos en la carpeta del script. $Here = Split-Path -Parent $MyInvocation.MyCommand.Path Set-Location $Here # --- Versión (leída de jail_launcher/__init__.py) --------------------------------- $initPath = Join-Path $Here 'jail_launcher\__init__.py' $verMatch = Select-String -Path $initPath -Pattern '^__version__\s*=\s*"([^"]*)"' | Select-Object -First 1 if (-not $verMatch) { Write-Error '[build] no se pudo leer __version__ de jail_launcher/__init__.py' } $Version = $verMatch.Matches[0].Groups[1].Value # Arquitectura al estilo uname -m (x86_64 / arm64). $Arch = switch ($env:PROCESSOR_ARCHITECTURE) { 'AMD64' { 'x86_64' } 'ARM64' { 'arm64' } default { $env:PROCESSOR_ARCHITECTURE.ToLower() } } # --- Intérprete de Python ----------------------------------------------------- # Preferimos el launcher «py -3»; si no, «python». function Resolve-Python { if (Get-Command py -ErrorAction SilentlyContinue) { return @('py', '-3') } if (Get-Command python -ErrorAction SilentlyContinue) { return @('python') } Write-Error '[build] no se encontró Python (ni «py» ni «python» en el PATH).' } $Py = Resolve-Python # Comprueba si un módulo se puede importar en el venv, SIN abortar el script: # bajo $ErrorActionPreference='Stop', un código de salida ≠ 0 (módulo ausente) # se trataría como error terminante. Aquí relajamos eso solo para la sonda. function Test-PyModule([string]$Module) { $prev = $ErrorActionPreference $ErrorActionPreference = 'Continue' try { & $VenvPython -c "import $Module" 2>&1 | Out-Null return ($LASTEXITCODE -eq 0) } finally { $ErrorActionPreference = $prev } } # --- venv (en Windows los ejecutables viven en .venv\Scripts) ----------------- $VenvPython = Join-Path $Here '.venv\Scripts\python.exe' if (-not (Test-Path $VenvPython)) { Write-Host '[build] creando venv…' & $Py[0] $Py[1..($Py.Count - 1)] -m venv .venv & $VenvPython -m pip install --quiet --upgrade pip } Write-Host '[build] sincronizando dependencias…' & $VenvPython -m pip install --quiet -r requirements.txt # Nuitka + zstandard (compresión del onefile → binario más pequeño). if (-not (Test-PyModule 'nuitka')) { Write-Host '[build] instalando nuitka en el venv…' & $VenvPython -m pip install --quiet 'nuitka[onefile]' } if (-not (Test-PyModule 'zstandard')) { Write-Host '[build] instalando zstandard (compresión onefile)…' & $VenvPython -m pip install --quiet zstandard } Write-Host "[build] versión: v$Version" Write-Host '[build] limpiando artefactos previos…' foreach ($d in 'dist', 'build', 'app.build', 'app.dist', 'app.onefile-build') { if (Test-Path $d) { Remove-Item -Recurse -Force $d } } $IconIco = 'icon\icon.ico' $IconPng = 'icon\icon.png' if (-not (Test-Path $IconIco)) { Write-Error "[build] falta $IconIco" } # --- Compilación onefile ------------------------------------------------------ Write-Host '[build] compilando jail-launcher.exe (PySide6 onefile; puede tardar varios minutos)…' & $VenvPython -m nuitka ` --onefile ` --assume-yes-for-downloads ` --enable-plugin=pyside6 ` --include-package=jail_launcher ` --windows-icon-from-ico=$IconIco ` --windows-console-mode=disable ` --company-name=jailgames ` --product-name=jail-launcher ` --product-version=$Version ` --file-version=$Version ` --output-dir=dist ` --output-filename=jail-launcher ` --remove-output ` app.py if ($LASTEXITCODE -ne 0) { Write-Error '[build] Nuitka falló.' } $Exe = 'dist\jail-launcher.exe' if (-not (Test-Path $Exe)) { Write-Error '[build] Nuitka no produjo dist\jail-launcher.exe' } # games.toml junto al .exe (la app lo lee desde ahí: base_dir junto al binario). Write-Host '[build] copiando games.toml junto al ejecutable…' Copy-Item games.toml dist\games.toml -Force # icon.png para el diálogo «Quant a» (paths.app_icon_path → base_dir()\icon\icon.png). Write-Host '[build] sembrando icon\icon.png para el diálogo «Quant a»…' New-Item -ItemType Directory -Force -Path dist\icon | Out-Null Copy-Item $IconPng dist\icon\icon.png -Force # --- Empaquetado .zip --------------------------------------------------------- $ReleaseName = "jail-launcher-v$Version-windows-$Arch" $Zip = "dist\$ReleaseName.zip" Write-Host "[build] empaquetando release $ReleaseName.zip…" Compress-Archive -Path dist\jail-launcher.exe, dist\games.toml, dist\icon ` -DestinationPath $Zip -Force Write-Host '[build] hecho:' Get-Item dist\jail-launcher.exe, dist\games.toml, $Zip | Format-Table -AutoSize Name, @{Name = 'Size'; Expression = { '{0:N0} B' -f $_.Length } } Write-Host '[build] el binario crea jail_launcher_data\ y settings.json junto a sí mismo.' Write-Host '[build] distribuir: descomprimir el .zip (jail-launcher.exe + games.toml + icon\ juntos).'