Skip to content

Instantly share code, notes, and snippets.

@shmerl
Last active November 29, 2025 23:37
Show Gist options
  • Select an option

  • Save shmerl/f4e5f76871239158cf083e37c5da56f4 to your computer and use it in GitHub Desktop.

Select an option

Save shmerl/f4e5f76871239158cf083e37c5da56f4 to your computer and use it in GitHub Desktop.
For building Mesa on Debian
#!/bin/bash
# Notes:
#
# 1. Works for tags and specific hash commits too (override mesa_branch variable with needed value).
#
# 2. By default builds for /opt/mesa-<branch> and places the result in ${HOME}/mnt/vmshare/mesa-<branch>
# You can override the build deployment location by setting dest_dir. For example this should put it right away
# in /opt/mesa-<branch>
#
# dest_dir=/ mesa_debian_build.sh
#
# 3. You can override the Mesa repo and resulting Mesa directory name. For instance, to build Mesa with ray tracing fixes
# (that development repo is picked just as an example):
#
# mesa_repo='https://gitlab.freedesktop.org/bnieuwenhuizen/mesa.git' mesa_branch='stable-rt-handles' mesa_dir='/opt/mesa-rt' mesa_debian_build.sh
#
# 4. Make sure deb-src section is configured for your Debian distro in your apt sources. That's needed to install build development packages.
#
# 5. If you aren't using Debian testing, set your debian_release to what you need (like "unstable").
#
debian_release=${debian_release:-"testing"} # Debian release (archive/suite), i.e. "testing", "unstable" etc.
mesa_branch=${mesa_branch:-"main"}
mesa_repo=${mesa_repo:-"https://gitlab.freedesktop.org/mesa/mesa.git"}
base_dir=${base_dir:-"${HOME}/build/mesa"}
src_dir=${src_dir:-"${base_dir}/source"}
build_dir=${build_dir:-"${base_dir}/build"}
patches_dir=${patches_dir:-"${base_dir}/patches"}
cpuarch=${cpuarch:-"znver4"} # Zen 4 by default. Change to your arch or "native" accordingly.
build_debug=${build_debug:-false}
verbose=${verbose:-false}
update_sources=${update_sources:-true}
reset_sources=${reset_sources:-true}
apply_patches=${apply_patches:-true}
if [[ "$mesa_branch" != "mesa"* ]]; then
mesa_dir=${mesa_dir:-"/opt/mesa-${mesa_branch}"}
else
mesa_dir=${mesa_dir:-"/opt/${mesa_branch}"}
fi
dest_dir=${dest_dir:-"${HOME}/mnt/vmshare/$(basename ${mesa_dir})"}
arch_dir="x86_64"
function assert() {
rc=$1
message="$2"
if ((rc != 0)); then
echo $message
exit $rc
fi
}
function ensure() {
local rc=1
while (($rc != 0)); do
$@
rc=$?
if (($rc != 0)); then
sleep 1
fi
done
}
function setup_sources() {
echo "=== Setting up sources ===="
mkdir -p "$base_dir"
mkdir -p "$dest_dir"
rm -rfv ${dest_dir}/${mesa_dir}/*
ensure sudo apt install build-essential git
# Potential clean up of previously created repo directory due to repo URL mismatch.
if [[ -e "$src_dir" ]]; then
cd "$src_dir"
local prev_mesa_repo=$(git config --get remote.origin.url)
if [[ "$prev_mesa_repo" != "$mesa_repo" ]]; then
cd $(dirname "$src_dir")
rm -rfv $(basename "$src_dir")
fi
fi
cd $(dirname "$src_dir")
if ! [[ -e "$src_dir" ]]; then
git clone "$mesa_repo" $(basename "$src_dir")
fi
cd "$src_dir"
# If updating, reset is enforced regardless of the $reset_sources, to avoid possible merging confusion.
if $reset_sources || $update_sources; then
git reset --hard HEAD
git clean -df
fi
if $update_sources; then
git checkout main
git pull --rebase --prune
git checkout $mesa_branch
if (($? != 0)); then
echo "Invalid branch or tag ${mesa_branch}! Aborting"
exit 2
fi
fi
if $apply_patches; then
mkdir -p "$patches_dir"
for patch in ${patches_dir}/*; do
patch -p 1 < ${patch}
assert $? "Failed to apply patch ${patch}"
done
fi
mkdir -p "$build_dir"
rm -rfv ${build_dir}/*
}
function setup_packages() {
echo "=== Setting up packages for the build ===="
ensure sudo apt --target-release $debian_release build-dep mesa
}
configure() {
echo "==== Configuring build ===="
cd "$build_dir"
local build_type='plain'
local debug_flags=''
local ndebug=true
local strip_option='--strip'
if $build_debug; then
build_type='debug'
debug_flags='-g'
ndebug=false
strip_option=''
fi
export CFLAGS="-march=${cpuarch} ${debug_flags} -O2 -ffile-prefix-map=${HOME}/build=. -fstack-protector-strong -Wformat -Werror=format-security -Wall"
export CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2"
export CXXFLAGS="-march=${cpuarch} ${debug_flags} -O2 -ffile-prefix-map=${HOME}/build=. -fstack-protector-strong -Wformat -Werror=format-security -Wall"
export LDFLAGS="-Wl,-z,relro"
LC_ALL=C.UTF-8 meson setup "$src_dir" \
--wrap-mode=nodownload \
--buildtype=$build_type \
$strip_option \
--prefix="$mesa_dir" \
--sysconfdir=/etc \
--localstatedir=/var \
--libdir="$arch_dir" \
-D dri-drivers-path="${mesa_dir}/${arch_dir}" \
-D platforms="['x11','wayland']" \
-D vulkan-drivers="['amd']" \
-D vulkan-layers="['device-select','overlay']" \
-D glvnd=enabled \
-D b_ndebug=$ndebug \
-D glx-direct=true \
-D gbm=enabled \
-D gallium-extra-hud=true \
-D lmsensors=enabled \
-D llvm=disabled \
-D gallium-va=enabled \
-D va-libs-path="$arch_dir" \
-D video-codecs=all \
-D gallium-drivers="['radeonsi','zink']" \
-D gles1=disabled \
-D gles2=enabled \
-D sse2=true \
-D teflon=false
assert $? "Configure failed!"
}
function build() {
echo "==== Building... ===="
cd "$build_dir"
if $verbose; then
LC_ALL=C.UTF-8 ninja -v
else
LC_ALL=C.UTF-8 ninja
fi
assert $? "build failed!"
}
function publish() {
cd "$build_dir"
DESTDIR="$dest_dir" LC_ALL=C.UTF-8 ninja install
}
function clean() {
ensure sudo apt autoremove --purge
}
################################################
shopt -s nullglob
setup_sources
setup_packages
configure
build
publish
clean
@Unterstrichmoepunterstrich

Hello @shmerl ,

I tried today to run this script on my debian buster VM to build Mesa 20.0.7 and I have some trouble to run it, because I the script have some problems with libclang-11-dev and llvm-11-dev, I also tried version 7, which is the default version on Debian Buster
Whats the correct version or is there some other problem?
It's also not a problem to build it on sid, but I don't know, if Mesa 20.0.7 is working on Debian Buster.

The script crashed btw at this lines:

if $apply_patches; then
mkdir -p "$patches_dir"
for patch in ${patches_dir}/*; do
patch -p 1 < ${patch}
assert $? "Failed to apply patch ${patch}"
done
fi

because in the patch directory was empty.

@shmerl
Copy link
Author

shmerl commented Jun 2, 2020

I didn't try using it with stable (running it on testing usually). In order to use llvm 11, you might need the llvm repo, see note #4:

# 4. To use latest llvm snapshot, make sure to configure llvm respository for Debian.
#    For example, create the following apt list: /etc/apt/sources.list.d/llvm.list
#
# deb http://apt.llvm.org/unstable/ llvm-toolchain main
# deb-src http://apt.llvm.org/unstable/ llvm-toolchain main

Also, see this bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2843
Mesa developers still didn't fix it.

@shmerl
Copy link
Author

shmerl commented Jun 2, 2020

Fixed the empty directory issue, please test.

@Unterstrichmoepunterstrich

Fixed the empty directory issue, please test.

where is the fixed code? In another gist? I would like to test, if the problem is solved.
I'm now on Debian bullseye and I can compile the it.
Can you put this script under an official open source licence? I would like to contribute some improvements, for example when you don't use deb-src from bullyseye, yo get an endless loop.

@shmerl
Copy link
Author

shmerl commented Jun 12, 2020

Same gist.

Good point on the need to use deb-src, I have it. I'll add a comment about it to make it more obvious.

@Unterstrichmoepunterstrich

great it's working

@shmerl
Copy link
Author

shmerl commented Oct 9, 2025

Removed obsolete 32-bit build path

@shmerl
Copy link
Author

shmerl commented Nov 12, 2025

Removed llvm usage, it's not needed for any AMD drivers anymore they can work with ACO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment