172 lines
5.3 KiB
Python
Executable File
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())
|