DaVinci-Resolve-openSUSE-Tu.../install-resolve-tw.sh
28allday 4ef11e7248 Add detailed comments to script and comprehensive README
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 12:26:42 +00:00

287 lines
12 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# ==============================================================================
# DaVinci Resolve Installer for openSUSE Tumbleweed
#
# Installs DaVinci Resolve (19/20, free or Studio) on openSUSE Tumbleweed.
# Tumbleweed is a rolling-release distro that's always on the bleeding edge,
# which means it often has newer library versions than Resolve expects.
#
# This script handles several Tumbleweed-specific compatibility issues:
#
# 1. gdk-pixbuf2 — Tumbleweed's version is too new for Resolve's bundled
# Qt libraries. We fetch a compatible version from Fedora's archives
# and place it in Resolve's lib directory.
#
# 2. GLib replacement — Same as other distros: Resolve's bundled GLib
# conflicts with the system version. We replace it with system GLib.
#
# 3. OpenCL symlink — Resolve looks for libOpenCL.so.1 in its own lib
# directory. We symlink the system's OpenCL there.
#
# 4. libtiff shim — Tumbleweed ships libtiff.so.6, but Resolve wants
# libtiff.so.5. We create a compatibility symlink.
#
# 5. APR libraries — Apache Portable Runtime libs that Resolve's internal
# database engine sometimes needs on Tumbleweed.
#
# 6. XWayland wrapper — Forces Resolve to run under X11 (via XWayland)
# since it doesn't support native Wayland.
#
# Works for Resolve 19 and 20 (free and Studio editions).
#
# Prerequisites:
# - openSUSE Tumbleweed with NVIDIA drivers installed
# - DaVinci Resolve ZIP or .run downloaded to ~/Downloads/
#
# Usage:
# sudo ./install-resolve-tw.sh
# # or specify a file directly:
# sudo ./install-resolve-tw.sh /path/to/DaVinci_Resolve_Linux.zip
# ==============================================================================
# Ensure we're running in bash (not sh/dash)
[ -n "${BASH_VERSION:-}" ] || exec /usr/bin/env bash "$0" "$@"
set -euo pipefail
# Add sbin paths — some tools like ldconfig live in /sbin on openSUSE
export PATH="$PATH:/sbin:/usr/sbin"
# Enable debug mode with DEBUG=1 for verbose output
[[ "${DEBUG:-0}" == "1" ]] && set -x
# Coloured logging helpers for easy visual scanning of output
say() { echo -e "\033[1;32m==>\033[0m $*"; }
warn() { echo -e "\033[1;33m[!]\033[0m $*"; }
err() { echo -e "\033[1;31m[ERROR]\033[0m $*"; }
have() { command -v "$1" >/dev/null 2>&1; }
# zypper wrapper — --no-recommends keeps the install lean, || true prevents
# a missing optional package from killing the script
pkg_install() { sudo zypper -n in --no-recommends "$@" || true; }
# Resolve the real user's home directory for finding the ZIP in ~/Downloads/
TARGET_USER="${SUDO_USER:-$USER}"
TARGET_HOME="$(getent passwd "$TARGET_USER" | cut -d: -f6)"
USR_APP_DIR="$TARGET_HOME/.local/share/applications"
# Track temp dirs and X11 auth changes for cleanup on exit
WORKDIR=""
XHOST_ADDED=""
# Cleanup handler — removes temp extraction directory and revokes X11 root
# access that we may have granted for the GUI installer
cleanup() {
[[ -n "$WORKDIR" && -d "$WORKDIR" ]] && rm -rf "$WORKDIR"
[[ -n "$XHOST_ADDED" ]] && xhost -SI:localuser:root >/dev/null 2>&1 || true
}
trap cleanup EXIT
# Auto-detect the newest Resolve installer in ~/Downloads/. Checks for
# both .zip and .run files, preferring .zip (more common download format).
pick_latest() {
local z r
z=$(ls -t "$TARGET_HOME"/Downloads/DaVinci_Resolve*_Linux.zip 2>/dev/null | head -n1 || true)
r=$(ls -t "$TARGET_HOME"/Downloads/DaVinci_Resolve*_Linux.run 2>/dev/null | head -n1 || true)
[[ -n "$z" ]] && { echo "$z"; return; }
[[ -n "$r" ]] && { echo "$r"; return; }
echo ""
}
# -------- inputs ----------
SRC="${1:-}"
[[ -z "$SRC" ]] && SRC="$(pick_latest)"
[[ -n "$SRC" ]] || { err "Give a path to DaVinci Resolve Linux .zip or .run (or put it in ~/Downloads)."; exit 1; }
[[ -e "$SRC" ]] || { err "File not found: $SRC"; exit 1; }
# ==================== Dependencies ====================
#
# Install runtime libraries that Resolve needs. Tumbleweed uses zypper
# as its package manager. Key packages:
# libOpenCL1: OpenCL support for GPU-accelerated processing
# libjpeg62: JPEG library (Resolve uses the older ABI)
# libX11-xcb1 + xcb-*: X11/XCB protocol libraries for display
# libglib/gio/etc: GLib stack (system versions to replace bundled ones)
# libapr1/util: Apache Portable Runtime (Resolve's DB engine needs these)
say "Installing runtime tools + common libs…"
sudo zypper -n ref || true
RUNTIME_PKGS=(
unzip xhost curl rpm cpio
xwayland desktop-file-utils xdg-utils
libOpenCL1 libjpeg62 libX11-xcb1 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-keysyms1
libxcb-icccm4 libxcb-cursor0 libxcb-xfixes0 libxcb-randr0 libxcb-shape0
libglib-2_0-0 libgobject-2_0-0 libgmodule-2_0-0 libgio-2_0-0 libgthread-2_0-0
libapr1-0 libapr-util1-0 # APR libs Resolve sometimes needs on TW
)
pkg_install "${RUNTIME_PKGS[@]}"
# Ensure gthread exists (blackmagic GUI installer needs it)
if ! ldconfig -p 2>/dev/null | grep -q 'libgthread-2\.0\.so\.0'; then
pkg_install libgthread-2_0-0
fi
# -------- prepare installer --------
RUN_PATH=""
if [[ "$SRC" == *.run ]]; then
RUN_PATH="$(readlink -f "$SRC")"
elif [[ "$SRC" == *.zip ]]; then
say "Validating ZIP…"
unzip -tqq "$SRC" >/dev/null 2>&1 || { err "ZIP CRC failed. Re-download from Blackmagic."; exit 1; }
BASE="${XDG_CACHE_HOME:-$TARGET_HOME/.cache}/resolve-installer"
mkdir -p "$BASE"
WORKDIR="$(mktemp -d -p "$BASE")"
say "Extracting…"
unzip -q "$SRC" -d "$WORKDIR"
RUN_PATH="$(find "$WORKDIR" -maxdepth 3 -type f -name 'DaVinci_Resolve*_Linux.run' | head -n1 || true)"
[[ -n "$RUN_PATH" && -f "$RUN_PATH" ]] || { err "Could not find DaVinci_Resolve*_Linux.run inside ZIP."; exit 1; }
else
err "Unsupported file type: $SRC"
fi
say "Using installer: $RUN_PATH"
# ==================== Run Installer ====================
#
# Blackmagic's installer is a GUI application. We try running it as the
# current user first. If that doesn't result in /opt/resolve/bin/resolve
# being created (e.g. permission denied writing to /opt), we retry with
# sudo while passing through the display environment variables so the
# GUI can still render.
#
# QT_QPA_PLATFORM=xcb forces the installer to use X11 (not Wayland).
# SKIP_PACKAGE_CHECK=1 bypasses Resolve's distro check (it doesn't
# recognise openSUSE as a supported distro).
say "Running Blackmagic installer (user)…"
chmod +x "$RUN_PATH" || true
set +e
env QT_QPA_PLATFORM=xcb SKIP_PACKAGE_CHECK=1 "$RUN_PATH"
RC_USER=$?
set -e
say "User-run exit code: $RC_USER"
if [[ ! -x /opt/resolve/bin/resolve ]]; then
if [[ -n "${DISPLAY:-}" ]] && have xhost; then
xhost +SI:localuser:root >/dev/null 2>&1 && XHOST_ADDED=1 || true
fi
say "Running Blackmagic installer (sudo fallback)…"
set +e
sudo -E env DISPLAY="${DISPLAY:-:0}" XAUTHORITY="${XAUTHORITY:-$HOME/.Xauthority}" \
XDG_RUNTIME_DIR="/run/user/$(id -u "$TARGET_USER")" \
QT_QPA_PLATFORM=xcb SKIP_PACKAGE_CHECK=1 "$RUN_PATH"
RC_SUDO=$?
set -e
say "Sudo-run exit code: $RC_SUDO"
fi
[[ -d /opt/resolve/libs ]] || { err "/opt/resolve not present; installer likely cancelled."; exit 1; }
# ==================== Tumbleweed-Specific Fixes ====================
#
# gdk-pixbuf2 fix:
# Tumbleweed's gdk-pixbuf2 is too new for Resolve's bundled Qt libraries
# (ABI mismatch causes crashes). The workaround is to grab a compatible
# version from Fedora's package archives and place it in Resolve's lib
# directory. We try archived Fedora 38/40 builds first, then fall back
# to scraping Rawhide for the latest version.
say "Applying gdk-pixbuf + GLib + OpenCL + APR tweaks for Tumbleweed…"
tmp="$(mktemp -d)"
rpmfile="$tmp/gdk.rpm"
fetch_ok=""
# Try stable archived Fedora builds first (x86_64)
for url in \
"https://archive.fedoraproject.org/pub/archive/fedora/linux/releases/38/Everything/x86_64/os/Packages/g/gdk-pixbuf2-2.42.10-2.fc38.x86_64.rpm" \
"https://archive.fedoraproject.org/pub/archive/fedora/linux/releases/40/Everything/x86_64/os/Packages/g/gdk-pixbuf2-2.42.10-8.fc40.x86_64.rpm" \
; do
if curl -fsSL -o "$rpmfile" "$url"; then fetch_ok="1"; break; fi
done
# Last resort: scrape Rawhide index for the latest gdk-pixbuf2 x86_64 rpm
if [[ -z "$fetch_ok" ]]; then
idx="https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os/Packages/g/"
html="$(curl -fsSL "$idx" || true)"
cand="$(printf "%s" "$html" | grep -o 'gdk-pixbuf2-[^\" ]*\.x86_64\.rpm' | head -n1 || true)"
if [[ -n "$cand" ]]; then
curl -fsSL -o "$rpmfile" "${idx}${cand}" && fetch_ok="1"
fi
fi
if [[ -n "$fetch_ok" ]]; then
say "Extracting Fedora gdk-pixbuf2 into /opt/resolve/libs…"
( cd "$tmp" && rpm2cpio "$rpmfile" | cpio -idmv >/dev/null 2>&1 )
if [[ -d "$tmp/usr/lib64" ]]; then
sudo cp -vr "$tmp/usr/lib64/"* /opt/resolve/libs/ || true
else
warn "No usr/lib64 in RPM payload — skipping copy."
fi
else
warn "Could not fetch a Fedora gdk-pixbuf2 RPM (all URLs failed)."
fi
rm -rf "$tmp"
# Symlink the system's OpenCL library into Resolve's lib directory.
# Resolve needs libOpenCL.so.1 for GPU-accelerated processing (effects,
# colour grading, neural engine). On Tumbleweed it's usually provided
# by ocl-icd (OpenCL Installable Client Driver).
ocl="$(ldconfig -p 2>/dev/null | awk '/libOpenCL\.so\.1/{print $4; exit}')"
[[ -z "${ocl:-}" && -e /usr/lib64/ocl-icd/libOpenCL.so.1.0.0 ]] && ocl=/usr/lib64/ocl-icd/libOpenCL.so.1.0.0
[[ -n "${ocl:-}" ]] && sudo ln -sf "$ocl" /opt/resolve/libs/libOpenCL.so.1 || warn "libOpenCL.so.1 not found."
# Replace Resolves bundled GLib with the system version. Same fix as on
# Arch/Mint/Rocky — the bundled version is older and conflicts with other
# system libraries that Resolve also loads.
if ls /lib64/libglib-2.0.* >/dev/null 2>&1; then
sudo rm -f /opt/resolve/libs/libglib-2.0.so* || true
sudo cp -va /lib64/libglib-2.0.* /opt/resolve/libs/
elif ls /usr/lib64/libglib-2.0.* >/dev/null 2>&1; then
sudo rm -f /opt/resolve/libs/libglib-2.0.so* || true
sudo cp -va /usr/lib64/libglib-2.0.* /opt/resolve/libs/
fi
# libtiff compatibility shim — Tumbleweed ships libtiff.so.6, but Resolve
# links against libtiff.so.5. Creating a symlink works because the ABI
# is backwards-compatible between these versions.
if ! ldconfig -p | grep -q 'libtiff\.so\.5'; then
[[ -e /usr/lib64/libtiff.so.6 && ! -e /opt/resolve/libs/libtiff.so.5 ]] && \
sudo ln -s /usr/lib64/libtiff.so.6 /opt/resolve/libs/libtiff.so.5 || true
fi
# ==================== XWayland Wrapper ====================
#
# Create a wrapper script that forces Resolve to run under X11 (XWayland)
# and sets up the library search path. Tumbleweed defaults to Wayland on
# most desktop environments, but Resolve doesn't support native Wayland.
#
# Key environment variables:
# QT_QPA_PLATFORM=xcb: Force X11 mode
# __GLX_VENDOR_LIBRARY_NAME=nvidia: Use NVIDIA's GLX implementation
# QT_XCB_GL_INTEGRATION=none: Disable Qt's XCB GL integration
# (avoids conflicts with NVIDIA GL)
# QT_OPENGL=desktop: Use desktop OpenGL (not GLES)
# LD_LIBRARY_PATH: Prioritise our patched libs in /opt/resolve/
say "Creating /usr/local/bin/resolve wrapper…"
sudo tee /usr/local/bin/resolve >/dev/null <<'EOF'
#!/usr/bin/env bash
# Force X11/XWayland + NVIDIA GLVND
export QT_QPA_PLATFORM=xcb
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export QT_XCB_GL_INTEGRATION=none
export QT_OPENGL=desktop
# Prefer the libs we just placed in /opt/resolve/libs
export LD_LIBRARY_PATH="/opt/resolve/libs:/opt/resolve/bin:${LD_LIBRARY_PATH:-}"
exec /opt/resolve/bin/resolve "$@"
EOF
sudo chmod +x /usr/local/bin/resolve
# Copy and patch desktop entries to use our wrapper instead of launching
# Resolve directly. User-level entries in ~/.local/share/applications/
# take priority over system entries in /usr/share/applications/.
say "Patching desktop entries to use wrapper…"
mkdir -p "$USR_APP_DIR"
for f in /usr/share/applications/davinci-resolve.desktop \
/usr/share/applications/com.blackmagicdesign.resolve.desktop; do
if [[ -f "$f" ]]; then
install -m 0644 "$f" "$USR_APP_DIR/"
tgt="$USR_APP_DIR/$(basename "$f")"
sed -i 's|^Exec=.*|Exec=/usr/local/bin/resolve %u|g' "$tgt"
sed -i 's|^TryExec=.*|TryExec=/usr/local/bin/resolve|g' "$tgt" || true
sed -i 's|^Path=.*|Path=/opt/resolve/|g' "$tgt" || true
fi
done
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$USR_APP_DIR" || true
say "Done. Launch with: resolve"