Initial commit: DaVinci Resolve installer for openSUSE Tumbleweed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
28allday 2026-03-28 12:24:08 +00:00
commit 36354807aa

192
install-resolve-tw.sh Executable file
View file

@ -0,0 +1,192 @@
#!/usr/bin/env bash
# openSUSE Tumbleweed — DaVinci Resolve + gdk-pixbuf (Fedora) + GLib + OpenCL + APR
# Folds in the working recipe discussed by Mark Himsley and others.
# Works for Resolve 19/20 (free or Studio).
[ -n "${BASH_VERSION:-}" ] || exec /usr/bin/env bash "$0" "$@"
set -euo pipefail
export PATH="$PATH:/sbin:/usr/sbin"
[[ "${DEBUG:-0}" == "1" ]] && set -x
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; }
pkg_install() { sudo zypper -n in --no-recommends "$@" || true; }
TARGET_USER="${SUDO_USER:-$USER}"
TARGET_HOME="$(getent passwd "$TARGET_USER" | cut -d: -f6)"
USR_APP_DIR="$TARGET_HOME/.local/share/applications"
WORKDIR=""
XHOST_ADDED=""
cleanup() {
[[ -n "$WORKDIR" && -d "$WORKDIR" ]] && rm -rf "$WORKDIR"
[[ -n "$XHOST_ADDED" ]] && xhost -SI:localuser:root >/dev/null 2>&1 || true
}
trap cleanup EXIT
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; }
# -------- deps ----------
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 --------
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; }
# -------- TW fix: fetch Fedora gdk-pixbuf2 and copy into /opt/resolve/libs --------
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 system OpenCL into Resolve dir
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."
# Copy system GLib into Resolves lib folder (overwrites bundled copies)
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
# Optional: libtiff5 shim (TW ships libtiff6)
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
# -------- wrapper --------
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
# -------- desktop entries --------
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"