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:
commit
36354807aa
1 changed files with 192 additions and 0 deletions
192
install-resolve-tw.sh
Executable file
192
install-resolve-tw.sh
Executable 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 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"
|
||||
Loading…
Add table
Reference in a new issue