Skip to content

Latest commit

 

History

History
128 lines (100 loc) · 3.9 KB

File metadata and controls

128 lines (100 loc) · 3.9 KB

Cross-Compilation Issue Explained

What Happened

Expected

  • Build Windows .exe from macOS system
  • Create portable Windows executable for AMD64 architecture

Reality

  • PyInstaller created ARM64 Mach-O executable (macOS format)
  • File named as .exe but actually macOS binary
  • Cross-compilation from macOS to Windows failed

Root Cause Analysis

PyInstaller Limitation

PyInstaller builds executables for the HOST platform, not TARGET platform

Technical Details:

  1. Host Platform: macOS ARM64 (where build runs)
  2. Target Platform: Windows AMD64 (what we wanted)
  3. PyInstaller Behavior: Always creates host platform binaries
  4. Result: ARM64 Mach-O instead of Windows PE32+

Configuration Issues

Original build_windows.py configuration:

'--onefile',     # Single executable 
'--windowed',    # No console (caused .app creation on macOS)
'--console',     # Changed to console (but still creates macOS binary)

The --windowed flag:

  • On macOS: Creates .app bundle (even for "Windows" build)
  • On Windows: Creates GUI executable without console
  • Not a cross-platform target specifier

Why Cross-Compilation Doesn't Work

PyInstaller Architecture

  1. Bootloader: Platform-specific (compiled C code)
  2. Python Runtime: Platform-specific libraries
  3. Dependencies: Platform-specific (.so vs .dll vs .dylib)
  4. Executable Format: Platform-specific (Mach-O vs PE32+ vs ELF)

Platform Dependencies

macOS ARM64:    Mach-O 64-bit executable arm64
Windows AMD64:  PE32+ executable (console) x86-64  
Linux AMD64:    ELF 64-bit LSB executable, x86-64

What PyInstaller Actually Did

file dist/windows/FFmpeg_GUI_Windows_AMD64
# Output: Mach-O 64-bit executable arm64

Not:

# What we wanted:
# PE32+ executable (console) x86-64, for MS Windows

Technical Solutions

1. Native Platform Build (Implemented)

  • Files Created: FFmpeg_GUI_Windows.spec, BUILD_WINDOWS_NATIVE.md
  • Approach: Build on actual Windows system
  • Result: True Windows PE32+ executable

2. Cross-Platform CI/CD

  • GitHub Actions: runs-on: windows-latest
  • Automated: Build on Windows runners
  • Distribution: Artifacts from Windows build

3. Docker Windows Containers

FROM mcr.microsoft.com/windows/servercore:ltsc2022
RUN pip install pyinstaller
COPY . .
RUN pyinstaller FFmpeg_GUI_Windows.spec

4. Wine (Development Only)

# Install Windows Python under Wine
wine python.exe -m pip install pyinstaller
wine python.exe -m PyInstaller FFmpeg_GUI_Windows.spec

Lessons Learned

PyInstaller Facts

  1. No cross-compilation support for different architectures
  2. Host platform determines output format always
  3. --windowed flag creates .app on macOS regardless of intent
  4. Executable format cannot be overridden

Proper Cross-Platform Strategy

  1. Build on target platform or use CI/CD
  2. Separate build scripts per platform
  3. Platform-specific configuration files
  4. Testing on target platform mandatory

File Naming Confusion

  • Naming file .exe doesn't make it Windows executable
  • File extension != executable format
  • Always verify with file command

Current Status

Working Solutions

  • macOS ARM64: Native build complete (FFmpeg_GUI_macOS_ARM64.dmg)
  • Windows AMD64: Spec files ready for native build
  • Documentation: Complete build instructions provided

Not Working

  • Cross-compilation: PyInstaller limitation (not configuration error)
  • Wine approach: Complex, unreliable for distribution
  • Docker Windows: Resource intensive, complex setup

Conclusion

The issue was not a configuration error but a fundamental PyInstaller limitation. Cross-compilation from macOS to Windows is not supported. The proper solution is native builds on each target platform, which is now implemented with the spec files and documentation created.