blender/release/bin/blender-launcher
Brecht Van Lommel 321e737891 Linux: Preload system TBB if it is compatible and newer
This avoids issues where the Intel GPU ray tracing driver may depend
on the newer system TBB version. In particular, on Ubuntu the TBB
library is no longer statically linked into the driver as it was before.

We think this really should be fixed upstream in distributions, and
that graphics drivers should not pull in TBB as a dynamic library. As
other VFX software will run into the same issue, and this breaks an
implicit convention that graphics drivers avoid such ABI conflicts.
But policies around static and dynamic linking make this difficult.

This fix only affects the Blender Snap package and the blender-launcher
script used for Steam, to reduce the risk for Blender 5.0. For later
versions we may change the Blender executable itself into a shell script,
or use an alternative fix that makes Blender into a shared library.

Ref #140631

Pull Request: https://projects.blender.org/blender/blender/pulls/148154
2025-10-24 19:07:48 +02:00

50 lines
2 KiB
Bash
Executable file

#!/bin/sh
BF_DIST_BIN=$(dirname "$(readlink -f "$0")")
BF_PROGRAM="blender"
# Attempt to preload system TBB library if it is newer than the one we bundled.
# This solves problems with the Intel ray-tracing library using this newer TBB
# while Blender is already using an older one.
# Library name with major version that we needed.
BF_TBB_LIB_NAME=$(readlink ${BF_DIST_BIN}/lib/libtbb.so)
if [ -n "$BF_TBB_LIB_NAME" ]; then
BF_TBB_LIB_NAME=$(basename $BF_TBB_LIB_NAME)
# Get absolute path from LD_DEBUG output trying to preload this library.
# We have not found a better alternative that takes into account LD_LIBRARY_PATH.
BF_TBB_LD_OUTPUT=$(LD_DEBUG=versions LD_PRELOAD="$BF_TBB_LIB_NAME" /bin/true 2>&1 >/dev/null)
BF_TBB_LIB_PATH=$(echo "$BF_TBB_LD_OUTPUT" |
grep "calling init:" |
grep "$BF_TBB_LIB_NAME" |
(sed -n "s/.*calling init: \([^[:space:]]\+\).*\/$BF_TBB_LIB_NAME$/\1/p" 2>/dev/null))
fi
if [ -n "$BF_TBB_LIB_PATH" ]; then
# If the library exists, compare its version to the one we bundle.
BF_TBB_SYSTEM_NAME=$(readlink $BF_TBB_LIB_PATH/$BF_TBB_LIB_NAME)
BF_TBB_BUNDLED_NAME=$(readlink $BF_DIST_BIN/lib/$BF_TBB_LIB_NAME)
if [ -n "$BF_TBB_SYSTEM_NAME" ] && [ -n "$BF_TBB_BUNDLED_NAME" ]; then
BF_TBB_SYSTEM_NAME=$(basename $BF_TBB_SYSTEM_NAME)
BF_TBB_BUNDLED_NAME=$(basename $BF_TBB_BUNDLED_NAME)
BF_TBB_NEWEST_NAME=$(printf "%s\n%s\n" "$BF_TBB_SYSTEM_NAME" "$BF_TBB_BUNDLED_NAME" |
(sort -V 2>/dev/null) |
(tail -n 1 2>/dev/null))
# If the system TBB version is newer, preload it.
if [ "$BF_TBB_SYSTEM_NAME" = "$BF_TBB_NEWEST_NAME" ]; then
BLENDER_RESTORE_LD_PRELOAD=${LD_PRELOAD}
LD_PRELOAD=$BF_TBB_LIB_PATH/$BF_TBB_LIB_NAME:${LD_PRELOAD}
export BLENDER_RESTORE_LD_PRELOAD
export LD_PRELOAD
fi
fi
fi
# Add own lib folder first, because Steam or other environments may set an
# $LD_LIBRARY_PATH that has priority over the run-path in the Blender executable,
# but contains incompatible libraries.
LD_LIBRARY_PATH=${BF_DIST_BIN}/lib:${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
exec "$BF_DIST_BIN/$BF_PROGRAM" "$@"