Xlibre build script updated.

This commit is contained in:
Storm Dragon
2026-06-21 16:21:37 -04:00
parent 4aeff109f7
commit 426069f36a
2 changed files with 325 additions and 28 deletions
+325
View File
@@ -0,0 +1,325 @@
#!/usr/bin/env bash
set -euo pipefail
repoUrl="https://github.com/X11Libre/pkgbuilds-arch-based.git"
rootfsUrl="http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz"
aarch64Packages=(
xlibre-xserver
xlibre-input-libinput
xlibre-video-fbdev
xlibre-video-amdgpu
xlibre-video-ati
xlibre-video-nouveau
)
outputDir=$(pwd -P)
workDir=""
chrootDir=""
binfmtMounted=false
binfmtRegistered=false
log() {
printf '%s %s\n' "$*" "$(date '+%Y-%m-%d %H:%M:%S')"
}
die() {
printf 'Error: %s\n' "$*" >&2
exit 1
}
cleanup() {
local exitStatus=$?
local cleanupFailed=false
local mountTarget
local chrootMounts=()
trap - EXIT INT TERM
if [[ -n "$workDir" && -d "$workDir" ]]; then
log "Removing temporary chroot"
if [[ -n "$chrootDir" ]]; then
mapfile -t chrootMounts < <(
findmnt -rn -o TARGET |
awk -v root="$chrootDir" '$0 == root || index($0, root "/") == 1' |
sort -r
)
fi
for mountTarget in "${chrootMounts[@]}"; do
if ! mountpoint -q "$mountTarget"; then
continue
fi
if ! umount --recursive "$mountTarget"; then
printf 'Warning: normal chroot unmount failed; detaching it lazily\n' >&2
umount --recursive --lazy "$mountTarget" || cleanupFailed=true
fi
done
rm -rf --one-file-system "$workDir" || cleanupFailed=true
if [[ -e "$workDir" ]]; then
printf 'Error: failed to remove temporary chroot: %s\n' "$workDir" >&2
cleanupFailed=true
fi
fi
if [[ "$binfmtRegistered" == true && -e /proc/sys/fs/binfmt_misc/qemu-aarch64 ]]; then
printf '%s' -1 > /proc/sys/fs/binfmt_misc/qemu-aarch64 || cleanupFailed=true
fi
if [[ "$binfmtMounted" == true ]]; then
umount /proc/sys/fs/binfmt_misc || cleanupFailed=true
fi
if [[ "$cleanupFailed" == true && "$exitStatus" -eq 0 ]]; then
exitStatus=1
fi
exit "$exitStatus"
}
require_commands() {
local commandName
local missingCommands=()
for commandName in arch-chroot awk bsdtar chown cp curl date findmnt grep install mkdir mktemp mount mountpoint rm sort tr umount; do
if ! command -v "$commandName" >/dev/null 2>&1; then
missingCommands+=("$commandName")
fi
done
if ((${#missingCommands[@]})); then
die "Missing required commands: ${missingCommands[*]}"
fi
[[ -x /usr/bin/qemu-aarch64-static ]] || die "/usr/bin/qemu-aarch64-static is required"
[[ -r /usr/lib/binfmt.d/qemu-aarch64-static.conf ]] || die "The qemu-user-static-binfmt package is required"
}
configure_binfmt() {
if ! mountpoint -q /proc/sys/fs/binfmt_misc; then
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
binfmtMounted=true
fi
if [[ ! -e /proc/sys/fs/binfmt_misc/qemu-aarch64 ]]; then
tr -d '\n' < /usr/lib/binfmt.d/qemu-aarch64-static.conf > /proc/sys/fs/binfmt_misc/register
binfmtRegistered=true
fi
grep -qx 'enabled' /proc/sys/fs/binfmt_misc/qemu-aarch64 || die "aarch64 binfmt registration is not enabled"
}
create_build_script() {
local buildScript=$1
install -m 0755 /dev/stdin "$buildScript" <<'CHROOT_SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
repoUrl=$1
shift
packages=("$@")
repoDir=/build/pkgbuilds
log() {
printf '%s %s\n' "$*" "$(date '+%Y-%m-%d %H:%M:%S')"
}
install_dependencies() {
local packageDir=$1
local dependency
local outputPackage
local srcInfo
local dependencies=()
local filteredDependencies=()
local missingDependencies=()
local outputPackages=()
local -A internalPackages=()
# $1 is expanded by the nested builder shell, not this root shell.
# shellcheck disable=SC2016
srcInfo=$(runuser -u builder -- bash -c \
'cd "$1" && makepkg --printsrcinfo' _ "$packageDir")
mapfile -t outputPackages < <(
printf '%s\n' "$srcInfo" |
awk -F ' = ' '/^[[:space:]]*pkgname = / { print $2 }'
)
for outputPackage in "${outputPackages[@]}"; do
internalPackages["$outputPackage"]=1
done
mapfile -t dependencies < <(
printf '%s\n' "$srcInfo" |
awk -F ' = ' '
/^[[:space:]]*(depends|makedepends|checkdepends)(_aarch64)? = / {
dependency=$2
sub(/[<>=].*/, "", dependency)
print dependency
}
' |
sort -u
)
for dependency in "${dependencies[@]}"; do
if [[ -z ${internalPackages[$dependency]+present} ]]; then
filteredDependencies+=("$dependency")
fi
done
((${#filteredDependencies[@]})) || return 0
mapfile -t missingDependencies < <(pacman -T "${filteredDependencies[@]}" || true)
((${#missingDependencies[@]})) || return 0
log "Installing dependencies for ${packageDir##*/}"
pacman -S --asdeps --needed --noconfirm "${missingDependencies[@]}"
}
remove_installed_packages() {
local packageName
local installedPackages=()
for packageName in "$@"; do
if pacman -Q "$packageName" >/dev/null 2>&1; then
installedPackages+=("$packageName")
fi
done
((${#installedPackages[@]})) || return 0
log "Removing conflicting packages: ${installedPackages[*]}"
pacman -Rdd --noconfirm "${installedPackages[@]}"
}
build_package() {
local packageName=$1
local installAfterBuild=${2:-false}
local packageDir="$repoDir/$packageName"
local builtPackages=()
[[ -f "$packageDir/PKGBUILD" ]] || {
printf 'Missing PKGBUILD for %s\n' "$packageName" >&2
return 1
}
log "Building $packageName"
install_dependencies "$packageDir"
# $1 is expanded by the nested builder shell, not this root shell.
# shellcheck disable=SC2016
runuser -u builder -- bash -c \
'cd "$1" && makepkg --noconfirm --clean --cleanbuild' _ "$packageDir"
mapfile -d '' builtPackages < <(
find "$packageDir" -maxdepth 1 -type f -name '*.pkg.tar.*' ! -name '*.sig' -print0
)
((${#builtPackages[@]})) || {
printf 'No package artifacts were produced for %s\n' "$packageName" >&2
return 1
}
if [[ "$installAfterBuild" == true ]]; then
case "$packageName" in
xlibre-input-libinput)
remove_installed_packages xf86-input-libinput
;;
xlibre-xserver)
remove_installed_packages \
xorg-server \
xorg-server-common \
xorg-server-devel \
xorg-server-xephyr \
xorg-server-xnest \
xorg-server-xvfb \
glamor-egl \
xf86-video-modesetting
;;
esac
log "Installing $packageName for subsequent builds"
pacman -U --noconfirm "${builtPackages[@]}"
fi
}
log "Initializing Arch Linux ARM"
# Pacman's Landlock sandbox is unavailable through qemu-user emulation.
sed -i \
-e '/^[[:space:]]*DisableSandbox[[:space:]]*$/d' \
-e '/^\[options\][[:space:]]*$/a DisableSandbox' \
/etc/pacman.conf
pacman-key --init
pacman-key --populate archlinuxarm
pacman -Syu --noconfirm
pacman -S --needed --noconfirm base-devel git
useradd --create-home --shell /bin/bash builder
install -d -o builder -g builder /build
log "Cloning XLibre PKGBUILDs"
runuser -u builder -- git clone --depth 1 "$repoUrl" "$repoDir"
# The input driver must first be built against the stock xorg-server-devel.
build_package xlibre-input-libinput true
# Installing all server split packages replaces the stock Xorg server/devel
# packages and provides the ABI dependencies needed by the video drivers.
build_package xlibre-xserver true
for packageName in "${packages[@]}"; do
case "$packageName" in
xlibre-input-libinput|xlibre-xserver)
continue
;;
esac
build_package "$packageName"
done
install -d /output
find "$repoDir" -type f -name '*.pkg.tar.*' ! -name '*.sig' -exec cp -t /output -- {} +
log "All requested aarch64 packages built"
CHROOT_SCRIPT
}
main() {
local rootfsArchive
local packageFile
local copiedPackageCount=0
((EUID == 0)) || die "Run this script as root: sudo $0"
require_commands
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
configure_binfmt
workDir=$(mktemp -d /tmp/xlibre-aarch64.XXXXXX)
chrootDir="$workDir/root"
rootfsArchive="$workDir/ArchLinuxARM-aarch64-latest.tar.gz"
mkdir -p "$chrootDir"
log "Downloading a fresh Arch Linux ARM aarch64 root filesystem"
curl --fail --location --retry 3 --output "$rootfsArchive" "$rootfsUrl"
log "Creating aarch64 chroot"
bsdtar -xpf "$rootfsArchive" -C "$chrootDir"
install -m 0755 /usr/bin/qemu-aarch64-static "$chrootDir/usr/bin/qemu-aarch64-static"
cp --remove-destination /etc/resolv.conf "$chrootDir/etc/resolv.conf"
create_build_script "$chrootDir/root/build-xlibre"
# arch-chroot expects the chroot root to be a mountpoint.
mount --bind "$chrootDir" "$chrootDir"
log "Starting aarch64 package build"
arch-chroot "$chrootDir" /root/build-xlibre "$repoUrl" "${aarch64Packages[@]}"
shopt -s nullglob
for packageFile in "$chrootDir"/output/*.pkg.tar.*; do
[[ ${packageFile##*/} == *-aarch64.pkg.tar.* ]] || die "Unexpected non-aarch64 artifact: ${packageFile##*/}"
install -m 0644 "$packageFile" "$outputDir/"
((copiedPackageCount += 1))
if [[ -n ${SUDO_UID:-} && -n ${SUDO_GID:-} ]]; then
chown "$SUDO_UID:$SUDO_GID" "$outputDir/${packageFile##*/}"
fi
done
shopt -u nullglob
((copiedPackageCount > 0)) || die "No package artifacts were copied to $outputDir"
log "Copied $copiedPackageCount completed packages to $outputDir"
}
main "$@"
-28
View File
@@ -1,28 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
startDir="$(pwd)"
buildDir="${startDir}/xlibre-build"
packageList=(
xlibre-input-libinput
xlibre-xserver
xlibre-video-amdgpu
xlibre-video-ati
xlibre-video-fbdev
xlibre-video-intel
xlibre-video-nouveau
xlibre-video-vesa
xlibre-video-dummy-with-vt
)
mkdir -p "${buildDir}"
for i in "${packageList[@]}" ; do
yay -Ga "$i"
pushd "$i"
makepkg -Acrsf
cp -v ./*.pkg.tar.* "${buildDir}/"
popd
done