Skip to content

Instantly share code, notes, and snippets.

@shmerl
Last active September 15, 2024 01:08
Show Gist options
  • Save shmerl/f4e5f76871239158cf083e37c5da56f4 to your computer and use it in GitHub Desktop.
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. 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
#
# Sometimes you might want to enable Debian experimental repo for specific version of llvm that's older than latest snapshot, but newer
# than ones in other Debian repos.
#
# 5. Make sure deb-src section is configured for your Debian distro in your apt sources. That's needed to install build development packages.
#
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"}
use_llvm=${use_llvm:-true}
llvm_ver=${llvm_ver:-"20"}
cpuarch=${cpuarch:-"znver4"} # Zen 4 by default. Change to your arch or "native" accordingly.
build_32=${build_32:-false} # Don't build 32-bit by default - needs fixing to work
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["32"]="x86"
arch_dir["64"]="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 common_prepare() {
echo "=== Common setup ===="
mkdir -p ${dest_dir}
rm -rfv ${dest_dir}/${mesa_dir}/*
ensure sudo apt-get 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 prepare_64() {
echo "=== Preparing 64-bit build ===="
ensure sudo apt-get build-dep mesa
if $use_llvm; then
ensure sudo apt-get install llvm-${llvm_ver}-dev libclang-${llvm_ver}-dev libpolly-${llvm_ver}-dev
fi
}
function prepare_32() {
echo "==== Preparing 32-bit build ===="
# TODO: all this needs a working method in Debian
echo "Not supported now"
return
ensure sudo apt-get install llvm-${llvm_ver}-dev:i386 libclang-${llvm_ver}-dev:i386 gcc-multilib g++-multilib libdrm-dev:i386 libexpat1-dev:i386 libxcb-dri3-dev:i386 libxcb-present-dev:i386 libxshmfence-dev:i386 libxext-dev:i386 libxdamage-dev:i386 libx11-xcb-dev:i386 libxcb-glx0-dev:i386 libxcb-dri2-0-dev:i386 libxxf86vm-dev:i386 libwayland-dev:i386 libsensors4-dev:i386 libelf-dev:i386 zlib1g-dev:i386 libglvnd-core-dev:i386
}
configure_64() {
echo "==== Configuring 64-bit 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
local llvm_val='disabled'
if $use_llvm; then
llvm_val='enabled'
fi
local native_config
read -r -d '' native_config <<EOF
[binaries]
llvm-config = '/usr/bin/llvm-config-${llvm_ver}'
cmake = '/usr/bin/false'
EOF
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 \
--native-file=<(echo "$native_config") \
--prefix="$mesa_dir" \
--sysconfdir=/etc \
--localstatedir=/var \
--libdir="${arch_dir["64"]}" \
-D dri-drivers-path="${arch_dir["64"]}" \
-D platforms="['x11','wayland']" \
-D vulkan-drivers="['amd']" \
-D vulkan-layers="['device-select','overlay']" \
-D glvnd=enabled \
-D shared-glapi=enabled \
-D b_ndebug=$ndebug \
-D glx-direct=true \
-D gbm=enabled \
-D gallium-extra-hud=true \
-D gallium-vdpau=disabled \
-D lmsensors=enabled \
-D llvm=$llvm_val \
-D shared-llvm=disabled \
-D gallium-va=enabled \
-D va-libs-path="${arch_dir["64"]}" \
-D video-codecs=all \
-D gallium-drivers="['radeonsi','zink']" \
-D gles1=disabled \
-D gles2=enabled \
-D sse2=true \
-D teflon=false
assert $? "Configure failed!"
}
configure_32() {
echo "==== Configuring 32-bit ===="
echo "Not supported now"
return
}
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_64() {
if $use_llvm; then
ensure sudo apt-get purge llvm-${llvm_ver}-dev libclang-${llvm_ver}-dev libpolly-${llvm_ver}-dev
fi
ensure sudo apt-get autoremove --purge
}
function clean_32() {
ensure sudo apt-get purge llvm-${llvm_ver}-dev:i386 libclang-${llvm_ver}-dev:i386 libsensors4-dev:i386
ensure sudo apt-get autoremove --purge
}
################################################
shopt -s nullglob
common_prepare
prepare_64
configure_64
build
publish
clean_64
if ! $build_32; then
exit
fi
prepare_32
configure_32
build
publish
clean_32
@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

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