DaVinci-Resolve-openSUSE-Tu.../install-resolve-tw.sh
28allday 36354807aa Initial commit: DaVinci Resolve installer for openSUSE Tumbleweed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 12:24:08 +00:00

192 lines
7.4 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
# 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"