FLIMKit

Plugins / FLIMKit / Compiled App macOS Windows Linux · edit on GitHub

Compiled App (macOS / Windows / Linux)

FLIMKit can be packaged as a standalone executable - no Python needed on the target machine.

Build

python install.py --dev   # installs PyInstaller (and test requirements)
python build_and_sign.py

Output: dist/FLIMKit.app (macOS) or dist/FLIMKit / dist/FLIMKit.exe (Linux/Windows).

GPU acceleration in the compiled app

The compiled app bundles whatever GPU libraries are present on the build machine. The GPU backend is not fetched or probed at runtime from an external install, it must be baked in at build time.

Build machine GPU bundled
Apple Silicon (M-series) Mac with mlx installed MLX + PyTorch MPS
Intel Mac CPU only (no Metal GPU)
Linux/Windows with CUDA PyTorch CUDA
Linux/Windows with ROCm PyTorch ROCm

If you need GPU acceleration in the compiled app, build it yourself on the machine (or OS/hardware type) where it will run. A pre-built binary downloaded from Releases will only have GPU support if it was built on matching hardware.

build_and_sign.py detects and bundles GPU backends automatically, run it on the target hardware after running python install.py to install the right backend.

Development builds

New work lands on the dev branch first, and dev is merged into main for each release. Every push to dev that touches the code builds the app again as FLIMKitDEV and publishes it on the Releases page as a pre-release tagged dev-YYYY.MM.DD, with the documentation PDF as it stood at that commit. It is not a release: nothing goes to PyPI, and a released FLIMKit is never offered it. A second push on the same day replaces that day's build.

FLIMKitDEV-macos.zip, FLIMKitDEV-windows.zip and FLIMKitDEV-linux.zip unzip to an app named FLIMKitDEV, so it can sit beside the released FLIMKit. Its version reads as the last release plus the date, for example 0.13.8+dev.2026.09.30, and the window title and About box say FLIMKitDEV with that version, so a running dev build can't be mistaken for a release. Both share the settings in ~/.flimkit.

A push that changes flimkit/_version.py is a release, so the version tag builds it instead. Pushing to main builds nothing on its own; a release is built from its version tag.

Updating the app

Help > Check for Updates shows a Download and install button when a newer build is on GitHub. A released FLIMKit is offered the latest release, and FLIMKitDEV the latest dev build. It downloads the zip for your platform (337 MB for macOS at 0.13.8), puts the new app where the running one is, and offers to restart. The old copy is kept until the new one is in place, so a failed download or a full disk leaves FLIMKit as it was.

It downloads the build GitHub made, which carries the GPU backends of GitHub's machines (GPU acceleration in the compiled app). If you built the app yourself to get your GPU, update the clone and rebuild instead:

python update.py --rebuild --app-path /Applications/FLIMKit.app

On macOS, an app opened straight from the Downloads folder runs from a temporary read-only copy and cannot replace itself. Move it into Applications, or any other folder, first. On Windows the old .exe can't be deleted while it runs, so it is left as FLIMKit.exe.old and removed the next time FLIMKit starts.

Documentation PDF

Docs/build_pdf.py turns this file into a PDF. It needs markdown and weasyprint, and WeasyPrint needs Pango.

pip install markdown weasyprint
python Docs/build_pdf.py FLIMKit-docs.pdf

macOS notes

The app is self-signed (ad-hoc). If you built it locally, Gatekeeper won't prompt because there's no quarantine flag. For distribution to other machines, you need a paid Apple Developer ID and notarization via xcrun notarytool.

Uses --onedir for a proper .app bundle and avoids the two-dock-icon issue you get with --onefile's two-stage launcher.

Output file location

All output files are saved to the same directory as the input PTU file. The working directory inside the bundle is read-only.

Machine IRF

Machine IRFs are stored in ~/.flimkit/machine_irf/ (created automatically). The app ships with a bundled default until you build your own. After saving a new machine IRF, restart the app, or point File > Preferences... > Files > Default machine IRF (.npy) at it, which takes effect at once.