Building Executables
This guide explains how to build standalone executables for Windows and macOS.
CI/CD Build Process (Automated)
The build process is automated via GitHub Actions:
Triggers: Builds run automatically on:
Pull requests changing source code, specs, or dependencies
New release publications
Manual workflow dispatch
Dependency Download: tttool v1.8.1 and ffmpeg are downloaded during build
Parallel builds: Windows and macOS builds run simultaneously
Artifacts: Built executables uploaded as workflow artifacts (30-day retention) or release assets
To trigger a manual build:
git tag v2.0.0
git push origin v2.0.0
gh release create v2.0.0 --title "Release v2.0.0" --notes "Release notes"
Prerequisites
Python 3.11 or later
PyInstaller 6.0 or later
Git
Internet connection (to download tttool and ffmpeg)
Setup
git clone https://github.com/thawn/ttmp32gme.git && cd ttmp32gme
uv pip install -e ".[build]" # or: pip install -e ".[build]"
Building for Windows
On Windows:
# Download tttool
$TTTOOL_VERSION = "1.8.1"
New-Item -ItemType Directory -Force -Path lib/win
Invoke-WebRequest -Uri "https://github.com/entropia/tip-toi-reveng/releases/download/${TTTOOL_VERSION}/tttool-${TTTOOL_VERSION}.zip" -OutFile tttool.zip
Expand-Archive -Path tttool.zip -DestinationPath .
Move-Item -Path tttool.exe -Destination lib/win/tttool.exe -Force
Remove-Item tttool.zip
# Download ffmpeg
Invoke-WebRequest -Uri "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip" -OutFile ffmpeg.zip
Expand-Archive -Path ffmpeg.zip -DestinationPath .
$ffmpegDir = Get-ChildItem -Directory -Filter "ffmpeg-*" | Select-Object -First 1
Move-Item -Path "$($ffmpegDir.FullName)/bin/ffmpeg.exe" -Destination lib/win/ffmpeg.exe -Force
Remove-Item -Recurse -Force $ffmpegDir
Remove-Item ffmpeg.zip
# Build
pyinstaller ttmp32gme-windows.spec --clean
cd dist
Compress-Archive -Path ttmp32gme -DestinationPath ttmp32gme-windows.zip
Output: ttmp32gme-windows.zip contains ttmp32gme.exe with bundled tttool, ffmpeg, and dependencies.
Building for macOS
On macOS:
# Download tttool
TTTOOL_VERSION="1.8.1"
mkdir -p lib/mac
wget "https://github.com/entropia/tip-toi-reveng/releases/download/${TTTOOL_VERSION}/tttool-${TTTOOL_VERSION}.zip"
unzip "tttool-${TTTOOL_VERSION}.zip"
chmod +x tttool && mv tttool lib/mac/tttool
rm "tttool-${TTTOOL_VERSION}.zip"
# Download ffmpeg
wget "https://evermeet.cx/ffmpeg/getrelease/ffmpeg/zip" -O ffmpeg.zip
unzip ffmpeg.zip
chmod +x ffmpeg && mv ffmpeg lib/mac/ffmpeg
rm ffmpeg.zip
# Build
pyinstaller ttmp32gme-macos.spec --clean
cd dist
zip -r ttmp32gme-macos.zip ttmp32gme.app
Output: ttmp32gme-macos.zip contains ttmp32gme.app bundle with tttool, ffmpeg, and dependencies.
Testing Built Executables
Windows:
ttmp32gme.exe --help
ttmp32gme.exe --port 10020
macOS:
./ttmp32gme.app/Contents/MacOS/ttmp32gme --help
./ttmp32gme.app/Contents/MacOS/ttmp32gme --port 10020
Or double-click the app bundle in Finder.
Troubleshooting
“Module not found” errors: Add dependencies to hiddenimports list in spec files
Missing data files: Add files to datas list in spec files
Bundled binaries not found: Verify lib/ directory structure in spec files
macOS Gatekeeper issues: Users must right-click → Open first time (bypass instructions)
Windows SmartScreen issues: Users must click “More info” → “Run anyway” (bypass instructions)
Code Signing
The distributed executables are not code-signed as code signing certificates are not available. This causes security warnings on macOS and Windows:
macOS: Gatekeeper warning - users must right-click → Open
Windows: SmartScreen warning - users must click “More info” → “Run anyway”
To sign executables for distribution, you would need:
macOS: Apple Developer account and notarization ($99/year)
Windows: Code signing certificate from trusted CA ($100-400/year)
Notes
Chrome/Chromium: Not bundled - users install separately for PDF generation
Size: Windows ~50-80 MB, macOS ~60-90 MB (compressed)
Python runtime: Fully embedded, no Python installation required