Skip to content

Commit 1c49862

Browse files
Add Linux support (x86_64 + aarch64)
Full cross-platform Linux support with self-contained dependency bundling, matching the existing macOS and Windows architecture. Rust worker: - New platform/linux.rs with XDG Base Directory paths - LinuxX64/LinuxArm64 platform variants in dependency_locator - LD_LIBRARY_PATH + vapoursynth.auto.conf environment setup - Linux libdvdread search paths (Debian, Fedora, Arch) Flutter app: - Generated app/linux/ platform (GTK3) - Linux branches in dependency_manager, tool_locator, disc_detector, whisper_addon_manager for XDG paths and LD_LIBRARY_PATH - Linux DVD detection (/media, /run/media, /mnt) - xdg-open for "Show in Folder" on Linux Build scripts: - download-deps-linux.sh: builds Python, VapourSynth, FFmpeg, 20 plugins - package-deps-linux.sh: zips deps with SHA256 for auto-download - package-linux.sh: creates distributable .tar.gz - run-debug-linux.sh: dev build + run convenience script CI & release: - build-linux.yml: GitHub Actions matrix (x64 + arm64) - Updated release.sh, ci-build-and-release.sh, check-deps-changed.sh Documentation: - CLAUDE.md and README.md updated with Linux instructions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent be008e0 commit 1c49862

33 files changed

Lines changed: 2462 additions & 20 deletions

.github/workflows/build-linux.yml

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
name: Build Linux
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version number (e.g., 0.9.0)'
8+
required: true
9+
type: string
10+
deps_tag:
11+
description: 'Deps release tag (e.g., deps-v1.3.0)'
12+
required: true
13+
type: string
14+
arch:
15+
description: 'Architecture'
16+
required: false
17+
type: choice
18+
options:
19+
- x64
20+
- arm64
21+
- both
22+
default: x64
23+
24+
jobs:
25+
build:
26+
strategy:
27+
matrix:
28+
include:
29+
- os: ubuntu-22.04
30+
arch: x64
31+
flutter_arch: x64
32+
rust_target: x86_64-unknown-linux-gnu
33+
- os: ubuntu-22.04-arm
34+
arch: arm64
35+
flutter_arch: arm64
36+
rust_target: aarch64-unknown-linux-gnu
37+
fail-fast: false
38+
39+
runs-on: ${{ matrix.os }}
40+
41+
# Only run the job if it matches the requested arch (or both)
42+
if: ${{ inputs.arch == 'both' || inputs.arch == matrix.arch }}
43+
44+
steps:
45+
- name: Checkout repository
46+
uses: actions/checkout@v4
47+
48+
- name: Install system dependencies
49+
run: |
50+
sudo apt-get update
51+
sudo apt-get install -y clang cmake git ninja-build pkg-config \
52+
libgtk-3-dev liblzma-dev libstdc++-12-dev
53+
54+
- name: Setup Flutter
55+
uses: subosito/flutter-action@v2
56+
with:
57+
channel: 'stable'
58+
cache: true
59+
60+
- name: Setup Rust
61+
uses: dtolnay/rust-toolchain@stable
62+
with:
63+
targets: ${{ matrix.rust_target }}
64+
65+
- name: Cache Rust dependencies
66+
uses: actions/cache@v4
67+
with:
68+
path: |
69+
~/.cargo/bin/
70+
~/.cargo/registry/index/
71+
~/.cargo/registry/cache/
72+
~/.cargo/git/db/
73+
worker/target/
74+
key: ${{ runner.os }}-${{ matrix.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }}
75+
restore-keys: |
76+
${{ runner.os }}-${{ matrix.arch }}-cargo-
77+
78+
- name: Download Linux dependencies
79+
run: |
80+
DEPS_VERSION="${{ inputs.deps_tag }}"
81+
DEPS_VERSION="${DEPS_VERSION#deps-v}"
82+
83+
mkdir -p deps/linux-${{ matrix.arch }}
84+
85+
DEPS_URL="https://github.com/${{ github.repository }}/releases/download/${{ inputs.deps_tag }}/VapourBox-deps-${DEPS_VERSION}-linux-${{ matrix.arch }}.zip"
86+
echo "Downloading deps from: $DEPS_URL"
87+
curl -L -o deps.zip "$DEPS_URL"
88+
unzip -o deps.zip -d deps/linux-${{ matrix.arch }}
89+
rm -f deps.zip
90+
91+
echo "Dependencies extracted:"
92+
ls -la deps/
93+
94+
- name: Update version numbers
95+
run: |
96+
VERSION="${{ inputs.version }}"
97+
DEPS_TAG="${{ inputs.deps_tag }}"
98+
DEPS_VERSION="${DEPS_TAG#deps-v}"
99+
100+
# Update pubspec.yaml
101+
sed -i "s/^version: .*/version: ${VERSION}+1/" app/pubspec.yaml
102+
103+
# Update deps-version.json
104+
sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"${DEPS_VERSION}\"/" app/assets/deps-version.json
105+
sed -i "s/\"releaseTag\": \"[^\"]*\"/\"releaseTag\": \"${DEPS_TAG}\"/" app/assets/deps-version.json
106+
107+
# Update Cargo.toml
108+
sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" worker/Cargo.toml
109+
110+
- name: Build Rust worker
111+
run: |
112+
cd worker
113+
cargo build --release --target ${{ matrix.rust_target }}
114+
# Copy to default release location for package script
115+
mkdir -p target/release
116+
cp target/${{ matrix.rust_target }}/release/vapourbox-worker target/release/ || true
117+
118+
- name: Build Flutter app
119+
run: |
120+
cd app
121+
flutter pub get
122+
dart run build_runner build --delete-conflicting-outputs
123+
flutter build linux --release
124+
125+
- name: Package release
126+
run: |
127+
./Scripts/package-linux.sh --version "${{ inputs.version }}" --arch ${{ matrix.arch }} --skip-build
128+
129+
- name: Upload artifacts
130+
uses: actions/upload-artifact@v4
131+
with:
132+
name: VapourBox-${{ inputs.version }}-linux-${{ matrix.arch }}
133+
path: dist/VapourBox-${{ inputs.version }}-linux-${{ matrix.arch }}.tar.gz

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ app/windows/flutter/generated_plugins.cmake
5050
# Platform-specific (unsupported platforms)
5151
app/android/
5252
app/ios/
53-
app/linux/
5453
app/web/
5554

5655
# =============================================================================

CLAUDE.md

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Both files should stay synchronized - README.md is for humans, CLAUDE.md is for
1212

1313
## Project Overview
1414

15-
VapourBox is a **cross-platform** (macOS + Windows) video processing application using VapourSynth. It provides a simple drag-and-drop interface for deinterlacing, denoising, sharpening, and other video processing tasks as an alternative to more complex tools like Hybrid.
15+
VapourBox is a **cross-platform** (macOS + Windows + Linux) video processing application using VapourSynth. It provides a simple drag-and-drop interface for deinterlacing, denoising, sharpening, and other video processing tasks as an alternative to more complex tools like Hybrid.
1616

1717
**Technology Stack:**
1818
- **UI**: Flutter (Dart) - cross-platform desktop app
@@ -56,7 +56,8 @@ VapourBox/
5656
│ ├── assets/filters/ # Built-in filter schemas (JSON)
5757
│ │ └── core/ # Core filters (deinterlace, denoise, etc.)
5858
│ ├── macos/ # macOS platform config
59-
│ └── windows/ # Windows platform config
59+
│ ├── windows/ # Windows platform config
60+
│ └── linux/ # Linux platform config
6061
6162
├── worker/ # Rust worker crate
6263
│ ├── src/
@@ -72,7 +73,9 @@ VapourBox/
7273
├── deps/ # Platform-specific dependencies
7374
│ ├── macos-arm64/ # Python 3.12, VS, FFmpeg, plugins
7475
│ ├── macos-x64/
75-
│ └── windows-x64/ # VSPipe, Python 3.8, FFmpeg, plugins
76+
│ ├── windows-x64/ # VSPipe, Python 3.8, FFmpeg, plugins
77+
│ ├── linux-x64/ # Python 3.12, VS, FFmpeg, plugins
78+
│ └── linux-arm64/
7679
7780
├── licenses/ # GPL, LGPL, NOTICES
7881
├── Scripts/ # Build, package, and release scripts
@@ -109,15 +112,19 @@ VapourBox/
109112
- Rust 1.70+
110113
- Windows: Visual Studio Build Tools with C++ workload
111114
- macOS: Xcode Command Line Tools
115+
- Linux: `clang cmake git ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev`
112116

113117
### Download Dependencies
114118

115119
```bash
116120
# macOS
117-
./scripts/download-deps-macos.sh
121+
./Scripts/download-deps-macos.sh
118122

119123
# Windows (PowerShell)
120-
.\scripts\download-deps-windows.ps1
124+
.\Scripts\download-deps-windows.ps1
125+
126+
# Linux
127+
./Scripts/download-deps-linux.sh
121128
```
122129

123130
### Build Rust Worker
@@ -152,6 +159,11 @@ mkdir -p ../build/macos/Build/Products/Release
152159
cp -R ~/Library/Developer/Xcode/DerivedData/Runner-*/Build/Products/Release/vapourbox.app ../build/macos/Build/Products/Release/
153160
```
154161

162+
**Linux:**
163+
```bash
164+
cd app && flutter pub get && flutter build linux --release
165+
```
166+
155167
### Generate Dart JSON Serialization
156168

157169
```bash
@@ -189,6 +201,15 @@ dart run build_runner build
189201
2. Copy worker: `cp worker/target/debug/vapourbox-worker.exe app/build/windows/x64/runner/Debug/`
190202
3. Run app: `cd app && flutter run`
191203

204+
**Linux: Use the debug script:**
205+
206+
```bash
207+
./Scripts/run-debug-linux.sh # Full build (worker + app) and launch
208+
./Scripts/run-debug-linux.sh --skip-worker # Rebuild app only
209+
./Scripts/run-debug-linux.sh --skip-app # Rebuild worker only
210+
./Scripts/run-debug-linux.sh --run-only # Just copy and launch
211+
```
212+
192213
### Production Packaging
193214

194215
**IMPORTANT**: Never manually assemble a release build. Always use packaging scripts — the app will silently crash on video drop if the bundle is incomplete.
@@ -200,8 +221,14 @@ dart run build_runner build
200221
# Windows
201222
.\Scripts\package-windows.ps1 -Version "X.Y.Z" [-SkipBuild]
202223

224+
# Linux
225+
./Scripts/package-linux.sh --version X.Y.Z [--skip-build]
226+
203227
# Test packaged app from terminal to see errors:
228+
# macOS:
204229
dist/VapourBox.app/Contents/MacOS/vapourbox
230+
# Linux:
231+
dist/VapourBox-X.Y.Z-linux-x64/vapourbox
205232
```
206233

207234
Do NOT run `app/build/macos/Build/Products/Release/vapourbox.app` directly — it lacks templates and proper bundle structure.
@@ -431,7 +458,17 @@ The `download-deps-windows.ps1` and `download-deps-macos.sh` scripts apply these
431458
- Quarantine removal: `xattr -cr` on deps after download
432459
- Show in Folder: `open -R <path>`
433460

434-
Plugin lists for both platforms: see `deps/` directories or download scripts.
461+
### Linux
462+
463+
- Bundled deps in `~/.local/share/VapourBox/deps/linux-{x64,arm64}/` (or `$XDG_DATA_HOME`)
464+
- Worker sets: `PYTHONHOME`, `PYTHONPATH`, `VAPOURSYNTH_CONF_PATH`, `LD_LIBRARY_PATH`
465+
- `patchelf` used for RPATH fixup (equivalent to macOS `install_name_tool`)
466+
- GPU/OpenCL: requires user-installed GPU driver; nnedi3cl degrades gracefully without it
467+
- Show in Folder: `xdg-open <directory>`
468+
- Debug builds: use `./Scripts/run-debug-linux.sh`
469+
- No code signing or quarantine removal needed
470+
471+
Plugin lists for all platforms: see `deps/` directories or download scripts.
435472

436473
---
437474

@@ -478,23 +515,29 @@ Prerequisites: draft release must exist for the tag, `gh` CLI authenticated.
478515
| `Scripts/check-deps-changed.sh` | Detect if deps changed since last release (exit 0=changed, 1=unchanged) |
479516
| `Scripts/package-macos.sh` | Package macOS app |
480517
| `Scripts/package-windows.ps1` | Package Windows app |
518+
| `Scripts/package-linux.sh` | Package Linux app |
481519
| `Scripts/package-deps-macos.sh` | Package macOS deps |
482520
| `Scripts/package-deps-windows.ps1` | Package Windows deps |
521+
| `Scripts/package-deps-linux.sh` | Package Linux deps |
522+
| `Scripts/download-deps-linux.sh` | Build Linux deps from source |
523+
| `Scripts/run-debug-linux.sh` | Dev build + run for Linux |
483524

484525
### Release Checklist
485526

486527
1. **Confirm version** — ask user, update `pubspec.yaml`
487528
2. **Check deps** — run `check-deps-changed.sh`; if changed, bump version in `deps-version.json`
488529
3. **Build & package** — use packaging scripts (or `release.sh` for full automation)
489-
4. **Update `app/assets/deps-version.json`** — after packaging each platform's deps zip, update its `sha256` and `size` fields with the values printed by the packaging script. **Both platforms must have valid (non-null) sha256 and size before release.** The app uses these values to verify downloaded deps at runtime.
530+
4. **Update `app/assets/deps-version.json`** — after packaging each platform's deps zip, update its `sha256` and `size` fields with the values printed by the packaging script. **All platforms must have valid (non-null) sha256 and size before release.** The app uses these values to verify downloaded deps at runtime.
490531
5. **Test** — fresh install + upgrade test
491532
6. **Create GitHub releases** — deps release first (if changed, tag `deps-vX.Y.Z`), then app release (tag `vX.Y.Z`)
492533

493534
### Cross-Platform Notes
494535

495536
- Flutter Windows can't build on macOS — use GitHub Actions
537+
- Flutter Linux can't build on macOS — use GitHub Actions or a Linux VM
496538
- Windows deps can be zipped on macOS if `deps/windows-x64/` exists
497-
- CI builds are ad-hoc signed; sign locally for distribution
539+
- Linux deps must be built on Linux (`./Scripts/download-deps-linux.sh`)
540+
- CI builds are ad-hoc signed; sign locally for distribution (macOS only)
498541

499542
### Dependency Version History
500543

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Get the latest release for your platform:
3030
|----------|------|
3131
| macOS (Apple Silicon) | `VapourBox-x.x.x-macos-arm64.dmg` |
3232
| Windows 10/11 (x64) | `VapourBox-x.x.x-windows-x64.zip` |
33+
| Linux (x64) | `VapourBox-x.x.x-linux-x64.tar.gz` |
34+
| Linux (arm64) | `VapourBox-x.x.x-linux-arm64.tar.gz` |
3335

3436
## Installation
3537

@@ -48,6 +50,15 @@ Get the latest release for your platform:
4850
3. Run `vapourbox.exe`
4951
4. On first launch, VapourBox will automatically download its processing dependencies (~195 MB)
5052

53+
### Linux
54+
55+
1. Download the `.tar.gz` file for your architecture from the [releases page](https://github.com/StuartCameronCode/VapourBox/releases/latest)
56+
2. Extract: `tar -xzf VapourBox-x.x.x-linux-x64.tar.gz`
57+
3. Run: `cd VapourBox-x.x.x-linux-x64 && ./vapourbox`
58+
4. On first launch, VapourBox will automatically download its processing dependencies (~100 MB)
59+
60+
> **GPU acceleration**: For GPU-accelerated deinterlacing (NNEDI3CL), install your GPU's OpenCL driver. Without it, VapourBox falls back to CPU-based processing automatically.
61+
5162
## Features
5263

5364
- **Drag-and-drop interface** — drop video files, folders, or VIDEO_TS directories to start
@@ -117,6 +128,17 @@ brew install libdvdcss
117128

118129
Download `libdvdcss-2.dll` from [VideoLAN](https://www.videolan.org/developers/libdvdcss.html) and place it in the VapourBox application directory (next to `vapourbox.exe`).
119130

131+
**Linux:**
132+
133+
```bash
134+
# Debian/Ubuntu
135+
sudo apt install libdvdcss2
136+
# Fedora (RPM Fusion required)
137+
sudo dnf install libdvdcss
138+
# Arch
139+
sudo pacman -S libdvdcss
140+
```
141+
120142
Unencrypted DVDs (home recordings, some independent releases) work without libdvdcss.
121143

122144
### Timeline Navigation

Scripts/check-deps-changed.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ DEPS_PATHS=(
2020
"deps/windows-x64/ffmpeg"
2121
"deps/macos-arm64"
2222
"deps/macos-x64"
23+
"deps/linux-x64"
24+
"deps/linux-arm64"
2325
"Scripts/download-deps-windows.ps1"
2426
"Scripts/download-deps-macos.sh"
27+
"Scripts/download-deps-linux.sh"
2528
)
2629

2730
# Get the last deps release tag

0 commit comments

Comments
 (0)