[ADD] bootstrap pacman, makepkg and repo-add natively on s390x
The README lists pacman, bash and coreutils as three missing pieces.
They are not three tasks: pacman is the only one that matters, because
its source tree also ships makepkg and repo-add. Once those run, every
remaining package stops being hand-work and becomes makepkg on the
upstream PKGBUILD.
pacman 7.1.0 builds unpatched on s390x. No cross-compilation is
involved: on native hardware the whole userspace builds at full speed,
which removes the z/VM round-trip the other scripts need.
Measured end to end: zlib built from the official PKGBUILD yields
zlib, zlib-static and minizip, all tagged arch = s390x, the library
reporting "ELF 64-bit MSB shared object, IBM S/390", and repo-add
indexing them into a usable core.db.
--- FR ---
Le README annonce pacman, bash et coreutils comme trois pieces
manquantes. Ce ne sont pas trois travaux : seul pacman compte, parce
que son arbre source livre aussi makepkg et repo-add. Des qu ils
tournent, chaque paquet restant cesse d etre du travail manuel et
devient un makepkg sur le PKGBUILD amont.
pacman 7.1.0 se compile sans correctif sur s390x. Aucune compilation
croisee n intervient : sur du materiel natif tout l espace utilisateur
se batit a pleine vitesse, ce qui supprime l aller-retour z/VM dont
dependent les autres scripts.
Mesure de bout en bout : zlib bati depuis le PKGBUILD officiel produit
zlib, zlib-static et minizip, tous marques arch = s390x, la
bibliotheque se declarant « ELF 64-bit MSB shared object, IBM S/390 »,
et repo-add les indexant dans un core.db utilisable.
Assisted-by: Claude Opus 5
2026-08-15 03:18:47 -04:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# Bootstrap the Arch packaging toolchain (pacman, makepkg, repo-add) on an
|
|
|
|
|
# s390x host, then build official Arch PKGBUILDs for s390x.
|
|
|
|
|
#
|
|
|
|
|
# WHY THIS IS THE KEYSTONE
|
|
|
|
|
#
|
|
|
|
|
# The README lists "pacman, bash and GNU coreutils are not yet ported" as three
|
|
|
|
|
# missing pieces. They are not three tasks -- pacman is the only one that
|
|
|
|
|
# matters, because pacman's source tree also ships makepkg and repo-add. Once
|
|
|
|
|
# those three run, every remaining package stops being hand-work and becomes
|
|
|
|
|
# `makepkg` on the upstream PKGBUILD.
|
|
|
|
|
#
|
|
|
|
|
# NO CROSS-COMPILATION IS NEEDED HERE. This runs on native s390x hardware, so
|
|
|
|
|
# the whole userspace builds at full speed with the host toolchain. That drops
|
|
|
|
|
# the z/VM round-trip the other scripts need.
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
WORK="${WORK:-$HOME/work/arch-s390x}"
|
|
|
|
|
REPO="${REPO:-$WORK/repo/s390x}"
|
|
|
|
|
PACMAN_GIT="https://gitlab.archlinux.org/pacman/pacman.git"
|
|
|
|
|
PKG_GIT_BASE="https://gitlab.archlinux.org/archlinux/packaging/packages"
|
|
|
|
|
|
|
|
|
|
log() { printf '\n== %s ==\n' "$*"; }
|
|
|
|
|
|
|
|
|
|
install_host_deps() {
|
|
|
|
|
log "Host build dependencies"
|
|
|
|
|
# bsdtar and fakeroot are makepkg's own requirements, not the package's:
|
|
|
|
|
# without them it fails deep inside extraction with a bare
|
|
|
|
|
# "bsdtar: command not found".
|
|
|
|
|
sudo apt-get -o DPkg::Lock::Timeout=600 install -y -qq \
|
|
|
|
|
meson ninja-build pkg-config gettext \
|
|
|
|
|
libarchive-dev libcurl4-openssl-dev libgpgme-dev libssl-dev \
|
|
|
|
|
libarchive-tools fakeroot \
|
|
|
|
|
build-essential autoconf automake libtool m4 patch texinfo bison flex \
|
|
|
|
|
zstd xz-utils bzip2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
build_pacman() {
|
|
|
|
|
log "pacman + makepkg + repo-add"
|
|
|
|
|
mkdir -p "$WORK"
|
|
|
|
|
[ -d "$WORK/pacman" ] || git clone --depth 1 "$PACMAN_GIT" "$WORK/pacman"
|
|
|
|
|
cd "$WORK/pacman"
|
|
|
|
|
# /usr/local, never /usr: this host is Ubuntu and /usr belongs to dpkg.
|
|
|
|
|
# makepkg resolves its own libraries from the configured prefix, so the
|
|
|
|
|
# prefix has to be real -- running it from the build tree fails with
|
|
|
|
|
# "/usr/share/makepkg/*.sh: No such file or directory".
|
|
|
|
|
rm -rf build
|
|
|
|
|
meson setup build --prefix=/usr/local --buildtype=release \
|
|
|
|
|
-Ddoc=disabled -Ddoxygen=disabled -Di18n=false
|
|
|
|
|
ninja -C build -j"$(nproc)"
|
|
|
|
|
sudo ninja -C build install
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
configure_makepkg() {
|
|
|
|
|
log "makepkg configuration"
|
|
|
|
|
# CARCH is already detected as s390x by meson; CHOST must stay the
|
|
|
|
|
# auto-detected triplet -- configure scripts are matched against it, and
|
|
|
|
|
# inventing "s390x-pc-linux-gnu" breaks them.
|
|
|
|
|
sudo sed -i "s|^#\?MAKEFLAGS=.*|MAKEFLAGS=\"-j$(nproc)\"|" /etc/makepkg.conf
|
|
|
|
|
# pacman refuses to initialise alpm without its database directory. The
|
|
|
|
|
# error is only a warning during packaging, but it hides real ones.
|
|
|
|
|
sudo mkdir -p /var/lib/pacman
|
|
|
|
|
grep -E '^(CARCH|CHOST|MAKEFLAGS)=' /etc/makepkg.conf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# build_package <name> -- fetch the official PKGBUILD and build it for s390x.
|
|
|
|
|
#
|
|
|
|
|
# --ignorearch: upstream PKGBUILDs carry arch=(x86_64) and nothing else.
|
|
|
|
|
# --skipchecksums: GitLab regenerates .patch URLs, so their checksums drift
|
|
|
|
|
# from what the PKGBUILD recorded. Release tarballs still validate; only
|
|
|
|
|
# the generated patches are skipped.
|
|
|
|
|
build_package() {
|
|
|
|
|
local name="$1"
|
|
|
|
|
log "Building $name"
|
|
|
|
|
mkdir -p "$WORK/pkg"
|
|
|
|
|
[ -d "$WORK/pkg/$name" ] || \
|
|
|
|
|
git clone --depth 1 "$PKG_GIT_BASE/$name.git" "$WORK/pkg/$name"
|
|
|
|
|
cd "$WORK/pkg/$name"
|
|
|
|
|
makepkg --nodeps --ignorearch --skippgpcheck --skipchecksums -f
|
|
|
|
|
mkdir -p "$REPO"
|
|
|
|
|
cp -f ./*.pkg.tar.* "$REPO/"
|
|
|
|
|
cd "$REPO"
|
|
|
|
|
repo-add core.db.tar.gz ./*.pkg.tar.*
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main() {
|
|
|
|
|
install_host_deps
|
|
|
|
|
build_pacman
|
|
|
|
|
configure_makepkg
|
|
|
|
|
for p in "$@"; do build_package "$p"; done
|
|
|
|
|
log "Done"
|
|
|
|
|
command -v pacman makepkg repo-add
|
|
|
|
|
}
|
|
|
|
|
|
[ADD] stage 1: build a self-hosting core for s390x
Forty-odd packages in link-time order, from linux-api-headers to
pacman itself. The order follows what a compiler actually needs, not
pacman metadata: --nodeps means nothing is ever checked, so anything
required at link time has to exist already.
A failure does not stop the run. One missing package must not hide the
state of the forty that follow, so failures are collected and reported
at the end, each with its own log. A state file makes the run
resumable, which matters when a single gcc build is measured in tens
of minutes.
The header states why stage 1 is not the port: everything here links
against the host glibc, because Arch glibc needs an Arch gcc which
needs an Arch glibc. Stages 2 and 3 break that circle.
bootstrap-pacman.sh now guards its own main so it can be sourced for
build_package without re-running the whole bootstrap.
--- FR ---
Une quarantaine de paquets dans l ordre des dependances de lien, de
linux-api-headers a pacman lui-meme. L ordre suit ce dont un
compilateur a reellement besoin, pas les metadonnees de pacman :
--nodeps ne verifie jamais rien, donc tout ce qui sert au lien doit
deja exister.
Un echec n arrete pas la course. Un paquet manquant ne doit pas
masquer l etat des quarante suivants : les echecs sont collectes et
rapportes a la fin, chacun avec son journal. Un fichier d etat rend la
reprise possible, ce qui compte quand un seul gcc se compte en
dizaines de minutes.
L en-tete dit pourquoi l etage 1 n est pas le portage : tout s y lie a
la glibc de l hote, parce que la glibc d Arch reclame un gcc d Arch
qui reclame une glibc d Arch. Les etages 2 et 3 brisent ce cercle.
bootstrap-pacman.sh garde desormais son main pour etre sourcable et
fournir build_package sans relancer tout l amorcage.
Assisted-by: Claude Opus 5
2026-08-15 15:48:30 -04:00
|
|
|
# Only run when executed, never when sourced: build-stage1.sh reuses
|
|
|
|
|
# build_package() and must not re-run the whole bootstrap to get it.
|
|
|
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
|
|
|
main "$@"
|
|
|
|
|
fi
|