This document describes how to build and distribute standalone executables of mbari-pbp.
Note: Standalone distributions for Linux, macOS, and Windows are automatically built and published via GitHub Actions when a version tag is pushed. See the CI/CD Integration section for details.
The standalone build creates a single executable that includes:
- Python runtime
- All Python dependencies (pypam, numpy, scipy, etc.)
- All mbari-pbp tools as subcommands
Users can run the executable without installing Python, conda, or any dependencies.
- Poetry installed
- Development environment set up (
poetry install --with dev)
just build_standalone # same as: ./scripts/build_standalone.shOr manually:
poetry run pyinstaller pbp.specThe distribution will be created in dist/pbp/ directory containing the
executable and all dependencies.
The standalone executable provides a unified CLI with subcommands:
# Add to PATH (or use full path)
export PATH="$PATH:/path/to/dist/pbp"
# Show help
pbp --help
# Run subcommands
pbp meta-gen --help
pbp hmb-gen --help
pbp hmb-plot --help
pbp cloud --help
# Or run directly without adding to PATH:
./dist/pbp/pbp --helpNote: For official releases, standalone distributions are automatically created by the GitHub Actions workflow described in the CI/CD Integration section. The instructions below are for creating standalone builds locally during development or testing.
The build script automatically creates a distribution package with:
- The executable and bundled dependencies
- README.md
- QUICKSTART.txt with platform-specific usage instructions
The final zip file is named:
mbari-pbp-{version}-standalone-{platform}-{arch}.zip
You must build separately for each platform:
- macOS Intel: Build on macOS Intel machine
- macOS Apple Silicon: Build on macOS ARM machine (or use
--target-arch universal2) - Linux: Build on Linux machine (consider using Docker for reproducible builds)
- Windows: Build on Windows machine
In the initial setup, distribution sizes (as zip files) were in the order of 200-300 MB per platform. The sizes vary due to platform-specific bundling and compression of the Python runtime and scientific libraries (numpy, scipy, etc.).
The --onedir format provides faster startup (~1-2 seconds) compared to
--onefile (~3-5 seconds).
The --show and --only-show options in pbp hmb-plot are not available in
standalone builds due to missing interactive display backends. The executable
will display a user-friendly message suggesting to save plots to files instead.
On first run, matplotlib will display a "building font cache" message. This is harmless and should only happen once per session.
If the executable fails with import errors, add the missing module to
hiddenimports in pbp.spec.
Some dependencies (soundfile, h5netcdf) require native libraries. These should be automatically detected and bundled. If issues occur:
- Check PyInstaller output for warnings about missing libraries
- Manually specify binaries in
pbp.specif needed
Always test the standalone executable on a clean machine without Python installed to ensure all dependencies are properly bundled.
- Entry point:
pbp/main_cli.py- Unified CLI with subcommand routing- Includes multiprocessing compatibility fixes for frozen executables
- Detects frozen state using
sys.frozenandsys._MEIPASSattributes
- Build config:
pbp.spec- PyInstaller specification - Build script:
scripts/build_standalone.sh- Automated build process - CI/CD:
.github/workflows/release-standalone.yml- Automated multi-platform builds
Standalone Distribution:
- ✅ No Python/conda installation required
- ✅ No dependency conflicts
- ✅ Fast startup (~1-2 seconds with --onedir)
- ✅ Simple: download, extract, add to PATH
- ❌ Large file size (200-300MB)
- ❌ Platform-specific builds needed
Traditional Installation (pip/conda):
- ✅ Smaller download size
- ✅ Easier to update
- ❌ Requires Python/conda knowledge
- ❌ Potential dependency conflicts
- ❌ More complex setup for non-technical users
Automated builds are configured in .github/workflows/release-standalone.yml.
The workflow:
- Triggers automatically on version tags (e.g.,
v1.8.4) - Can be triggered manually from the GitHub Actions tab for testing
- Builds for Linux, macOS, and Windows in parallel
- Creates properly named zip files:
mbari-pbp-{version}-standalone-{platform}-{arch}.zip - Automatically uploads to GitHub Releases
To create a new release with standalone builds:
# Update version in pyproject.toml, then:
just tag-and-pushThis triggers both PyPI publication and standalone builds.
See .github/workflows/README.md for detailed documentation.
The standalone distribution capability is made possible by PyInstaller, a powerful tool for packaging Python applications into standalone executables.
The implementation of the standalone build system, including the multiprocessing compatibility fixes, GitHub Actions workflow, and documentation, was developed with assistance from Claude (Anthropic's AI assistant).