Skip to content

Commit 42ff146

Browse files
committed
Installer updates
1 parent 9b03e7e commit 42ff146

7 files changed

Lines changed: 363 additions & 75 deletions

File tree

.claude/skills/build-installer.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
description: Build the FastFlix installer, distribution, launcher, and uninstaller
3+
---
4+
5+
# Building the FastFlix Installer & Distribution
6+
7+
## Prerequisites
8+
9+
- Go 1.22+ installed
10+
- `go-winres` installed: `go install github.com/tc-hib/go-winres@latest`
11+
- Python 3.13+ with `uv`
12+
- `zstandard` Python package: `uv run pip install zstandard`
13+
- Internet access (first build downloads embeddable Python)
14+
15+
## Full Build (everything from scratch)
16+
17+
```bash
18+
# 1. Build the full distribution + archive
19+
uv run python scripts/build_distribution.py --archive
20+
21+
# 2. Generate icon/manifest resources for installer
22+
cd cmd/installer && go-winres make && cd ../..
23+
24+
# 3. Build the installer (embeds the archive)
25+
go build -ldflags="-s -w -H windowsgui -X main.Version=$(python -c 'from fastflix.version import __version__; print(__version__)')" -o dist/FastFlix_installer.exe ./cmd/installer
26+
```
27+
28+
The build script (`scripts/build_distribution.py --archive`) handles:
29+
- Downloading embeddable Python 3.13
30+
- Installing all dependencies via pip `--target`
31+
- Building the Go launcher (`FastFlix.exe`) and uninstaller (`uninstall.exe`)
32+
- Trimming unused PySide6 modules (~527 MB savings)
33+
- Creating `fastflix_dist.tar.zst` archive
34+
- Copying `licenses.txt` and generating `terms_translations.json`
35+
36+
## Quick Rebuild (after code changes)
37+
38+
### Launcher only
39+
```bash
40+
go build -ldflags="-s -w -X main.Version=6.3.0" -o dist/FastFlix/FastFlix.exe ./cmd/launcher
41+
```
42+
43+
### Uninstaller only
44+
```bash
45+
go build -ldflags="-s -w -H windowsgui" -o dist/FastFlix/uninstall.exe ./cmd/uninstaller
46+
```
47+
48+
### Installer only (requires archive already built)
49+
```bash
50+
go build -ldflags="-s -w -H windowsgui -X main.Version=6.3.0" -o dist/FastFlix_installer.exe ./cmd/installer
51+
```
52+
53+
## Important Notes
54+
55+
- **Launcher**: Built WITHOUT `-H windowsgui` (needs console for logs)
56+
- **Installer/Uninstaller**: Built WITH `-H windowsgui` (no console)
57+
- **go-winres**: Must run `go-winres make` in each `cmd/*/` directory before building to embed icons. The `.syso` files are gitignored.
58+
- **licenses.txt**: Copied from `docs/build-licenses.txt` by the build script. Must exist in `cmd/installer/` before building.
59+
- **terms_translations.json**: Generated by the build script from `TERMS_SECTIONS` in `terms_agreement.py` + `languages.yaml`
60+
- **DO NOT** use `CREATE_NO_WINDOW` flag on the launcher's child process — breaks FFmpeg pipe handles
61+
- **DO NOT** use `walk` or other Go GUI frameworks — they have `TTM_ADDTOOL` failures on modern Windows. Use raw Win32 API.
62+
63+
## Testing
64+
65+
```bash
66+
# Test launcher
67+
dist/FastFlix/FastFlix.exe --version
68+
dist/FastFlix/FastFlix.exe --test
69+
70+
# Test full app launch
71+
dist/FastFlix/FastFlix.exe
72+
73+
# Test installer
74+
dist/FastFlix_installer.exe
75+
76+
# Test standalone uninstaller (from install location)
77+
"%LOCALAPPDATA%\Programs\FastFlix\uninstall.exe"
78+
```

CLAUDE.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ uv run pytest tests/encoders/test_hevc_x265_command_builder.py -v
2929
# Run the application
3030
python -m fastflix
3131

32-
# Build executables
33-
uv run pyinstaller FastFlix_Windows_OneFile.spec
32+
# Build Windows distribution + installer (Go-based, replaces PyInstaller)
33+
uv run python scripts/build_distribution.py --archive # Full dist + archive
34+
cd cmd/installer && go-winres make && cd ../.. # Icon/manifest resources
35+
go build -ldflags="-s -w -H windowsgui -X main.Version=6.3.0 -X main.BuildDate=$(date +%Y-%m-%d)" -o dist/FastFlix_installer.exe ./cmd/installer
36+
37+
# Build Linux/macOS executables (still uses PyInstaller)
3438
uv run pyinstaller FastFlix_Nix_OneFile.spec
3539
```
3640

WINDOWS_BUILD.md

Lines changed: 114 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,187 @@
11
# Building FastFlix on Windows
22

3-
This guide explains how to build FastFlix executables on Windows.
3+
This guide explains how to build FastFlix executables and the installer on Windows.
44

55
## Prerequisites
66

77
1. **Python 3.13 or higher**
88
- Download from [python.org](https://www.python.org/downloads/)
99
- Make sure to check "Add Python to PATH" during installation
1010

11-
2. **Git** (to clone/update the repository)
12-
- Download from [git-scm.com](https://git-scm.com/download/win)
11+
2. **Go 1.22 or higher**
12+
- Download from [go.dev](https://go.dev/dl/)
13+
- Needed for the launcher, installer, and uninstaller binaries
1314

14-
## Build Steps
15+
3. **go-winres** (for embedding icons and manifests)
16+
```bash
17+
go install github.com/tc-hib/go-winres@latest
18+
```
1519

16-
### 1. Open Command Prompt or PowerShell
20+
4. **uv** (Python package manager)
21+
```bash
22+
pip install uv
23+
```
1724

18-
Navigate to where you want to clone/have the FastFlix repository:
25+
5. **Git** (to clone/update the repository)
26+
- Download from [git-scm.com](https://git-scm.com/download/win)
1927

20-
```bash
21-
cd C:\path\to\your\projects
22-
git clone https://github.com/cdgriffith/FastFlix.git
23-
cd FastFlix
24-
```
28+
## Quick Build (Full Installer)
2529

26-
Or if you already have it:
30+
If you just want to build the installer from scratch:
2731

2832
```bash
2933
cd C:\path\to\FastFlix
30-
```
3134

32-
### 2. Create and Activate Virtual Environment
35+
# Install Python dependencies
36+
uv sync --frozen
3337

34-
```bash
35-
python -m venv venv
36-
venv\Scripts\activate
37-
```
38+
# Install zstandard for archive compression
39+
uv run pip install zstandard
3840

39-
You should see `(venv)` in your command prompt.
41+
# Build the full distribution + archive (downloads embeddable Python, installs deps, builds Go binaries)
42+
uv run python scripts/build_distribution.py --archive
4043

41-
### 3. Install Dependencies
44+
# Generate icon/manifest resources for the installer
45+
cd cmd\installer
46+
go-winres make
47+
cd ..\..
4248

43-
```bash
44-
pip install --upgrade pip
45-
pip install -e ".[dev]"
49+
# Build the installer
50+
go build -ldflags="-s -w -H windowsgui -X main.Version=6.3.0" -o dist\FastFlix_installer.exe .\cmd\installer
4651
```
4752

48-
This installs FastFlix in editable mode with all development dependencies including PyInstaller.
53+
The installer will be at `dist\FastFlix_installer.exe` (~87 MB).
4954

50-
### 4. Build the Executable
55+
## What the Build Script Does
5156

52-
You have two options:
57+
`scripts/build_distribution.py --archive` performs these steps automatically:
5358

54-
#### Option A: Single Executable (Recommended for distribution)
59+
1. Downloads the official Python 3.13 embeddable distribution (~11 MB)
60+
2. Configures the embeddable Python to find installed packages
61+
3. Builds a FastFlix wheel and installs it with all dependencies
62+
4. Builds the Go launcher (`FastFlix.exe`) and uninstaller (`uninstall.exe`)
63+
5. Trims unused PySide6 modules (~527 MB savings)
64+
6. Copies licenses and generates translated terms text
65+
7. Creates a compressed `tar.zst` archive (~83 MB)
5566

56-
```bash
57-
pyinstaller FastFlix_Windows_OneFile.spec
58-
```
67+
The archive is then embedded into the Go installer binary via `go:embed`.
5968

60-
The executable will be in: `dist\FastFlix.exe`
69+
## Building Individual Components
6170

62-
#### Option B: Directory with Multiple Files (Faster startup)
71+
### Launcher Only
6372

6473
```bash
65-
pyinstaller FastFlix_Windows_Installer.spec
74+
go build -ldflags="-s -w -X main.Version=6.3.0" -o dist\FastFlix\FastFlix.exe .\cmd\launcher
6675
```
6776

68-
The executable will be in: `dist\FastFlix\FastFlix.exe`
77+
### Uninstaller Only
6978

70-
### 5. Test the Build
79+
```bash
80+
cd cmd\uninstaller
81+
go-winres make
82+
cd ..\..
83+
go build -ldflags="-s -w -H windowsgui" -o dist\FastFlix\uninstall.exe .\cmd\uninstaller
84+
```
85+
86+
### Installer Only (requires archive already built)
7187

7288
```bash
73-
cd dist
74-
FastFlix.exe
89+
cd cmd\installer
90+
go-winres make
91+
cd ..\..
92+
go build -ldflags="-s -w -H windowsgui -X main.Version=6.3.0" -o dist\FastFlix_installer.exe .\cmd\installer
7593
```
7694

77-
Or for the installer version:
95+
## Testing the Build
7896

7997
```bash
80-
cd dist\FastFlix
81-
FastFlix.exe
98+
# Test launcher
99+
dist\FastFlix\FastFlix.exe --version
100+
dist\FastFlix\FastFlix.exe --test
101+
102+
# Launch the full app
103+
dist\FastFlix\FastFlix.exe
104+
105+
# Test the installer
106+
dist\FastFlix_installer.exe
82107
```
83108

84-
## Running Without Building (For Testing)
109+
## Running Without Building (For Development)
85110

86-
If you just want to test changes without building an executable:
111+
If you just want to test changes without building executables:
87112

88113
```bash
114+
uv sync --frozen
89115
python -m fastflix
90116
```
91117

92118
## Troubleshooting
93119

94-
### Missing Dependencies
95-
96-
If you get import errors, try reinstalling:
120+
### Missing Go
97121

122+
If `go build` fails with "go: command not found", ensure Go is installed and in your PATH:
98123
```bash
99-
pip install --upgrade --force-reinstall -e ".[dev]"
124+
go version
100125
```
101126

102-
### Build Errors
127+
### Missing go-winres
103128

104-
1. Make sure you're in the FastFlix root directory
105-
2. Ensure the virtual environment is activated (you see `(venv)`)
106-
3. Try deleting `build` and `dist` folders and rebuilding:
129+
The installer and uninstaller need `go-winres` to embed icons:
130+
```bash
131+
go install github.com/tc-hib/go-winres@latest
132+
```
133+
134+
### Missing licenses.txt or terms_translations.json
107135

136+
These are generated by the build script. If building the installer manually:
108137
```bash
109-
rmdir /s /q build dist
110-
pyinstaller FastFlix_Windows_OneFile.spec
138+
copy docs\build-licenses.txt cmd\installer\licenses.txt
139+
uv run python scripts/build_distribution.py --archive
111140
```
112141

142+
### Build Errors
143+
144+
1. Make sure you're in the FastFlix root directory
145+
2. Try deleting `dist` and rebuilding:
146+
```bash
147+
rmdir /s /q dist
148+
uv run python scripts/build_distribution.py --archive
149+
```
150+
113151
### FFmpeg Not Found
114152

115-
The FastFlix executable doesn't include FFmpeg. You need to:
153+
The FastFlix distribution doesn't include FFmpeg. You need to:
116154

117155
1. Download FFmpeg from [ffmpeg.org](https://ffmpeg.org/download.html#build-windows)
118156
2. Extract it somewhere
119157
3. Add the `bin` folder to your PATH, or configure it in FastFlix settings
120158

121-
## Known Limitations
159+
## Architecture
160+
161+
The Windows distribution uses three Go binaries instead of PyInstaller:
162+
163+
| Binary | Purpose | Console |
164+
|--------|---------|---------|
165+
| `FastFlix.exe` | Go launcher — sets up Python environment and runs `python.exe -m fastflix` | Yes (for logs) |
166+
| `uninstall.exe` | Standalone uninstaller — registered with Windows Add/Remove Programs | No (GUI) |
167+
| `FastFlix_installer.exe` | Dark-themed installer with embedded distribution archive | No (GUI) |
122168

123-
### PGS to SRT OCR (PyInstaller builds)
169+
The installer supports two modes:
170+
- **Install for just me** — installs to `%LOCALAPPDATA%\Programs\FastFlix` (no admin required)
171+
- **Install for all users** — installs to `%ProgramFiles%\FastFlix` (triggers UAC)
124172

125-
Due to an upstream issue in pgsrip v0.1.12, PGS to SRT OCR conversion does not work in PyInstaller-built executables. The feature works perfectly when running from source (`python -m fastflix`).
173+
## Linux/macOS
126174

127-
If you need PGS OCR functionality, please run FastFlix from source instead of using the compiled executable.
175+
Linux and macOS builds still use PyInstaller:
176+
177+
```bash
178+
uv run pyinstaller FastFlix_Nix_OneFile.spec
179+
```
128180

129181
## Notes
130182

131-
- The build process creates a `portable.py` file temporarily (it's removed after)
132-
- The `.spec` files automatically collect all dependencies from `pyproject.toml`
133-
- The icon is located at `fastflix\data\icon.ico`
183+
- The Go launcher is built as a **console app** (not GUI) so users can see log output
184+
- The installer and uninstaller are built with `-H windowsgui` (no console window)
185+
- Icons are embedded via `go-winres``.syso` files are gitignored
186+
- The distribution archive uses Zstandard compression (level 22) for best ratio
187+
- PySide6 trimming removes WebEngine (193 MB), Quick/QML, 3D, Designer, and other unused Qt modules

cmd/installer/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import (
1717
"unsafe"
1818
)
1919

20-
// Version is set at build time via -ldflags="-X main.Version=6.3.0"
20+
// Version and BuildDate are set at build time via -ldflags
2121
var Version = "dev"
22+
var BuildDate = "" // format: 2006-01-02
2223

2324
func main() {
2425
runtime.LockOSThread()

0 commit comments

Comments
 (0)