diff --git a/README.md b/README.md
index 2e3fd645b..750c0796c 100644
--- a/README.md
+++ b/README.md
@@ -169,6 +169,11 @@ Fedora package names:
alsa-lib-devel autoconf automake brotli-devel clang cmake dbus-devel egl-wayland-devel extra-cmake-modules fontconfig-devel gcc-c++ gtk3-devel libavcodec-free-devel libavformat-free-devel libavutil-free-devel libcurl-devel libdecor-devel libevdev-devel libICE-devel libinput-devel libSM-devel libswresample-free-devel libswscale-free-devel libX11-devel libXau-devel libxcb-devel libXcomposite-devel libXcursor-devel libXext-devel libXfixes-devel libXft-devel libXi-devel libxkbcommon-devel libxkbcommon-x11-devel libXpresent-devel libXrandr-devel libXrender-devel libtool lld llvm make mesa-libEGL-devel mesa-libGL-devel nasm ninja-build openssl-devel patch pcre2-devel perl-Digest-SHA pipewire-devel pulseaudio-libs-devel systemd-devel wayland-devel xcb-util-cursor-devel xcb-util-devel xcb-util-errors-devel xcb-util-image-devel xcb-util-keysyms-devel xcb-util-renderutil-devel xcb-util-wm-devel xcb-util-xrm-devel zlib-devel
```
+Arch package names:
+```
+base-devel clang cmake curl dbus extra-cmake-modules freetype git libjpeg-turbo libpng libwebp libx11 libxrandr lld llvm ninja qt6-base qt6-imageformats qt6-svg qt6-tools wayland zstd
+```
+
#### Building
1. Clone the repository: `git clone https://github.com/stenzek/duckstation.git`, `cd duckstation`.
diff --git a/data/resources/thirdparty.html b/data/resources/thirdparty.html
index 6e22f1d1a..1411c2605 100644
--- a/data/resources/thirdparty.html
+++ b/data/resources/thirdparty.html
@@ -2472,8 +2472,6 @@ SOFTWARE.
Some shaders provided with the application are sourced from:
License details are included in the relevant shader source files, under resources\shaders\reshade.
diff --git a/scripts/packaging/arch/PKGBUILD b/scripts/packaging/arch/PKGBUILD
new file mode 100644
index 000000000..5075725b7
--- /dev/null
+++ b/scripts/packaging/arch/PKGBUILD
@@ -0,0 +1,128 @@
+# SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin
+# SPDX-License-Identifier: CC-BY-NC-ND-4.0
+
+# NOTE: These package files are intended for your own personal/private use.
+# You do not have permission to upload them to other package repositories.
+
+pkgname=duckstation
+pkgver=0
+pkgrel=1
+pkgdesc='PlayStation 1, aka. PSX Emulator'
+arch=('x86_64' 'aarch64')
+url='https://www.duckstation.org/'
+license=('CC-BY-NC-ND-4.0')
+
+# We want to keep debug symbols for backtraces.
+# Our cmake build already generates symbols.
+options=('!strip' '!debug')
+
+# User-selectable dependencies (as .so), and packages.
+depends=('libjpeg.so' # libjpeg or libjpeg-turbo
+ 'libudev.so'
+ 'curl'
+ 'dbus'
+ 'freetype2'
+ 'hicolor-icon-theme'
+ 'libpng'
+ 'libwebp'
+ 'libx11'
+ 'libxrandr'
+ 'qt6-base'
+ 'qt6-imageformats'
+ 'qt6-svg'
+ 'wayland'
+ 'zlib'
+ 'zstd'
+)
+
+# qttools only needed for building (moc/uic/rcc/lupdate)
+# Same with the compilers.
+makedepends=('base-devel'
+ 'clang'
+ 'cmake'
+ 'extra-cmake-modules'
+ 'git'
+ 'lld'
+ 'llvm'
+ 'ninja'
+ 'qt6-tools')
+
+source=(
+ "${pkgname}::git+file://${startdir}/../../.."
+)
+sha256sums=(
+ "SKIP"
+)
+
+# Name of the .desktop file that will be installed.
+_desktopname=org.duckstation.DuckStation
+
+# https://wiki.archlinux.org/title/VCS_package_guidelines#Git
+# --dirty omitted, we need to ignore changes to this script because
+# makepkg is fricking weird and edits the build recipe, instead of
+# just setting in the resulting file?!
+pkgver() {
+ cd "$pkgname"
+ git describe | sed 's/\([^-]*-g\)/r\1/;s/-/./g'
+}
+
+prepare() {
+ cd "${pkgname}"
+
+ # Are we creating a CI/official build?
+ if [[ ! -z "$SCM_RELEASE_TAG" ]]; then
+ echo "Tagging as ${SCM_RELEASE_TAG} build."
+ echo "#pragma once" > src/scmversion/tag.h
+ echo "#define SCM_RELEASE_TAG ${SCM_RELEASE_TAG}" \
+ >> src/scmversion/tag.h
+ fi
+
+ # build dependencies
+ if [[ ! -z "$DEPSDIR" ]]; then
+ _depsdir="$DEPSDIR"
+ echo "Using existing dependencies from ${_depsdir}."
+ else
+ _depsdir="$PWD/deps"
+ echo "Building dependencies to ${_depsdir}..."
+ ./scripts/deps/build-dependencies-linux.sh \
+ -system-freetype -system-harfbuzz -system-libjpeg \
+ -system-libpng -system-libwebp -system-zstd -system-qt \
+ "${_depsdir}"
+ fi
+}
+
+build() {
+ cd "${pkgname}"
+
+ rm -fr build-arch
+ cmake -B build-arch \
+ -G Ninja \
+ -DCMAKE_C_COMPILER=clang \
+ -DCMAKE_CXX_COMPILER=clang++ \
+ -DCMAKE_EXE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
+ -DCMAKE_MODULE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
+ -DCMAKE_SHARED_LINKER_FLAGS_INIT="-fuse-ld=lld" \
+ -DCMAKE_PREFIX_PATH="${_depsdir}" \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
+ -DALLOW_INSTALL=ON \
+ -DINSTALL_SELF_CONTAINED=ON \
+ -DCMAKE_INSTALL_PREFIX="${pkgdir}/opt/duckstation"
+ ninja -C build-arch
+}
+
+package() {
+ cd "${pkgname}"
+ ninja -C build-arch install
+
+ # install wrapper script
+ install -Dm755 scripts/packaging/duckstation-qt "${pkgdir}/usr/bin/duckstation-qt"
+
+ # install desktop file and icon
+ install -Dm644 scripts/${_desktopname}.desktop "${pkgdir}/usr/share/applications/${_desktopname}.desktop"
+ install -Dm644 scripts/${_desktopname}.png "${pkgdir}/usr/share/icons/hicolor/512x512/apps/${_desktopname}.png"
+
+ # install license
+ install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
+}
+
diff --git a/scripts/packaging/duckstation-qt b/scripts/packaging/duckstation-qt
new file mode 100755
index 000000000..4ef675ff9
--- /dev/null
+++ b/scripts/packaging/duckstation-qt
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if [[ -z "$I_WANT_A_BROKEN_WAYLAND_UI" ]]; then
+ echo "Forcing X11 instead of Wayland, due to various protocol limitations"
+ echo "and Qt issues. If you want to use Wayland, launch DuckStation with"
+ echo "I_WANT_A_BROKEN_WAYLAND_UI=YES set."
+ export QT_QPA_PLATFORM=xcb
+else
+ echo "Wayland is not being disabled. Do not complain when things break."
+fi
+
+exec /opt/duckstation/duckstation-qt "$@"
+
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index 085dcef60..b08fdef04 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -313,6 +313,7 @@ function(add_util_resources target)
set_target_properties(${target} PROPERTIES INSTALL_RPATH "$ORIGIN")
# Copy dependency libraries to installation directory.
+ install_imported_dep_library(SDL2::SDL2)
install_imported_dep_library(Shaderc::shaderc_shared)
install_imported_dep_library(spirv-cross-c-shared)
install_imported_dep_library(SoundTouch::SoundTouchDLL)