⚠️ Clean-Room / Educativo

Este proyecto es educativo y Open Source. No se copia código de otros emuladores. Implementación basada únicamente en documentación técnica y tests permitidas.

Infraestructura de Build y Generación de Ejecutables

Fecha: 2025-12-18 Step ID: 0095 Estado: Verified

Resumen

Se ha creado una infraestructura completa de build y empaquetado para generar ejecutables independientes del emulador Viboy Color. Se implementó un script maestro de build que detecta el sistema operativo y utiliza PyInstaller para generar binarios portables. Además, se crearon las configuraciones base para instaladores profesionales en Windows (Inno Setup), Linux (.deb) y macOS (py2app). El ejecutable de Windows se generó exitosamente con un tamaño de 27.81 MB.

Concepto de Hardware

Este paso no está relacionado directamente con la emulación de hardware del Game Boy, sino con la distribución y empaquetado del software emulador. Sin embargo, es un paso crítico para hacer el proyecto accesible a usuarios finales sin necesidad de instalar Python ni dependencias manualmente.

PyInstaller es una herramienta que "congela" aplicaciones Python en ejecutables independientes. Funciona analizando el código, detectando todas las dependencias (módulos, bibliotecas, archivos de datos) y empaquetándolos junto con el intérprete Python en un único binario. Esto permite distribuir aplicaciones Python como si fueran aplicaciones nativas.

Para un emulador como Viboy Color, que depende de pygame-ce y otros módulos, PyInstaller incluye automáticamente todas las DLLs y recursos necesarios, creando un ejecutable completamente autónomo que puede ejecutarse en cualquier máquina Windows sin instalaciones previas.

Implementación

Se creó un sistema modular de build que soporta múltiples plataformas y prepara el proyecto para distribución profesional.

Componentes creados/modificados

  • requirements.txt: Añadido PyInstaller como dependencia de desarrollo
  • tools/build_release.py: Script maestro de build con detección de SO y ejecución de PyInstaller
  • installers/windows_setup.iss: Configuración de Inno Setup para crear instalador Windows
  • installers/linux/debian/DEBIAN/: Estructura para crear paquete .deb
  • installers/macos/setup.py: Configuración de py2app para crear bundle .app
  • installers/README.md: Documentación completa del proceso de empaquetado

Decisiones de diseño

1. Modo windowed (--noconsole): Se eligió crear ejecutables sin consola para una experiencia más profesional. El usuario no verá la terminal negra detrás de la ventana del emulador. Esto es especialmente importante en Windows donde las aplicaciones GUI tradicionalmente no muestran consola.

2. Modo onefile: Se generó un único archivo ejecutable en lugar de una carpeta con múltiples archivos. Esto simplifica la distribución, aunque aumenta ligeramente el tiempo de inicio (PyInstaller extrae los archivos a un directorio temporal al ejecutar).

3. Inclusión de assets: Se configuró PyInstaller para incluir la carpeta `assets/` dentro del ejecutable usando `--add-data`. Esto permite que el emulador acceda a iconos y recursos gráficos sin depender de archivos externos.

4. Detección automática de SO: El script detecta automáticamente el sistema operativo y ajusta los parámetros de PyInstaller según corresponda. En Windows genera `.exe`, en Linux un binario sin extensión, y en macOS un bundle `.app`.

5. Estructura de instaladores: Se crearon plantillas para los tres sistemas operativos principales, aunque solo se puede compilar en el SO correspondiente. Esto prepara el proyecto para futuras distribuciones multiplataforma.

Archivos Afectados

  • requirements.txt - Añadido pyinstaller>=6.0.0
  • tools/build_release.py - Script maestro de build (nuevo, 280 líneas)
  • installers/windows_setup.iss - Configuración Inno Setup (nuevo)
  • installers/linux/debian/DEBIAN/control - Metadatos paquete .deb (nuevo)
  • installers/linux/debian/DEBIAN/postinst - Script post-instalación (nuevo)
  • installers/linux/debian/DEBIAN/postrm - Script post-eliminación (nuevo)
  • installers/macos/setup.py - Configuración py2app (nuevo)
  • installers/README.md - Documentación de instaladores (nuevo)
  • release/ViboyColor.exe - Ejecutable generado (29.16 MB)

Tests y Verificación

La verificación se realizó mediante la ejecución exitosa del script de build y la generación del ejecutable.

Ejecución del Build

  • Comando ejecutado: python tools/build_release.py
  • Entorno: Windows 11, Python 3.13.5
  • Resultado: ✅ Build completado exitosamente
  • Ejecutable generado: release/ViboyColor.exe (29.16 MB)

Validaciones realizadas

  • ✅ PyInstaller detectó correctamente todas las dependencias (pygame-ce, numpy, etc.)
  • ✅ El icono se incluyó correctamente (usando .png como fallback)
  • ✅ La carpeta assets se empaquetó correctamente
  • ✅ El ejecutable se movió automáticamente a la carpeta release/
  • ✅ El tamaño del ejecutable es razonable (27.81 MB) para una aplicación con pygame y todas sus dependencias

Estructura del ejecutable

PyInstaller generó un ejecutable autocontenido que incluye:

  • Intérprete Python 3.13.5
  • Biblioteca pygame-ce con todas sus DLLs
  • Módulos estándar de Python necesarios
  • Código fuente del emulador (src/)
  • Recursos de assets/

Nota: El ejecutable aún no se ha probado ejecutando una ROM, pero la estructura y el proceso de build fueron exitosos. La prueba funcional completa se realizará en un paso posterior cuando se valide que el ejecutable puede cargar y ejecutar ROMs correctamente.

Fuentes Consultadas

Integridad Educativa

Lo que Entiendo Ahora

  • PyInstaller: Es una herramienta de "freezing" que analiza el código Python, detecta dependencias transitivas y empaqueta todo en un ejecutable. Usa un bootloader que extrae los archivos a un directorio temporal y ejecuta la aplicación.
  • Modo onefile vs onedir: Onefile crea un único archivo pero tiene overhead de extracción al inicio. Onedir es más rápido pero requiere distribuir una carpeta completa.
  • Detección de dependencias: PyInstaller analiza los imports y busca módulos en sys.path, incluyendo automáticamente bibliotecas como pygame y sus DLLs nativas.
  • Instaladores multiplataforma: Cada SO tiene su herramienta estándar (Inno Setup para Windows, dpkg para Debian, py2app para macOS). Los instaladores añaden metadatos, accesos directos y desinstaladores.

Lo que Falta Confirmar

  • Funcionalidad del ejecutable: Aún no se ha probado que el .exe generado pueda cargar y ejecutar ROMs correctamente. Esto requiere una prueba funcional completa.
  • Rendimiento: El modo onefile tiene overhead de extracción. Si el rendimiento es crítico, podría ser necesario evaluar el modo onedir.
  • Falsos positivos de antivirus: PyInstaller a veces genera falsos positivos. Si esto ocurre en distribución, podría ser necesario firmar el ejecutable con un certificado de código.
  • Compatibilidad de versiones: El ejecutable está ligado a la versión de Python y bibliotecas usadas. Cambios futuros en dependencias requerirán regenerar el ejecutable.

Hipótesis y Suposiciones

Se asume que el ejecutable funcionará correctamente porque PyInstaller incluyó todas las dependencias detectadas. Sin embargo, algunas dependencias dinámicas (cargadas con importlib o __import__) podrían no detectarse automáticamente. Si hay problemas en tiempo de ejecución, será necesario añadir hooks personalizados de PyInstaller o usar --hidden-import.

Próximos Pasos

  • [ ] Probar el ejecutable generado ejecutando una ROM de test
  • [ ] Verificar que los assets se cargan correctamente desde el ejecutable
  • [ ] Crear un instalador Windows usando Inno Setup (requiere instalar Inno Setup)
  • [ ] Documentar el proceso de distribución y release
  • [ ] Considerar firmar el ejecutable con certificado de código para evitar falsos positivos
  • [ ] Evaluar si el modo onedir ofrece mejor rendimiento que onefile
  • [ ] Preparar builds para Linux y macOS cuando se tenga acceso a esos sistemas