Files
soundshot/flash_tool/build.py
2025-10-13 18:54:50 -05:00

172 lines
5.3 KiB
Python
Executable File

#!/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())