Last active
September 23, 2026 20:31
-
-
Save martpie/2b5e108f0d173c85bcbb84843d93c839 to your computer and use it in GitHub Desktop.
Build gamescope from source for Pop!_OS 24.04 (COSMIC)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Build gamescope on Pop!_OS / Ubuntu 24.04. | |
| # 24.04's libdrm, libxkbcommon and pixman are too old for gamescope's | |
| # bundled wlroots, so we build newer copies into a private prefix | |
| # (/opt/gamescope) without touching the system libraries. | |
| set -euo pipefail | |
| # To update: bump GAMESCOPE_TAG (or any dep tag below) and re-run the script. | |
| # Existing checkouts are moved to the new tag, submodules included. | |
| GAMESCOPE_TAG=3.16.29 | |
| LIBDRM_TAG=libdrm-2.4.129 # wlroots 0.20 needs >= 2.4.129 (24.04 has 2.4.125) | |
| LIBXKBCOMMON_TAG=xkbcommon-1.12.3 # 24.04 has 1.6; 1.13+ needs a newer meson than 24.04's | |
| PIXMAN_TAG=pixman-0.46.4 # wlroots needs >= 0.43 (24.04 has 0.42) | |
| # libwayland and wayland-protocols always use their latest release (see below). | |
| PREFIX=/opt/gamescope | |
| SRC="$PWD" # everything is cloned/built in the folder you run the script from | |
| LIBDIR="$PREFIX/lib/x86_64-linux-gnu" | |
| # 1. Build tools + system deps that are new enough on 24.04 | |
| sudo apt install -y build-essential git meson ninja-build cmake pkg-config glslang-tools \ | |
| libxml2-dev libexpat1-dev libffi-dev \ | |
| libx11-dev libxdamage-dev libxcomposite-dev libxcursor-dev libxxf86vm-dev libxtst-dev \ | |
| libxres-dev libxmu-dev libxkbcommon-dev libvulkan-dev libsdl2-dev libdecor-0-dev \ | |
| libpipewire-0.3-dev libcap-dev libseat-dev libinput-dev libudev-dev libdisplay-info-dev \ | |
| libluajit-5.1-dev libavif-dev libbenchmark-dev libgbm-dev libegl-dev \ | |
| libxcb-composite0-dev libxcb-icccm4-dev libxcb-res0-dev libxcb-ewmh-dev wayland-protocols \ | |
| libxfixes-dev libxext-dev libxi-dev libxrender-dev libxrandr-dev libeis-dev \ | |
| xwayland hwdata libpciaccess-dev bison libxcb-xkb-dev patchelf file libx11-xcb-dev liblcms2-dev | |
| sudo mkdir -p "$PREFIX" && sudo chown "$USER" "$PREFIX" | |
| mkdir -p "$SRC" && cd "$SRC" | |
| export PKG_CONFIG_PATH="$LIBDIR/pkgconfig:$PREFIX/share/pkgconfig" | |
| export PATH="$PREFIX/bin:$PATH" | |
| export LDFLAGS="-Wl,-rpath,$LIBDIR" # binaries find our libs (see step 4 for Steam) | |
| # Clone repo, or move an existing checkout to the requested tag. | |
| sync_repo() { # dir git-url tag | |
| local dir=$1 url=$2 tag=$3 | |
| if [ ! -d "$dir/.git" ]; then | |
| git clone --recursive -b "$tag" "$url" "$dir" | |
| else | |
| git -C "$dir" fetch --tags --force origin | |
| git -C "$dir" checkout --force "refs/tags/$tag" | |
| git -C "$dir" submodule sync --recursive | |
| git -C "$dir" submodule update --init --recursive --force | |
| fi | |
| } | |
| build_dep() { # name git-url tag [meson options...] | |
| local name=$1 url=$2 tag=$3; shift 3 | |
| sync_repo "$name" "$url" "$tag" | |
| meson setup "$name/build" "$name" --prefix="$PREFIX" --libdir=lib/x86_64-linux-gnu \ | |
| --buildtype=release --wipe "$@" 2>/dev/null || \ | |
| meson setup "$name/build" "$name" --prefix="$PREFIX" --libdir=lib/x86_64-linux-gnu \ | |
| --buildtype=release "$@" | |
| ninja -C "$name/build" | |
| meson install -C "$name/build" | |
| } | |
| # 2. Newer libwayland, wayland-protocols, libdrm, libxkbcommon and pixman into /opt/gamescope | |
| # libwayland: latest release. Its wayland-scanner is needed to build the latest | |
| # wayland-protocols (older scanners reject the new "frozen" attribute). | |
| latest_tag() { git ls-remote --tags --refs "$1" | grep -oE "$2" | grep -vE "\.9[0-9]$" | sort -V | tail -1; } # skip x.y.9x pre-releases | |
| WL_URL=https://gitlab.freedesktop.org/wayland/wayland.git | |
| build_dep wayland "$WL_URL" "$(latest_tag "$WL_URL" '[0-9]+\.[0-9]+\.[0-9]+$')" \ | |
| -Ddocumentation=false -Dtests=false | |
| # wlroots 0.20 needs a newer wayland-protocols than 24.04's 1.45: use the latest release tag | |
| WLP_URL=https://gitlab.freedesktop.org/wayland/wayland-protocols.git | |
| build_dep wayland-protocols "$WLP_URL" "$(latest_tag "$WLP_URL" '[0-9]+\.[0-9]+$')" -Dtests=false | |
| build_dep libdrm https://gitlab.freedesktop.org/mesa/drm.git "$LIBDRM_TAG" \ | |
| -Dtests=false -Dman-pages=disabled -Dvalgrind=disabled -Dcairo-tests=disabled | |
| build_dep libxkbcommon https://github.com/xkbcommon/libxkbcommon.git "$LIBXKBCOMMON_TAG" \ | |
| -Denable-docs=false -Denable-wayland=false -Denable-tools=false -Denable-bash-completion=false \ | |
| -Dxkb-config-root=/usr/share/X11/xkb -Dx-locale-root=/usr/share/X11/locale | |
| build_dep pixman https://gitlab.freedesktop.org/pixman/pixman.git "$PIXMAN_TAG" \ | |
| -Dtests=disabled -Ddemos=disabled -Dgtk=disabled | |
| # 3. gamescope itself (wlroots, libliftoff, vkroots... come as bundled subprojects) | |
| sync_repo gamescope https://github.com/ValveSoftware/gamescope.git "$GAMESCOPE_TAG" | |
| cd gamescope | |
| meson setup build --prefix="$PREFIX" --buildtype=release -Denable_tests=false --wipe 2>/dev/null || \ | |
| meson setup build --prefix="$PREFIX" --buildtype=release -Denable_tests=false | |
| ninja -C build | |
| meson install -C build --skip-subprojects | |
| # 4. Force a DT_RPATH on gamescope's binaries. Unlike RUNPATH, RPATH wins over | |
| # LD_LIBRARY_PATH, so Steam's library path can't make gamescope load 24.04's | |
| # old libwayland (-> "undefined symbol: wl_resource_post_error_vargs"). | |
| for bin in "$PREFIX"/bin/gamescope*; do | |
| if file -b "$bin" | grep -q ELF; then | |
| patchelf --force-rpath --set-rpath "$LIBDIR" "$bin" | |
| fi | |
| done | |
| readelf -d "$PREFIX/bin/gamescope" | grep -E 'RPATH|RUNPATH' | |
| # 5. Put gamescope's binaries on PATH (gamescope launches helpers like | |
| # gamescopereaper by name, so they all need to be on PATH, not just gamescope). | |
| # Only gamescope* is linked; our private wayland-scanner etc. stay in /opt. | |
| for bin in "$PREFIX"/bin/gamescope*; do | |
| sudo ln -sf "$bin" "/usr/local/bin/$(basename "$bin")" | |
| done | |
| gamescope --version | |
| echo "Done. Uninstall with: bash uninstall-gamescope.sh" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| sudo apt install vulkan-tools | |
| gamescope -W 2560 -H 1440 -r 120 -- vkcube |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Uninstall gamescope built with build-gamescope.sh (Pop!_OS 24.04, COSMIC). | |
| # Everything was installed into /opt/gamescope + /usr/local/bin/gamescope* symlinks, so nothing | |
| # else on the system is touched. | |
| # | |
| # Usage: | |
| # bash uninstall-gamescope.sh # remove the installed gamescope | |
| # bash uninstall-gamescope.sh --sources # also delete the cloned sources in the current folder | |
| set -euo pipefail | |
| PREFIX=/opt/gamescope | |
| # Remove /usr/local/bin/gamescope* links, only if they point into our prefix | |
| for link in /usr/local/bin/gamescope*; do | |
| if [ -L "$link" ] && [[ "$(readlink "$link")" == "$PREFIX"/* ]]; then | |
| sudo rm -f "$link" | |
| echo "Removed $link" | |
| fi | |
| done | |
| if [ -d "$PREFIX" ]; then | |
| sudo rm -rf "$PREFIX" | |
| echo "Removed $PREFIX" | |
| fi | |
| if [ "${1:-}" = "--sources" ]; then | |
| for d in gamescope wayland wayland-protocols libdrm libxkbcommon pixman; do | |
| [ -d "$d" ] && rm -rf "$d" && echo "Removed ./$d" | |
| done | |
| fi | |
| hash -r | |
| if command -v gamescope >/dev/null; then | |
| echo "Note: another gamescope is still on PATH: $(command -v gamescope)" | |
| else | |
| echo "gamescope uninstalled." | |
| fi | |
| # The apt build dependencies are left installed (other software may use them). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment