#!/usr/bin/env python3 """ Universal build script for ESP32 Flasher GUI Automatically detects platform and builds the appropriate executable """ import sys import subprocess import platform import os def get_platform(): """Detect the current platform""" system = platform.system() if system == "Darwin": return "macos" elif system == "Windows": return "windows" elif system == "Linux": return "linux" else: return "unknown" def setup_venv(): """Create and setup virtual environment if on macOS""" if platform.system() == "Darwin": if not os.path.exists("venv"): print("Creating virtual environment (required on macOS)...") try: subprocess.run([sys.executable, "-m", "venv", "venv"], check=True) print("✓ Virtual environment created") except subprocess.CalledProcessError as e: print(f"✗ Failed to create virtual environment: {e}") return False # Use venv Python for the rest of the script venv_python = os.path.join("venv", "bin", "python3") if os.path.exists(venv_python): return venv_python return sys.executable def install_dependencies(python_exe=None): """Install required Python packages""" if python_exe is None: python_exe = sys.executable print("Installing dependencies...") packages = ["pyinstaller", "esptool", "pyserial"] try: subprocess.run([python_exe, "-m", "pip", "install"] + packages, check=True) print("✓ Dependencies installed successfully") return True except subprocess.CalledProcessError as e: print(f"✗ Failed to install dependencies: {e}") return False def build_macos(): """Build macOS application bundle""" print("\n=== Building for macOS ===") spec_file = "ESP32_Flasher_macOS.spec" if not os.path.exists(spec_file): print(f"✗ Error: {spec_file} not found") return False try: subprocess.run(["pyinstaller", spec_file], check=True) if os.path.exists("dist/ESP32_Flasher.app"): print("\n✓ Build complete!") print(f"\nApplication created at: dist/ESP32_Flasher.app") print("\nTo run the application:") print(" open dist/ESP32_Flasher.app") return True else: print("\n✗ Build failed - application not found in dist folder") return False except subprocess.CalledProcessError as e: print(f"\n✗ Build failed: {e}") return False def build_windows(): """Build Windows executable""" print("\n=== Building for Windows ===") spec_file = "ESP32_Flasher_Windows.spec" if not os.path.exists(spec_file): print(f"✗ Error: {spec_file} not found") return False try: subprocess.run(["pyinstaller", spec_file], check=True) if os.path.exists("dist/ESP32_Flasher.exe"): print("\n✓ Build complete!") print(f"\nExecutable created at: dist\\ESP32_Flasher.exe") print("\nYou can now distribute ESP32_Flasher.exe to users.") return True else: print("\n✗ Build failed - executable not found in dist folder") return False except subprocess.CalledProcessError as e: print(f"\n✗ Build failed: {e}") return False def build_linux(): """Build Linux executable""" print("\n=== Building for Linux ===") print("Note: Linux users typically prefer to run Python scripts directly.") print("Creating standalone executable anyway...") # Use macOS spec as template for Linux (both use ELF format) spec_file = "ESP32_Flasher_macOS.spec" if not os.path.exists(spec_file): print(f"✗ Error: {spec_file} not found") return False try: subprocess.run(["pyinstaller", spec_file], check=True) if os.path.exists("dist/ESP32_Flasher"): print("\n✓ Build complete!") print(f"\nExecutable created at: dist/ESP32_Flasher") print("\nTo run:") print(" ./dist/ESP32_Flasher") return True else: print("\n✗ Build failed - executable not found in dist folder") return False except subprocess.CalledProcessError as e: print(f"\n✗ Build failed: {e}") return False def main(): """Main build function""" print("=== ESP32 Flasher - Universal Build Script ===\n") # Detect platform current_platform = get_platform() print(f"Detected platform: {current_platform}") if current_platform == "unknown": print("✗ Unsupported platform") return 1 # Setup virtual environment if needed (macOS) python_exe = setup_venv() # Install dependencies if not install_dependencies(python_exe): return 1 # Build for detected platform success = False if current_platform == "macos": success = build_macos() elif current_platform == "windows": success = build_windows() elif current_platform == "linux": success = build_linux() return 0 if success else 1 if __name__ == "__main__": sys.exit(main())