#!/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 Resolve’s 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"