From 9147eb56fb2efa2ecd69d516fab28a2fec2fae6b Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 1 Jun 2026 12:14:45 +0200 Subject: [PATCH] Afig build.ps1 per compilar a Windows amb Nuitka --- build.ps1 | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 build.ps1 diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..f479343 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,138 @@ +# Compila jlauncher con Nuitka y empaqueta un release para Windows. +# - jlauncher.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 jlauncher/__init__.py) --------------------------------- +$initPath = Join-Path $Here 'jlauncher\__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 jlauncher/__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 jlauncher.exe (PySide6 onefile; puede tardar varios minutos)…' +& $VenvPython -m nuitka ` + --onefile ` + --assume-yes-for-downloads ` + --enable-plugin=pyside6 ` + --include-package=jlauncher ` + --windows-icon-from-ico=$IconIco ` + --windows-console-mode=disable ` + --company-name=jailgames ` + --product-name=jlauncher ` + --product-version=$Version ` + --file-version=$Version ` + --output-dir=dist ` + --output-filename=jlauncher ` + --remove-output ` + app.py +if ($LASTEXITCODE -ne 0) { + Write-Error '[build] Nuitka falló.' +} + +$Exe = 'dist\jlauncher.exe' +if (-not (Test-Path $Exe)) { + Write-Error '[build] Nuitka no produjo dist\jlauncher.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 = "jlauncher-v$Version-windows-$Arch" +$Zip = "dist\$ReleaseName.zip" +Write-Host "[build] empaquetando release $ReleaseName.zip…" +Compress-Archive -Path dist\jlauncher.exe, dist\games.toml, dist\icon ` + -DestinationPath $Zip -Force + +Write-Host '[build] hecho:' +Get-Item dist\jlauncher.exe, dist\games.toml, $Zip | + Format-Table -AutoSize Name, @{Name = 'Size'; Expression = { '{0:N0} B' -f $_.Length } } +Write-Host '[build] el binario crea jlauncher_data\ y settings.json junto a sí mismo.' +Write-Host '[build] distribuir: descomprimir el .zip (jlauncher.exe + games.toml + icon\ juntos).'