From 54fa8ab1170e6478e901953e68d87c8805e170ca Mon Sep 17 00:00:00 2001 From: LyAhn Date: Sat, 13 Jun 2026 21:48:40 +0100 Subject: [PATCH] build(cuda): ship a CUDA installer variant with bundled runtime DLLs The default build (default = candle-cuda) load-time-imports the CUDA runtime, so it crashes on any machine without the toolkit. Add a CUDA release variant that bundles the redistributable runtime DLLs (cudart/cublas/cublasLt/curand, verified via dumpbin) so it runs on any NVIDIA machine with just a driver. - tauri.cuda.conf.json: a 'tauri build --config' overlay (CPU release untouched) that points the updater at latest-cuda.json so a CUDA install never self-updates into the CPU build - windows/cuda-hooks.nsh: NSIS hook embeds the DLLs via File and extracts them next to phokus.exe, where the Windows loader searches - build:app:cuda script; cuda-redist/ gitignored (DLLs copied from the toolkit locally), with a negation so the overlay stays tracked --- .gitignore | 7 +++++++ package.json | 1 + src-tauri/tauri.cuda.conf.json | 17 ++++++++++++++++ src-tauri/windows/cuda-hooks.nsh | 35 ++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 src-tauri/tauri.cuda.conf.json create mode 100644 src-tauri/windows/cuda-hooks.nsh diff --git a/.gitignore b/.gitignore index 7e7224f..df5794f 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,10 @@ dist-ssr *.json *.pyc + +# Bundled CUDA runtime DLLs for the CUDA build (copied from the toolkit +# locally; ~600 MB, never committed). See RELEASE_PLAN.md "CUDA release variant". +src-tauri/cuda-redist/ + +# Keep the CUDA build config overlay tracked despite the *.json rule above. +!src-tauri/tauri.cuda.conf.json diff --git a/package.json b/package.json index c8b2cd2..b6d5842 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dev:app": "tauri dev", "dev:app:cpu": "tauri dev -- --no-default-features", "build:app:cpu": "tauri build -- --no-default-features", + "build:app:cuda": "tauri build --config src-tauri/tauri.cuda.conf.json", "dev:vite": "vite", "preview": "vite preview", "tauri": "tauri" diff --git a/src-tauri/tauri.cuda.conf.json b/src-tauri/tauri.cuda.conf.json new file mode 100644 index 0000000..4509530 --- /dev/null +++ b/src-tauri/tauri.cuda.conf.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "plugins": { + "updater": { + "endpoints": [ + "https://github.com/JezzWTF/phokus/releases/latest/download/latest-cuda.json" + ] + } + }, + "bundle": { + "windows": { + "nsis": { + "installerHooks": "./windows/cuda-hooks.nsh" + } + } + } +} diff --git a/src-tauri/windows/cuda-hooks.nsh b/src-tauri/windows/cuda-hooks.nsh new file mode 100644 index 0000000..14f8c47 --- /dev/null +++ b/src-tauri/windows/cuda-hooks.nsh @@ -0,0 +1,35 @@ +; NSIS hooks for the CUDA build variant. +; +; The CUDA exe load-time-imports the CUDA runtime DLLs, so they must sit next +; to phokus.exe ($INSTDIR) where the Windows loader searches. Rather than +; bundling them as Tauri "resources" (which land in $INSTDIR\resources\) and +; then relocating them — a move that proved unreliable in the elevated/silent +; installer (CopyFiles via SHFileOperation, and even Rename, failed) — we embed +; them directly into the installer with NSIS `File` and extract them straight +; to $INSTDIR. `File` is the standard, reliable install primitive. +; +; This hook is !included from its original location, and ${__FILEDIR__} in this +; top-level !define expands at *include* time to this file's own directory, +; src-tauri\windows. cuda-redist is its sibling under src-tauri, so one level +; up. (Caveat that bit us: ${__FILEDIR__} used inline *inside the macro* would +; instead expand at insertion time to Tauri's generated nsis dir — hence the +; !define here.) The 4 DLLs must be present in src-tauri\cuda-redist at build +; time (see RELEASE_PLAN.md). + +!define CUDA_REDIST "${__FILEDIR__}\..\cuda-redist" + +!macro NSIS_HOOK_POSTINSTALL + DetailPrint "Phokus: installing bundled CUDA runtime libraries..." + SetOutPath "$INSTDIR" + File "${CUDA_REDIST}\cudart64_12.dll" + File "${CUDA_REDIST}\cublas64_12.dll" + File "${CUDA_REDIST}\cublasLt64_12.dll" + File "${CUDA_REDIST}\curand64_10.dll" +!macroend + +!macro NSIS_HOOK_POSTUNINSTALL + Delete "$INSTDIR\cudart64_12.dll" + Delete "$INSTDIR\cublas64_12.dll" + Delete "$INSTDIR\cublasLt64_12.dll" + Delete "$INSTDIR\curand64_10.dll" +!macroend