Packaging & Distribution
14.1 Build from source (all platforms)
Use this checklist when you want to compile and share binaries with an alpha tester.
Prerequisites: Set up your development environment first (see §2 Development Environment Setup).
Install Rust (
rustup) and ensure the active toolchain uses edition 2021 (or later for edition 2024 support).Set up dependencies (choose one method from §2):
Docker (recommended):
docker-compose -f docker-compose.dev.yml build # Build image if needed docker-compose -f docker-compose.dev.yml run --rm dev cargo build --releaseSystem packages: Follow platform-specific instructions in §2.2
Conda:
conda activate orbitron-devand set environment variables (see §2.3)
Build binaries (examples for Docker; adjust paths for other environments):
# Build all binaries at once cargo build --release --workspace # Or build individually: cargo build --release -p orbitron-ui-shell cargo build --release -p orbitron-cli --bin orbitron cargo build --release -p orbitron-tui --bin orbitron-tuiArtifacts land in
target/release/:- GUI:
target/release/orbitron-viewer(ororbitron-ui-shell) - CLI:
target/release/orbitron - TUI:
target/release/orbitron-tui
- GUI:
Note: - Docker users: Environment variables are automatically set (see §2.1). HDF5 1.12.3 is pre-installed and compatible with hdf5-sys 0.8.1. - System packages/Conda users: Ensure HDF5_DIR and related environment variables are set (see §2.2 or §2.3). Verify HDF5 version compatibility with hdf5-sys 0.8.1 (requires HDF5 1.10.x - 1.12.x).
14.2 macOS desktop bundle
Run this after the build-from-source checklist to produce a signed .app (and optional .dmg).
Install the bundler tooling once:
cargo install cargo-bundleEnsure the GUI crate exposes a binary target (
ui/shell/src/bin/orbitron-viewer.rs) that launchesstart_ui.Confirm bundle metadata in
ui/shell/Cargo.tomlunder[package.metadata.bundle].Get your signing identity:
security find-identity -v -p codesigningBuild the
.app(and optional.dmg):# Ensure HDF5_DIR is set (see §2.2 for system packages or §2.3 for conda) cargo bundle --release -p orbitron-ui-shell --bin orbitron-viewer cargo bundle --release -p orbitron-ui-shell --bin orbitron-viewer --format dmgOutput lands in
target/release/bundle/osx/.Sign, notarize, and staple (recommended sequence). Use the bundle name reported by
cargo bundle(typicallyorbitron-ui-shell.appunless you override it in[package.metadata.bundle]):# ensure Resources exists (can be empty) mkdir -p target/release/bundle/osx/orbitron-ui-shell.app/Contents/Resources # sign the app bundle codesign --force --deep --options runtime --timestamp \ --sign "Developer ID Application: YOUR NAME (TEAMID)" \ target/release/bundle/osx/orbitron-ui-shell.app # verify signature codesign --verify --deep --strict --verbose=2 \ target/release/bundle/osx/orbitron-ui-shell.app # create a zip for notarization ditto -c -k --keepParent \ target/release/bundle/osx/orbitron-ui-shell.app \ orbitron-ui-shell.zip # submit for notarization (use a keychain profile) xcrun notarytool submit orbitron-ui-shell.zip \ --keychain-profile "notary-orbitron" \ --wait # staple the notarization ticket xcrun stapler staple target/release/bundle/osx/orbitron-ui-shell.app # verify Gatekeeper acceptance spctl -a -vv target/release/bundle/osx/orbitron-ui-shell.appIf you see
source=Unnotarized Developer ID, the app is signed correctly but has not been notarized/stapled yet. Ensure thenotarytool submit ... --waitandstapler staplesteps succeed, then re-runspctl. You can also check ticket state with:xcrun stapler validate target/release/bundle/osx/orbitron-ui-shell.appFor a single-command local workflow, use:
scripts/macos-notarize-app.sh \ --identity "Developer ID Application: YOUR NAME (TEAMID)" \ --profile "notary-orbitron" \ --app target/release/bundle/osx/orbitron-ui-shell.appBundle runtime dylibs if the app fails to launch (common with HDF5/OpenSSL):
APP=target/release/bundle/osx/orbitron-ui-shell.app # Set LIBDIR to your HDF5 installation (system packages: $(brew --prefix hdf5)/lib, conda: $CONDA_PREFIX/lib) LIBDIR="${HDF5_DIR:-$(brew --prefix hdf5)}/lib" FW="$APP/Contents/Frameworks" mkdir -p "$FW" cp "$LIBDIR"/libhdf5*.dylib "$FW/" cp "$LIBDIR"/libcrypto.3.dylib "$FW/" cp "$LIBDIR"/libssl.3.dylib "$FW/" cp "$LIBDIR"/libcurl.4.dylib "$FW/" cp "$LIBDIR"/libnghttp2.14.dylib "$FW/" cp "$LIBDIR"/libssh2.1.dylib "$FW/" cp "$LIBDIR"/libsz.2.dylib "$FW/" cp "$LIBDIR"/libz.1.dylib "$FW/" cp "$LIBDIR"/libgssapi_krb5.2.2.dylib "$FW/" cp "$LIBDIR"/libkrb5.3.3.dylib "$FW/" cp "$LIBDIR"/libk5crypto.3.1.dylib "$FW/" cp "$LIBDIR"/libcom_err.3.0.dylib "$FW/" cp "$LIBDIR"/libkrb5support.1.1.dylib "$FW/" install_name_tool -add_rpath "@executable_path/../Frameworks" \ "$APP/Contents/MacOS/orbitron-viewer" codesign --force --deep --options runtime --timestamp \ --sign "Developer ID Application: YOUR NAME (TEAMID)" \ "$APP"If another dylib is missing, run
otool -Lon the failing library, copy the exact versioned dylib fromLIBDIRintoContents/Frameworks, then re-sign.Create the keychain profile once:
xcrun notarytool store-credentials "notary-orbitron" \ --apple-id "you@example.com" \ --team-id "TEAMID" \ --password "APP_SPECIFIC_PASSWORD"
14.3 Windows installer
Install WiX tooling and the Cargo helper:
cargo install cargo-wixGenerate an initial installer manifest (runs once to scaffold
wix/main.wxs):cargo wix init --bin orbitron-viewer --output wixBuild the
.msi:cargo wix --nocapture --release --bin orbitron-viewerThe resulting installer lands in
target/wix/. Sign withsigntool.exebefore shipping.
14.4 Linux packages
Deb:
cargo install cargo-deb cargo deb --package orbitron-ui-shell --no-buildRPM (optional):
cargo install cargo-rpm cargo rpm build --releaseUpdate
Cargo.tomlmetadata (maintainer,license, post-install scripts) as required by the distribution.
14.5 Precompiled archive binaries
Build the desired targets with
cargo build --release --target <triple>.Package the artifacts alongside README, LICENSE, and sample config:
tar czf orbitron-viewer-${VERSION}-${TARGET}.tar.gz \ -C target/${TARGET}/release orbitron-viewer orbitron-cli README.md LICENSEUse
.ziparchives on Windows for ease of extraction.Publish checksum files (e.g.,
shasum -a 256 <file>).
Automate the above via CI (GitHub Actions/Gitea runners) using a matrix over macos-latest, windows-latest, and ubuntu-latest. Reuse the same pipelines to upload artifacts to the chosen release host.
14.6 Python Wheels
Python wheels provide the Orbitron API for use in Jupyter notebooks and Python scripts.
Build Script
./scripts/build-python-wheels.sh [OPTIONS]Options: - --skip-widget - Skip Jupyter widget frontend build - --release - Build with optimizations (default) - --debug - Build without optimizations (faster builds, slower runtime)
Output
dist/python-wheels/
├── orbitron-0.2.0-cp38-abi3-manylinux_2_34_x86_64.whl # Linux
├── orbitron-0.2.0-cp38-abi3-macosx_11_0_arm64.whl # macOS Apple Silicon
├── orbitron-0.2.0-cp38-abi3-win_amd64.whl # Windows
└── README.txt # Installation instructions
# abi3: one wheel per platform runs on CPython 3.8+. Intel macOS isn't built.
Manual Build
cd extensions/python-bridge
# Build wheel
maturin build --release --features python
# Output in target/wheels/
ls -lh ../../target/wheels/Platform-Specific Builds
macOS Universal Binary (Intel + Apple Silicon):
maturin build --release --features python --universal2Linux (manylinux):
# Requires Docker for manylinux compliance
maturin build --release --features python --manylinux 2_34Windows:
# Build on Windows machine or CI
maturin build --release --features pythonTesting Python Wheels
./scripts/test-python-wheel.sh [path/to/wheel.whl]
# Or test latest wheel
./scripts/test-python-wheel.shTests performed: 1. Create clean virtual environment 2. Install wheel 3. Run 6 smoke tests: - Import orbitron module - Create Orbitron instance - Load molecule - Measure distance - Serialize to bytes - Access properties
Troubleshooting Python Wheels
Error: “maturin not found”
pip install maturinError: “Could not find HDF5 headers”
# Ensure conda environment is active
conda activate orbitron-dev
# Verify HDF5
conda list | grep hdf5Error: “Rust compiler version mismatch”
# Project uses Rust 1.92.0 (pinned in rust-toolchain.toml)
rustup show # Should show 1.92.0
# If wrong version
rustup update
cd /path/to/orbitron # Let rust-toolchain.toml activateWheel platform mismatch:
# Build universal binary for macOS
maturin build --release --features python --universal2
# Check wheel platform tag
ls target/wheels/ # Should show macosx_*_universal2.whl14.7 WASM Web Viewer
The WASM web viewer provides an interactive 3D molecular viewer for embedding in websites.
Prerequisites
# Install trunk (WASM bundler)
cargo install trunk
# Add WASM target
rustup target add wasm32-unknown-unknown
# Verify
trunk --version # Should be 0.17+Build Script
./scripts/build-wasm-viewer.shThis script: 1. Builds WASM binary using trunk 2. Creates ZIP bundle with all assets 3. Calls standalone HTML builder (see §14.8) 4. Creates README.txt with usage instructions
Output
dist/wasm-viewer/
├── orbitron-viewer-web-v0.2.0.zip # ZIP bundle (~2-3 MB)
│ └── Contains:
│ ├── index.html
│ ├── orbitron-viewer-wasm_bg.wasm # WebGPU viewer binary
│ ├── orbitron-viewer-wasm.js # JavaScript glue code
│ └── README.txt
├── orbitron-viewer-standalone-v0.2.0.html # Self-contained HTML (~5 MB)
└── README.txt # Deployment instructions
Manual Build
cd viewer/wasm
# Build with trunk
trunk build --release
# Output in dist/ subdirectory
ls -lh dist/Customization
Edit viewer/wasm/Trunk.toml to customize: - Output directory - Asset paths - Build hooks - Optimization level
Testing WASM Viewer
ZIP Bundle:
# Extract and serve
cd dist/wasm-viewer
unzip orbitron-viewer-web-v0.2.0.zip
cd orbitron-viewer-web
# Create test molecule
orbitron convert ../../../../io/pipelines/tests/fixtures/xyz/benzene.xyz molecule.bin
# Serve locally
python3 -m http.server 8000
# Open in browser
open http://localhost:8000/index.html?scene=molecule.binManual checks: - [ ] Viewer loads without errors (check browser console) - [ ] Molecule renders correctly - [ ] Rotation, zoom, pan controls work - [ ] Selection works (click atoms) - [ ] No console errors or warnings
Troubleshooting WASM Viewer
Error: “trunk not found”
cargo install trunk
rustup target add wasm32-unknown-unknownError: “wasm32-unknown-unknown not installed”
rustup target add wasm32-unknown-unknownBlank viewer in browser: - Check browser console (F12) for errors - Verify WebGPU support: Run navigator.gpu in console (should not be null) - Check CORS: Serve via HTTP server, not file:// protocol
Large .wasm file size: - Ensure using --release flag (optimized build) - Check Cargo.toml for optimization settings - Expected size: ~2-3 MB for release build
14.8 Standalone HTML Viewer
The standalone HTML embeds the WASM binary as base64 for use in PowerPoint and presentations.
Prerequisites
# macOS/Linux
brew install coreutils # Provides base64
# Or verify system base64
base64 --version
which base64Build Script
./scripts/build-wasm-standalone.shThis script: 1. Builds WASM viewer (if not already built) 2. Reads .wasm binary and converts to base64 3. Embeds base64 into self-contained HTML file 4. Outputs ~5 MB HTML file (WASM ~2 MB → base64 ~3 MB)
Output
dist/wasm-viewer/
└── orbitron-viewer-standalone-v0.2.0.html # ~5 MB self-contained file
Manual Build
# Ensure WASM viewer is built first
cd viewer/wasm
trunk build --release
# Base64 encode WASM binary
WASM_BASE64=$(base64 -i dist/orbitron-viewer-wasm_bg.wasm)
# Embed in HTML (requires template editing)
# See scripts/build-wasm-standalone.sh for complete implementationTesting Standalone HTML
cd dist/wasm-viewer
# Create test molecule
orbitron convert ../../../io/pipelines/tests/fixtures/xyz/benzene.xyz molecule.bin
# Open in browser (requires local web server for CORS)
python3 -m http.server 8000 &
open http://localhost:8000/orbitron-viewer-standalone-v0.2.0.html?scene=molecule.binPowerPoint test: 1. Open PowerPoint 2. Insert → Object → Browse → Select standalone HTML 3. Resize frame 4. Enter slideshow mode (F5) 5. Verify viewer is interactive
Troubleshooting Standalone HTML
Error: “base64 command not found”
# macOS
brew install coreutils
# Linux
apt-get install coreutils # or yum install coreutils
# Verify
which base64Standalone HTML won’t open in PowerPoint: - Security settings: Enable “Trust access to VBA project” in PowerPoint Options - File path length: Move to shorter path (e.g., C:\slides\) - Alternative: Upload to web server and link via URL
File too large (>10 MB): - Expected size: ~5 MB - If larger: Check WASM binary size (~2 MB expected) - Optimization: Ensure trunk used --release flag
14.9 Complete Release Build
To build all distributions at once:
#!/bin/bash
# Complete release build script
set -e # Exit on error
echo "Building Orbitron v0.2.0 distributions..."
# 1. Clean previous builds
rm -rf dist/
mkdir -p dist
# 2. Build Python wheels
echo "Building Python wheels..."
./scripts/build-python-wheels.sh --skip-widget
# 3. Build WASM viewers
echo "Building WASM viewers..."
./scripts/build-wasm-viewer.sh
# 4. Create release archive
echo "Creating release archive..."
cd dist
tar -czf orbitron-v0.2.0-distributions.tar.gz python-wheels/ wasm-viewer/
cd ..
echo "Build complete!"
echo "Distributions:"
tree -L 2 dist/14.10 Distribution Sizes
Expected sizes for v0.2.0:
| Distribution | Size | Notes |
|---|---|---|
| Python wheel | 5-15 MB | Varies by platform |
| WASM ZIP bundle | 2-3 MB | Compressed |
| Standalone HTML | ~5 MB | Includes embedded WASM as base64 |
| Complete tarball | 25-50 MB | All distributions |
14.11 Build Times
Approximate build times on 2020 MacBook Pro (M1):
| Task | Time | Notes |
|---|---|---|
| Python wheel (release) | 3-5 min | First build; incremental ~30s |
| WASM viewer (release) | 2-4 min | First build; incremental ~20s |
| Standalone HTML | 10-30s | Depends on base64 encoding speed |
| Complete release | 5-10 min | All distributions |
14.12 Release Checklist
Before releasing distributions, verify:
See RELEASE_CHECKLIST.md for complete pre-release verification.