diff --git a/.gitignore b/.gitignore index 7fbacb9..9728c76 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ __pycache__/ dist/ build/ third_party/ +VoiceGrab.spec +VoiceGrab-AI.spec diff --git a/installer/build_linux.sh b/installer/build_linux.sh index be3b8b8..0d7a0c8 100644 --- a/installer/build_linux.sh +++ b/installer/build_linux.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash -# VoiceGrab — Linux build (produces dist/VoiceGrab- binary; AppImage if linuxdeploy available) -# WITH_AI=1 ./installer/build_linux.sh → also bundle torch+demucs (bigger build) +# VoiceGrab — Linux build +# ./installer/build_linux.sh → core app, onefile (dist/VoiceGrab) +# WITH_AI=1 ./installer/build_linux.sh → AI voice separation (torch+demucs) +# onedir (dist/VoiceGrab-AI/) +# +# Why onedir for the AI build: bundling torch into a onefile blob makes every +# startup re-extract ~2 GB (60–120 s). A onedir app starts instantly and the +# directory doubles as the plan's "sidecar" artifact. set -euo pipefail cd "$(dirname "$0")/.." @@ -8,13 +14,18 @@ PY="${PYTHON:-.venv/bin/python}" [ -x "$PY" ] || { echo "Create the venv first: python3 -m venv .venv && .venv/bin/pip install -r requirements.txt"; exit 1; } command -v ffmpeg >/dev/null || { echo "ffmpeg not found in PATH (needed to resolve the binary)"; exit 1; } -"$PY" -m pip install pyinstaller +"$PY" -m pip install -q pyinstaller + if [ "${WITH_AI:-0}" = "1" ]; then - echo "Building with AI voice separation (torch+demucs)…" - "$PY" -m pip install -r requirements-ai.txt + echo "Building WITH AI voice separation (torch+demucs, onedir)…" + "$PY" -m pip install -q -r requirements-ai.txt AI_FLAGS=(--collect-all demucs --collect-all torch) + LAYOUT=--onedir + NAME="VoiceGrab-AI" else AI_FLAGS=() + LAYOUT=--onefile + NAME="VoiceGrab" fi FFMPEG_BIN="$(command -v ffmpeg)" @@ -25,17 +36,23 @@ if [ -n "${FFPROBE_BIN:-}" ]; then EXTRA+=(--add-binary "$FFPROBE_BIN:.") fi -"$PY" -m PyInstaller --noconfirm --onefile --windowed --name VoiceGrab \ +"$PY" -m PyInstaller --noconfirm --clean --windowed \ + --name "$NAME" $LAYOUT \ --add-binary "$FFMPEG_BIN:." \ - "${EXTRA[@]}" \ - "${AI_FLAGS[@]}" \ + ${EXTRA[@]+"${EXTRA[@]}"} \ + ${AI_FLAGS[@]+"${AI_FLAGS[@]}"} \ --add-data "assets/icon.png:assets" \ --icon assets/icon.ico \ voicegrab.py echo -echo "Binary: dist/VoiceGrab" -echo "Test: ./dist/VoiceGrab" +if [ "$LAYOUT" = "--onedir" ]; then + echo "App dir: dist/$NAME/" + echo "Test: dist/$NAME/$NAME" +else + echo "Binary: dist/$NAME" + echo "Test: ./dist/$NAME" +fi # Optional: wrap in an AppImage if command -v linuxdeploy >/dev/null 2>&1; then