Skip to content

Commit 0bc3186

Browse files
Merge pull request #1216 from LucBennett/feat/linux-dev-scripts
Add Debian/Ubuntu build instructions and scripts
2 parents ec73ee4 + 0af9b42 commit 0bc3186

4 files changed

Lines changed: 177 additions & 1 deletion

File tree

dev/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ git submodule update --init --recursive
88
Platform-specific build instructions:
99
- [macOS](macos/README.md)
1010
- [Windows](windows/README.md)
11-
- Linux: See [GitHub Actions workflow](../.github/workflows/test.yml) - install deps from `debian/control`, then CMake build
11+
- [Linux](linux/README.md)
1212

1313
## Web Debugger
1414

dev/linux/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Building Jellyfin Desktop on Linux
2+
3+
## Quick Start
4+
5+
### Setup and build
6+
7+
```bash
8+
dev/linux/setup.sh # First time: install dependencies (Debian/Ubuntu)
9+
dev/linux/build.sh # Configure, build, and optionally install
10+
```
11+
12+
## Prerequisites
13+
14+
- **Debian/Ubuntu** (or derivative) with `apt-get`
15+
16+
`setup.sh` installs everything else:
17+
18+
- Build tooling: `devscripts`, `equivs`, `ninja-build`, `cmake`
19+
- Build-time packages from [`../../debian/control`](../../debian/control)'s `Build-Depends`, including the required Qt6 modules (`qt6-base-dev`, `qt6-base-private-dev`, `qt6-declarative-dev`, `qt6-webengine-dev`, `qt6-wayland-dev`), `libmpv-dev`, `libcec-dev`, and the rest of the native toolchain
20+
- Runtime QML plugins from `debian/control`'s `Depends:` field (`qml6-module-qtwebengine`, `qml6-module-qtwebchannel`, `qml6-module-qtquick-controls`, `qml6-module-qtquick-window`, `qml6-module-qtqml-workerscript`, `qml6-module-qtquick-templates`, `qml6-module-qt-labs-platform`), none of these are pulled in transitively by the `-dev` packages above, so they're installed separately
21+
22+
## Install
23+
24+
`build.sh` asks for confirmation separately before each `sudo` step:
25+
26+
1. **Install Binary** @ `/usr/local/bin/jellyfin-desktop`
27+
2. **Desktop integration** (`.desktop` file, icon, appdata metadata) @ `/usr/local/share/{applications,icons,metainfo}/`
28+
29+
Answer `n` to either prompt to skip it. The built binary at `build/src/jellyfin-desktop` still runs without installing.
30+
31+
## Directory Structure
32+
33+
- `build/` - Build output (safe to delete)
34+
- `build/src/jellyfin-desktop` - Built executable
35+
36+
## Scripts
37+
38+
- `setup.sh` - Install build and runtime dependencies
39+
- `build.sh` - Initialize submodules, configure, build, and optionally install
40+
41+
## Clean Build
42+
43+
```bash
44+
rm -rf build
45+
dev/linux/build.sh
46+
```
47+
48+
## Troubleshooting
49+
50+
### Missing Qt6 packages
51+
52+
```
53+
error: Qt6 dev packages not found. Run setup.sh first
54+
```
55+
56+
Run `dev/linux/setup.sh`.
57+
58+
## Notes
59+
60+
- Data/config/cache/log file locations are documented in the [main README](../../README.md#file-locations)

dev/linux/build.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env bash
2+
# Jellyfin Desktop - Linux build & install script
3+
set -euo pipefail
4+
5+
SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
6+
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
7+
BUILD_DIR="${PROJECT_ROOT}/build"
8+
PREFIX="/usr/local"
9+
10+
confirm() {
11+
local reply
12+
read -r -p "${1} [y/N] " reply
13+
[[ "${reply}" =~ ^[Yy]([Ee][Ss])?$ ]]
14+
}
15+
16+
if ! pkg-config --exists Qt6Core 2>/dev/null; then
17+
echo "error: Qt6 dev packages not found. Run setup.sh first" >&2
18+
exit 1
19+
fi
20+
21+
# Submodules (e.g. external/mpvqt) are required for -DUSE_STATIC_MPVQT=ON.
22+
if [[ -z "$(ls -A "${PROJECT_ROOT}/external/mpvqt" 2>/dev/null)" ]]; then
23+
echo "Initializing submodules..."
24+
git -C "${PROJECT_ROOT}" submodule update --init --recursive
25+
fi
26+
27+
if [[ -f "${BUILD_DIR}/CMakeCache.txt" ]]; then
28+
cached_source="$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "${BUILD_DIR}/CMakeCache.txt")"
29+
if [[ "${cached_source}" != "${PROJECT_ROOT}" ]]; then
30+
echo "Build directory was configured from ${cached_source}, removing stale build/"
31+
rm -rf "${BUILD_DIR}"
32+
fi
33+
fi
34+
35+
echo "Configuring..."
36+
cmake -B "${BUILD_DIR}" -G Ninja \
37+
-DCMAKE_BUILD_TYPE=Release \
38+
-DUSE_STATIC_MPVQT=ON \
39+
"${PROJECT_ROOT}"
40+
41+
echo "Building..."
42+
cmake --build "${BUILD_DIR}"
43+
44+
BINARY="${BUILD_DIR}/src/jellyfin-desktop"
45+
if [[ ! -x "${BINARY}" ]]; then
46+
echo "error: build did not produce ${BINARY}" >&2
47+
exit 1
48+
fi
49+
50+
echo ""
51+
echo "Build complete: ${BINARY}"
52+
echo ""
53+
54+
BIN_DEST="${PREFIX}/bin/jellyfin-desktop"
55+
DESKTOP_SRC="${PROJECT_ROOT}/resources/meta/org.jellyfin.JellyfinDesktop.desktop"
56+
APPDATA_SRC="${PROJECT_ROOT}/resources/meta/org.jellyfin.JellyfinDesktop.appdata.xml"
57+
ICON_SRC="${PROJECT_ROOT}/resources/images/icon.svg"
58+
DESKTOP_DEST="${PREFIX}/share/applications/org.jellyfin.JellyfinDesktop.desktop"
59+
APPDATA_DEST="${PREFIX}/share/metainfo/org.jellyfin.JellyfinDesktop.appdata.xml"
60+
ICON_DEST="${PREFIX}/share/icons/hicolor/scalable/apps/org.jellyfin.JellyfinDesktop.svg"
61+
62+
if confirm "Install binary to ${BIN_DEST} (requires sudo)?"; then
63+
sudo install -Dm755 "${BINARY}" "${BIN_DEST}"
64+
echo "Installed ${BIN_DEST}"
65+
else
66+
echo "Skipped binary install."
67+
fi
68+
69+
if confirm "Copy .desktop file, icon, and appdata metadata for app menu integration (requires sudo)?"; then
70+
sudo install -Dm644 "${DESKTOP_SRC}" "${DESKTOP_DEST}"
71+
sudo install -Dm644 "${APPDATA_SRC}" "${APPDATA_DEST}"
72+
sudo install -Dm644 "${ICON_SRC}" "${ICON_DEST}"
73+
echo "Installed desktop entry, icon, and appdata metadata."
74+
else
75+
echo "Skipped desktop integration files."
76+
fi
77+
78+
echo ""
79+
echo "Done."

dev/linux/setup.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
# Jellyfin Desktop - Linux dependency installer
3+
# Run once (Debian/Ubuntu) before build.sh.
4+
#
5+
# Installs everything listed under Build-Depends in ../../debian/control,
6+
# then installs the runtime QML plugins the app imports (Qt.labs.platform,
7+
# WebEngine, etc.).
8+
set -euo pipefail
9+
10+
SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
11+
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
12+
13+
if ! command -v apt-get >/dev/null; then
14+
echo "error: apt-get not found. This script targets Debian/Ubuntu." >&2
15+
echo "See ${PROJECT_ROOT}/debian/control for the full dependency list." >&2
16+
exit 1
17+
fi
18+
19+
echo "Installing build tooling (devscripts, equivs, ninja-build)..."
20+
sudo apt-get update
21+
sudo apt-get install --yes devscripts equivs ninja-build
22+
23+
echo "Installing build dependencies from debian/control..."
24+
sudo mk-build-deps -i -r -t "apt-get --yes" "${PROJECT_ROOT}/debian/control"
25+
26+
echo "Installing runtime QML modules..."
27+
sudo apt-get install --yes \
28+
qml6-module-qtwebengine \
29+
qml6-module-qtwebchannel \
30+
qml6-module-qtquick-controls \
31+
qml6-module-qtquick-window \
32+
qml6-module-qtqml-workerscript \
33+
qml6-module-qtquick-templates \
34+
qml6-module-qt-labs-platform
35+
36+
echo ""
37+
echo "Setup complete. Run build.sh to build."

0 commit comments

Comments
 (0)