Building Standalone Executables¶
This guide explains how to build standalone executables for the SCPI Instrument Control GUI application that can run without Python installed.
Overview¶
The project uses PyInstaller to create standalone executables for:
- Windows:
.exeexecutable - macOS:
.appapplication bundle - Linux: Binary executable
These executables bundle Python and all dependencies, allowing users to run the GUI without installing Python.
Quick Start¶
Local Build (Current Platform)¶
Build an executable for your current operating system:
# Using Make (recommended)
make build-exe
# Or using Python script directly
python scripts/build_executable.py
The executable will be created in the dist/ directory.
Automated Builds (All Platforms)¶
The project includes a GitHub Actions workflow that automatically builds executables for all platforms when you push a version tag:
This will:
- Build executables for Windows, macOS, and Linux
- Create release archives (.zip for Windows/macOS, .tar.gz for Linux)
- Upload to GitHub Releases automatically
Prerequisites¶
For Local Builds¶
- Install the package with all dependencies:
- Install PyInstaller:
- Create application icons (optional but recommended):
- Windows:
resources/siglent-icon.ico - macOS:
resources/siglent-icon.icns - Linux: Icons not embedded in binary
See Creating Application Icons below.
Building Methods¶
Method 1: Using Make (Recommended)¶
# Build for current platform
make build-exe
# Clean build artifacts first
make build-exe-clean
make build-exe
# Build and test the executable
make build-exe-test
Method 2: Using Build Script¶
# Basic build
python scripts/build_executable.py
# Clean and build
python scripts/build_executable.py --clean
# Build and test
python scripts/build_executable.py --test
# Build and create distribution archive
python scripts/build_executable.py --archive
Method 3: Using PyInstaller Directly¶
Build Artifacts¶
After building, you'll find:
Windows¶
macOS¶
dist/
└── SiglentGUI.app/ # Application bundle
└── Contents/
├── MacOS/
│ └── SiglentGUI # Actual executable
├── Resources/
└── Info.plist
Linux¶
Distribution¶
Creating Release Archives¶
The build script can create distributable archives:
This creates:
- Windows:
SiglentGUI-v0.3.1-Windows-x64.zip - macOS:
SiglentGUI-v0.3.1-macOS-arm64.zip - Linux:
SiglentGUI-v0.3.1-Linux-x86_64.tar.gz
Each archive includes:
- The executable/app
- README.md
- LICENSE
Automated Release Process¶
When you push a version tag (e.g., v0.3.2), GitHub Actions will:
- Build executables on Windows, macOS, and Linux runners
- Create platform-specific archives
- Upload to GitHub Releases
- Add installation instructions to the release notes
To trigger a release:
# Ensure your code is committed
git add .
git commit -m "Release v0.3.2"
# Create and push tag
git tag v0.3.2
git push origin main
git push origin v0.3.2
Then check the "Actions" tab on GitHub to monitor the build progress.
Creating Application Icons¶
Application icons make your executable look professional and identifiable.
Icon Requirements¶
- Windows (.ico): Multi-resolution, recommended sizes: 16x16, 32x32, 48x48, 256x256
- macOS (.icns): Multi-resolution, recommended sizes: 16x16 to 1024x1024
- Linux: Icons are typically not embedded; use desktop file instead
Creating Icons from PNG¶
-
Create a high-resolution PNG (1024x1024 or larger) with your logo/icon
-
Convert to .ico (Windows):
Using online tools: - https://convertio.co/png-ico/ - https://www.icoconverter.com/
Or using ImageMagick:
- Convert to .icns (macOS):
Using iconutil (macOS only):
# Create iconset directory
mkdir siglent-icon.iconset
# Create different sizes
sips -z 16 16 icon.png --out siglent-icon.iconset/icon_16x16.png
sips -z 32 32 icon.png --out siglent-icon.iconset/icon_16x16@2x.png
sips -z 32 32 icon.png --out siglent-icon.iconset/icon_32x32.png
sips -z 64 64 icon.png --out siglent-icon.iconset/icon_32x32@2x.png
sips -z 128 128 icon.png --out siglent-icon.iconset/icon_128x128.png
sips -z 256 256 icon.png --out siglent-icon.iconset/icon_128x128@2x.png
sips -z 256 256 icon.png --out siglent-icon.iconset/icon_256x256.png
sips -z 512 512 icon.png --out siglent-icon.iconset/icon_256x256@2x.png
sips -z 512 512 icon.png --out siglent-icon.iconset/icon_512x512.png
sips -z 1024 1024 icon.png --out siglent-icon.iconset/icon_512x512@2x.png
# Convert to icns
iconutil -c icns siglent-icon.iconset
Or use online tools: - https://cloudconvert.com/png-to-icns - https://iconverticons.com/online/
- Place icons in resources directory:
Icon Design Tips¶
- Use simple, recognizable designs (works well at small sizes)
- Include the Siglent logo or oscilloscope imagery
- Use high contrast colors
- Test at multiple sizes (16x16 to 512x512)
- Save with transparent background (PNG/ICNS)
Configuration¶
PyInstaller Spec File¶
The build configuration is in siglent-gui.spec. Key settings:
# Executable name
exe = EXE(
...
name='SiglentGUI', # Output name
console=False, # No console window (GUI app)
icon='resources/siglent-icon.ico' # Application icon
)
# Hidden imports (add modules that PyInstaller misses)
hiddenimports=[
'PyQt6',
'pyqtgraph',
'numpy',
# ... more
]
# Excluded modules (reduce size)
excludes=[
'tkinter', # Don't need Tkinter
'pytest', # Don't need test framework
]
Customizing the Build¶
To modify the build:
- Edit
siglent-gui.spec - Add/remove hidden imports
- Include additional data files
- Change executable name or icon
Then rebuild:
Troubleshooting¶
Build Fails with Missing Modules¶
Problem: PyInstaller can't find a module
Solution: Add to hiddenimports in siglent-gui.spec:
Executable is Too Large¶
Problem: Executable is 400+ MB
Solutions:
- Add unused modules to
excludeslist - Enable UPX compression (already enabled)
- Use folder distribution instead of single file
Executable Won't Start¶
Problem: Executable crashes on startup
Solutions:
- Check console output (run from terminal)
- Test on clean machine without Python installed
- Verify all dependencies are included
Windows: Run from Command Prompt to see errors:
macOS: Check Console app for crash logs
Linux: Run from terminal:
Icon Not Showing¶
Problem: Executable doesn't show custom icon
Solutions:
- Verify icon files exist in
resources/directory - Check icon file format (.ico for Windows, .icns for macOS)
- Rebuild after adding icons
- On Windows, icon cache may need refresh (restart Explorer)
macOS "App is Damaged" Error¶
Problem: macOS Gatekeeper blocks unsigned app
Solution: Users need to right-click → Open the first time
For developers: Code sign the app (requires Apple Developer account):
codesign --deep --force --verify --verbose --sign "Developer ID Application: Your Name" dist/SiglentGUI.app
Antivirus False Positives¶
Problem: Windows Defender flags executable as malware
Solutions:
- This is common with PyInstaller executables
- Code sign the executable (requires certificate)
- Submit to Microsoft for analysis
- Users can add exception in their antivirus
Testing Executables¶
Local Testing¶
- Build the executable:
- Test on your development machine:
- Test on clean VM/machine without Python:
- Use VirtualBox, VMware, or physical machine
- Verify no Python installation needed
- Test all GUI features
Automated Testing¶
The GitHub Actions workflow includes basic checks:
- Verifies executable was created
- Checks file size (should be 100-300 MB)
- Validates archive creation
File Size Optimization¶
Typical executable sizes:
- Minimal: ~100 MB (core GUI only)
- Standard: ~150-200 MB (all features)
- Maximum: ~250-300 MB (all optional features)
To reduce size:
- Exclude unused modules in spec file:
- Remove optional dependencies:
-
Comment out unused items in
hiddenimports -
Use UPX compression (already enabled):
- Use folder distribution instead of single file (faster startup):
- Edit spec file: change
exe = EXE(...)parameters - Remove single-file mode
Release Checklist¶
Before creating a release with executables:
- Update version in
pyproject.toml - Update
CHANGELOG.md - Test locally on current platform
- Create application icons (if not done)
- Commit all changes
- Create and push version tag
- Monitor GitHub Actions build
- Test downloaded executables from release
- Update release notes if needed
Advanced Topics¶
Code Signing¶
For production releases, code signing prevents security warnings:
Windows:
- Requires code signing certificate (from DigiCert, Sectigo, etc.)
- Use SignTool.exe
- Cost: $100-400/year
macOS:
- Requires Apple Developer account ($99/year)
- Use
codesignandnotarytool - Necessary for Gatekeeper approval
Linux:
- Generally not required
- Can use GPG signatures for packages
Creating Installers¶
For professional distribution:
Windows:
- Inno Setup (free)
- NSIS (free)
- WiX Toolset (free)
macOS:
- DMG canvas (paid)
hdiutil(built-in, free).pkginstaller
Linux:
- AppImage
- Flatpak
- Snap package
- .deb / .rpm packages
Additional Resources¶
Getting Help¶
If you encounter issues building executables:
- Check this documentation
- Review PyInstaller troubleshooting
- Search existing GitHub Issues
- Create a new issue with:
- Your OS and Python version
- Full error message
- Build command used
- PyInstaller version