From 4819063beb2552e3dae6a8176336966c694920c4 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:57:56 +0000 Subject: [PATCH 1/4] Add Debian, RPM, and AUR packaging recipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each recipe installs the compat libraries and headers into the private prefix /usr/lib/libx11-compat via make install, avoiding file conflicts with the real X11 dev packages. Also fix the pre-2.20 SDL2_ttf wrapper thunks for TTF_GlyphIsProvided and TTF_GlyphIsProvided32: SDL2_ttf < 2.20 declares them with a non-const TTF_Font *, so the const-qualified thunks failed to compile against those headers (e.g. Ubuntu 22.04's SDL2_ttf 2.0.18). Co-Authored-By: Erkin Alp Güney --- debian/changelog | 5 +++ debian/control | 30 +++++++++++++++++ debian/copyright | 27 +++++++++++++++ debian/rules | 29 ++++++++++++++++ debian/source/format | 1 + packaging/README.md | 41 +++++++++++++++++++++++ packaging/aur/PKGBUILD | 37 +++++++++++++++++++++ packaging/rpm/libx11-compat.spec | 57 ++++++++++++++++++++++++++++++++ src/wrapper/sdl-ttf-wrapper.c | 13 +------- 9 files changed, 228 insertions(+), 12 deletions(-) create mode 100644 debian/changelog create mode 100644 debian/control create mode 100644 debian/copyright create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 packaging/README.md create mode 100644 packaging/aur/PKGBUILD create mode 100644 packaging/rpm/libx11-compat.spec diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 00000000..10326f13 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +libx11-compat (0.1.0-1) unstable; urgency=medium + + * Initial packaging. + + -- libx11-compat maintainers Tue, 04 Aug 2026 17:00:00 +0000 diff --git a/debian/control b/debian/control new file mode 100644 index 00000000..c0b9c77b --- /dev/null +++ b/debian/control @@ -0,0 +1,30 @@ +Source: libx11-compat +Section: libs +Priority: optional +Maintainer: libx11-compat maintainers +Build-Depends: debhelper-compat (= 13), + pkgconf, + python3, + libsdl2-dev, + libsdl2-ttf-dev, + libpixman-1-dev +Standards-Version: 4.6.2 +Homepage: https://github.com/sysprog21/libx11-compat +Vcs-Git: https://github.com/sysprog21/libx11-compat.git +Vcs-Browser: https://github.com/sysprog21/libx11-compat +Rules-Requires-Root: no + +Package: libx11-compat +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: in-process Xlib implementation layered on SDL + libx11-compat is an in-process implementation of the X Window System + client library (Xlib) layered on top of SDL (SDL2 or SDL3), SDL_ttf, + and pixman. It lets existing Xlib clients keep their source unchanged + while running on platforms where a conventional X server is + unavailable or inconvenient: Wayland-only sessions, headless CI, and + similar environments. + . + This package ships the compat shared libraries (libX11-compat.so and + friends) with standard-name aliases plus the public X11 API headers, + so a downstream build can link against the shim as an ordinary X11. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 00000000..9fe12436 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,27 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: libx11-compat +Source: https://github.com/sysprog21/libx11-compat + +Files: * +Copyright: 2016-2019, 2022 Sebastian Scholz + 2026 National Cheng Kung University, Taiwan +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/debian/rules b/debian/rules new file mode 100755 index 00000000..2a8c51aa --- /dev/null +++ b/debian/rules @@ -0,0 +1,29 @@ +#!/usr/bin/make -f +# Note: the build stages pinned upstream Xorg headers via +# scripts/sync-upstream-headers.py, which downloads cached tarballs. +# For a fully offline build, pre-populate the download cache first +# (run `make upstream-sync` with network access) before building. + +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +%: + dh $@ + +override_dh_auto_build: + $(MAKE) + +# Install into a private prefix: the shipped headers (X11/, GL/, ...) +# and libX11.so aliases would otherwise clash with the real X11 dev +# packages. Downstreams point their build at this tree, e.g. +# ./configure --with-libx11-compat=/usr/lib/libx11-compat +override_dh_auto_install: + $(MAKE) install PREFIX=/usr/lib/libx11-compat DESTDIR=$(CURDIR)/debian/libx11-compat + +override_dh_auto_test: + # The full check suite needs a display and optional workloads; + # skip it during package builds. + +# The compat libraries deliberately carry unversioned sonames +# (libX11-compat.so, ...); skip symbols/shlibs generation. +override_dh_makeshlibs: + dh_makeshlibs -n diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/packaging/README.md b/packaging/README.md new file mode 100644 index 00000000..1f7c3444 --- /dev/null +++ b/packaging/README.md @@ -0,0 +1,41 @@ +# Packaging recipes + +Distribution packaging recipes for libx11-compat. Each recipe builds the +compat shared libraries with standard-name aliases plus the public X11 +API headers via `make install` (see `mk/install.mk`), into the private +prefix `/usr/lib/libx11-compat` (`%{_libdir}/libx11-compat` on RPM +distros): the shipped headers (`X11/`, `GL/`, ...) and `libX11.so` +aliases would clash with the real X11 dev packages under `/usr`. +Downstreams point their build at this tree, e.g. +`./configure --with-libx11-compat=/usr/lib/libx11-compat`. + +Note for all recipes: the build stages pinned upstream Xorg headers via +`scripts/sync-upstream-headers.py`, which downloads cached tarballs. For +a fully offline build (sbuild, mock, or a clean chroot without network), +pre-populate the download cache first by running `make upstream-sync` +with network access. + +## Debian / Ubuntu / Pardus (`../debian/`) + +debhelper-13 packaging at the repository root. Build with: + +```sh +dpkg-buildpackage -us -uc -b +``` + +The changelog targets `unstable`; retarget the distribution field when +uploading to a specific distro. + +## RPM (Fedora / RHEL / openSUSE) (`rpm/libx11-compat.spec`) + +```sh +rpmbuild -ba packaging/rpm/libx11-compat.spec +``` + +## Arch Linux (AUR) (`aur/PKGBUILD`) + +A `-git` package tracking the main branch: + +```sh +cd packaging/aur && makepkg -si +``` diff --git a/packaging/aur/PKGBUILD b/packaging/aur/PKGBUILD new file mode 100644 index 00000000..bdcfcc58 --- /dev/null +++ b/packaging/aur/PKGBUILD @@ -0,0 +1,37 @@ +# Maintainer: libx11-compat maintainers +pkgname=libx11-compat-git +pkgver=r1.0000000 +pkgrel=1 +pkgdesc="In-process Xlib implementation layered on SDL (SDL2/SDL3), SDL_ttf, and pixman" +arch=('x86_64' 'aarch64') +url="https://github.com/sysprog21/libx11-compat" +license=('MIT') +depends=('sdl2' 'sdl2_ttf' 'pixman') +makedepends=('git' 'python' 'pkgconf') +provides=('libx11-compat') +conflicts=('libx11-compat') +source=("libx11-compat::git+$url.git") +sha256sums=('SKIP') + +pkgver() { + cd libx11-compat + printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" +} + +build() { + cd libx11-compat + # Note: the build stages pinned upstream Xorg headers via + # scripts/sync-upstream-headers.py, which downloads cached tarballs. + make +} + +package() { + cd libx11-compat + # Install into a private prefix: the shipped headers (X11/, GL/, ...) + # and libX11.so aliases would otherwise clash with the real X11 dev + # packages. Downstreams point their build at this tree, e.g. + # ./configure --with-libx11-compat=/usr/lib/libx11-compat + make install PREFIX=/usr/lib/libx11-compat DESTDIR="$pkgdir" + install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" + install -Dm644 README.md "$pkgdir/usr/share/doc/$pkgname/README.md" +} diff --git a/packaging/rpm/libx11-compat.spec b/packaging/rpm/libx11-compat.spec new file mode 100644 index 00000000..43d6855c --- /dev/null +++ b/packaging/rpm/libx11-compat.spec @@ -0,0 +1,57 @@ +Name: libx11-compat +Version: 0.1.0 +Release: 1%{?dist} +Summary: In-process Xlib implementation layered on SDL + +License: MIT +URL: https://github.com/sysprog21/libx11-compat +Source0: %{url}/archive/refs/heads/main.tar.gz#/%{name}-%{version}.tar.gz + +BuildRequires: gcc +BuildRequires: make +BuildRequires: pkgconfig +BuildRequires: python3 +BuildRequires: pkgconfig(sdl2) +BuildRequires: pkgconfig(SDL2_ttf) +BuildRequires: pkgconfig(pixman-1) + +%description +libx11-compat is an in-process implementation of the X Window System +client library (Xlib) layered on top of SDL (SDL2 or SDL3), SDL_ttf, +and pixman. It lets existing Xlib clients keep their source unchanged +while running on platforms where a conventional X server is +unavailable or inconvenient: Wayland-only sessions, headless CI, and +similar environments. + +This package ships the compat shared libraries (libX11-compat.so and +friends) with standard-name aliases plus the public X11 API headers, +so a downstream build can link against the shim as an ordinary X11. + +# Note: the build stages pinned upstream Xorg headers via +# scripts/sync-upstream-headers.py, which downloads cached tarballs. +# For a fully offline (mock/koji) build, pre-populate the download +# cache first (run `make upstream-sync` with network access). + +%prep +%autosetup -n %{name}-main + +%build +%make_build + +# Install into a private prefix: the shipped headers (X11/, GL/, ...) +# and libX11.so aliases would otherwise clash with the real X11 dev +# packages. Downstreams point their build at this tree, e.g. +# ./configure --with-libx11-compat=%{_libdir}/libx11-compat +%global compat_prefix %{_libdir}/libx11-compat + +%install +%make_install PREFIX=%{compat_prefix} + +%files +%license LICENSE +%doc README.md +%{compat_prefix}/ + +%changelog +* Tue Aug 04 2026 libx11-compat maintainers - 0.1.0-1 +- Initial packaging. diff --git a/src/wrapper/sdl-ttf-wrapper.c b/src/wrapper/sdl-ttf-wrapper.c index 9cae2119..2f9d1693 100644 --- a/src/wrapper/sdl-ttf-wrapper.c +++ b/src/wrapper/sdl-ttf-wrapper.c @@ -57,20 +57,9 @@ TTF_WRAP(char *, TTF_FontFaceFamilyName, (const TTF_Font *font), (font)) TTF_WRAP(int, TTF_FontFaceIsFixedWidth, (const TTF_Font *font), (font)) TTF_WRAP(const char *, TTF_GetError, (void), ()) TTF_WRAP(int, TTF_GetFontStyle, (const TTF_Font *font), (font)) -#if SDL_TTF_VERSION_ATLEAST(2, 20, 0) TTF_WRAP(int, TTF_GlyphIsProvided, (TTF_Font * font, Uint16 ch), (font, ch)) -TTF_WRAP(int, TTF_GlyphIsProvided32, (TTF_Font * font, Uint32 ch), (font, ch)) -#else -TTF_WRAP(int, - TTF_GlyphIsProvided, - (const TTF_Font *font, Uint16 ch), - (font, ch)) #if SDL_TTF_VERSION_ATLEAST(2, 0, 18) -TTF_WRAP(int, - TTF_GlyphIsProvided32, - (const TTF_Font *font, Uint32 ch), - (font, ch)) -#endif +TTF_WRAP(int, TTF_GlyphIsProvided32, (TTF_Font * font, Uint32 ch), (font, ch)) #endif TTF_WRAP(int, TTF_GlyphMetrics, From 857c451a6bbe13196421facd52ff4c3b82f92bfa Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 03:28:16 +0000 Subject: [PATCH 2/4] Address cubic review feedback on packaging recipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use a real maintainer email in debian/control, debian/changelog, the RPM changelog, and the PKGBUILD maintainer line. - debian/rules: drop the dh_auto_build override and delegate install to dh_auto_install so DEB_BUILD_OPTIONS=parallel is honored. - Drop the Debian revision from the version (0.1.0) to match the 3.0 (native) source format. - RPM: pin Source0 to a fixed commit with a snapshot Release, move the compat_prefix/commit %globals to the top of the spec, and keep the upstream-headers note out of %description text. - PKGBUILD: stage the network-fetched upstream Xorg headers in prepare() via make upstream-sync instead of mid-build(). - Ignore debhelper build output under debian/. Co-Authored-By: Erkin Alp Güney --- debian/.gitignore | 6 ++++++ debian/changelog | 4 ++-- debian/control | 2 +- debian/rules | 4 +--- packaging/aur/PKGBUILD | 13 ++++++++++--- packaging/rpm/libx11-compat.spec | 30 +++++++++++++++++------------- 6 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 debian/.gitignore diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 00000000..cf56f2dd --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,6 @@ +.debhelper/ +debhelper-build-stamp +files +libx11-compat/ +libx11-compat.debhelper.log +libx11-compat.substvars diff --git a/debian/changelog b/debian/changelog index 10326f13..8a1b938c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -libx11-compat (0.1.0-1) unstable; urgency=medium +libx11-compat (0.1.0) unstable; urgency=medium * Initial packaging. - -- libx11-compat maintainers Tue, 04 Aug 2026 17:00:00 +0000 + -- libx11-compat maintainers Tue, 04 Aug 2026 17:00:00 +0000 diff --git a/debian/control b/debian/control index c0b9c77b..593afd2b 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: libx11-compat Section: libs Priority: optional -Maintainer: libx11-compat maintainers +Maintainer: libx11-compat maintainers Build-Depends: debhelper-compat (= 13), pkgconf, python3, diff --git a/debian/rules b/debian/rules index 2a8c51aa..ebdcd503 100755 --- a/debian/rules +++ b/debian/rules @@ -9,15 +9,13 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: dh $@ -override_dh_auto_build: - $(MAKE) # Install into a private prefix: the shipped headers (X11/, GL/, ...) # and libX11.so aliases would otherwise clash with the real X11 dev # packages. Downstreams point their build at this tree, e.g. # ./configure --with-libx11-compat=/usr/lib/libx11-compat override_dh_auto_install: - $(MAKE) install PREFIX=/usr/lib/libx11-compat DESTDIR=$(CURDIR)/debian/libx11-compat + dh_auto_install -- PREFIX=/usr/lib/libx11-compat override_dh_auto_test: # The full check suite needs a display and optional workloads; diff --git a/packaging/aur/PKGBUILD b/packaging/aur/PKGBUILD index bdcfcc58..6531c648 100644 --- a/packaging/aur/PKGBUILD +++ b/packaging/aur/PKGBUILD @@ -1,4 +1,4 @@ -# Maintainer: libx11-compat maintainers +# Maintainer: libx11-compat maintainers pkgname=libx11-compat-git pkgver=r1.0000000 pkgrel=1 @@ -18,10 +18,17 @@ pkgver() { printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" } +prepare() { + cd libx11-compat + # Stage the pinned upstream Xorg headers up front: the fetch happens + # over the network via scripts/sync-upstream-headers.py, outside + # makepkg's source/checksum handling, so do it in prepare() where + # network access is expected rather than mid-build(). + make upstream-sync +} + build() { cd libx11-compat - # Note: the build stages pinned upstream Xorg headers via - # scripts/sync-upstream-headers.py, which downloads cached tarballs. make } diff --git a/packaging/rpm/libx11-compat.spec b/packaging/rpm/libx11-compat.spec index 43d6855c..8375872c 100644 --- a/packaging/rpm/libx11-compat.spec +++ b/packaging/rpm/libx11-compat.spec @@ -1,11 +1,22 @@ +# Pin the source to a fixed commit so the NEVRA always maps to the same +# code; bump %%commit (and Version/Release) when updating the package. +%global commit 93e0505ce8880115187b32d80d25535f1cc66fe2 +%global shortcommit %(c=%{commit}; echo ${c:0:7}) + +# Install into a private prefix: the shipped headers (X11/, GL/, ...) +# and libX11.so aliases would otherwise clash with the real X11 dev +# packages. Downstreams point their build at this tree, e.g. +# ./configure --with-libx11-compat=%%{_libdir}/libx11-compat +%global compat_prefix %{_libdir}/libx11-compat + Name: libx11-compat Version: 0.1.0 -Release: 1%{?dist} +Release: 1.20260804git%{shortcommit}%{?dist} Summary: In-process Xlib implementation layered on SDL License: MIT URL: https://github.com/sysprog21/libx11-compat -Source0: %{url}/archive/refs/heads/main.tar.gz#/%{name}-%{version}.tar.gz +Source0: %{url}/archive/%{commit}/%{name}-%{shortcommit}.tar.gz BuildRequires: gcc BuildRequires: make @@ -27,23 +38,16 @@ This package ships the compat shared libraries (libX11-compat.so and friends) with standard-name aliases plus the public X11 API headers, so a downstream build can link against the shim as an ordinary X11. +%prep +%autosetup -n %{name}-%{commit} + # Note: the build stages pinned upstream Xorg headers via # scripts/sync-upstream-headers.py, which downloads cached tarballs. # For a fully offline (mock/koji) build, pre-populate the download # cache first (run `make upstream-sync` with network access). - -%prep -%autosetup -n %{name}-main - %build %make_build -# Install into a private prefix: the shipped headers (X11/, GL/, ...) -# and libX11.so aliases would otherwise clash with the real X11 dev -# packages. Downstreams point their build at this tree, e.g. -# ./configure --with-libx11-compat=%{_libdir}/libx11-compat -%global compat_prefix %{_libdir}/libx11-compat - %install %make_install PREFIX=%{compat_prefix} @@ -53,5 +57,5 @@ so a downstream build can link against the shim as an ordinary X11. %{compat_prefix}/ %changelog -* Tue Aug 04 2026 libx11-compat maintainers - 0.1.0-1 +* Tue Aug 04 2026 libx11-compat maintainers - 0.1.0-1.20260804git93e0505 - Initial packaging. From 533eab5f6e62ab353adb6ce8271c7fa0eb58400c Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 04:40:58 +0000 Subject: [PATCH 3/4] Make offline packaging builds real via a seedable tarball directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per review, the previous "pre-populate the cache" advice did not hold: dpkg-buildpackage's clean wipes the in-tree cache, mock/koji chroots are fresh with no network, and a prepare()-time fetch bypasses makepkg checksums. Teach scripts/sync-upstream-headers.py to seed the pinned upstream tarballs from LIBX11_COMPAT_TARBALL_DIR (sha256-verified against the pins) before falling back to the network. Declare the tarballs as real sources: Source1..Source6 in the RPM spec with the variable pointed at %_sourcedir, and source=() entries (checksummed by makepkg, noextract) in the PKGBUILD with the variable pointed at $srcdir. Document the Debian flow (seed directory outside the source tree) in debian/rules and packaging/README.md, and drop the now-unneeded PKGBUILD prepare(). Co-Authored-By: Erkin Alp Güney --- debian/rules | 8 ++++--- packaging/README.md | 14 ++++++++---- packaging/aur/PKGBUILD | 38 ++++++++++++++++++++++---------- packaging/rpm/libx11-compat.spec | 17 ++++++++++---- scripts/sync-upstream-headers.py | 26 +++++++++++++++++++--- 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/debian/rules b/debian/rules index ebdcd503..e5fadbd5 100755 --- a/debian/rules +++ b/debian/rules @@ -1,8 +1,10 @@ #!/usr/bin/make -f # Note: the build stages pinned upstream Xorg headers via -# scripts/sync-upstream-headers.py, which downloads cached tarballs. -# For a fully offline build, pre-populate the download cache first -# (run `make upstream-sync` with network access) before building. +# scripts/sync-upstream-headers.py, which downloads sha256-pinned +# tarballs. For an offline build, place those tarballs in a directory +# outside the source tree (the clean target wipes the in-tree cache) +# and export LIBX11_COMPAT_TARBALL_DIR pointing at it; the script then +# seeds from that directory instead of the network. export DEB_BUILD_MAINT_OPTIONS = hardening=+all diff --git a/packaging/README.md b/packaging/README.md index 1f7c3444..d6ecfd43 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -10,10 +10,16 @@ Downstreams point their build at this tree, e.g. `./configure --with-libx11-compat=/usr/lib/libx11-compat`. Note for all recipes: the build stages pinned upstream Xorg headers via -`scripts/sync-upstream-headers.py`, which downloads cached tarballs. For -a fully offline build (sbuild, mock, or a clean chroot without network), -pre-populate the download cache first by running `make upstream-sync` -with network access. +`scripts/sync-upstream-headers.py`, which downloads sha256-pinned +tarballs. For offline builds (sbuild, mock/koji, or a clean chroot +without network), the script seeds those tarballs from the directory +named by `LIBX11_COMPAT_TARBALL_DIR` instead of the network, verifying +the pinned sha256 either way. The RPM spec declares the tarballs as +`Source1:`..`Source6:` and points the variable at `%{_sourcedir}`; the +PKGBUILD lists them in `source=()` (checksummed by makepkg) and points +the variable at `$srcdir`; for Debian, place the tarballs in a directory +outside the source tree (the clean target wipes the in-tree cache) and +export the variable before `dpkg-buildpackage`. ## Debian / Ubuntu / Pardus (`../debian/`) diff --git a/packaging/aur/PKGBUILD b/packaging/aur/PKGBUILD index 6531c648..0e9c7ae7 100644 --- a/packaging/aur/PKGBUILD +++ b/packaging/aur/PKGBUILD @@ -10,26 +10,40 @@ depends=('sdl2' 'sdl2_ttf' 'pixman') makedepends=('git' 'python' 'pkgconf') provides=('libx11-compat') conflicts=('libx11-compat') -source=("libx11-compat::git+$url.git") -sha256sums=('SKIP') +# The pinned upstream Xorg tarballs the build stages headers/sources +# from are declared as sources so makepkg downloads and checksums them; +# scripts/sync-upstream-headers.py seeds them from $srcdir via +# LIBX11_COMPAT_TARBALL_DIR (re-verifying the pinned sha256) instead of +# fetching over the network mid-build. +source=("libx11-compat::git+$url.git" + 'https://xorg.freedesktop.org/archive/individual/lib/libX11-1.8.13.tar.xz' + 'https://xorg.freedesktop.org/archive/individual/proto/xorgproto-2025.1.tar.xz' + 'https://xorg.freedesktop.org/archive/individual/lib/libXt-1.3.1.tar.xz' + 'https://xorg.freedesktop.org/archive/individual/lib/libXpm-3.5.19.tar.xz' + 'https://xorg.freedesktop.org/archive/individual/lib/libXmu-1.3.1.tar.xz' + 'https://xorg.freedesktop.org/archive/individual/lib/libXaw-1.0.16.tar.xz') +noextract=('libX11-1.8.13.tar.xz' + 'xorgproto-2025.1.tar.xz' + 'libXt-1.3.1.tar.xz' + 'libXpm-3.5.19.tar.xz' + 'libXmu-1.3.1.tar.xz' + 'libXaw-1.0.16.tar.xz') +sha256sums=('SKIP' + '69606f485c2c07c14ef64f75b7bb326d48587af33795d9ab3e607c0b5f94f11c' + '56898c716c0578df8a2d828c9c3e5c528277705c0484381a81960fe1a67668e8' + 'e0a774b33324f4d4c05b199ea45050f87206586d81655f8bef4dba434d931288' + 'ad3576d689221a39dc728f0e0dc02ca7bb6a0d724c9a77fd1bfa1e9af83be900' + '81a99e94c4501e81c427cbaa4a11748b584933e94b7a156830c3621256857bc4' + '731d572b54c708f81e197a6afa8016918e2e06dfd3025e066ca642a5b8c39c8f') pkgver() { cd libx11-compat printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" } -prepare() { - cd libx11-compat - # Stage the pinned upstream Xorg headers up front: the fetch happens - # over the network via scripts/sync-upstream-headers.py, outside - # makepkg's source/checksum handling, so do it in prepare() where - # network access is expected rather than mid-build(). - make upstream-sync -} - build() { cd libx11-compat - make + LIBX11_COMPAT_TARBALL_DIR="$srcdir" make } package() { diff --git a/packaging/rpm/libx11-compat.spec b/packaging/rpm/libx11-compat.spec index 8375872c..bf30b009 100644 --- a/packaging/rpm/libx11-compat.spec +++ b/packaging/rpm/libx11-compat.spec @@ -17,6 +17,15 @@ Summary: In-process Xlib implementation layered on SDL License: MIT URL: https://github.com/sysprog21/libx11-compat Source0: %{url}/archive/%{commit}/%{name}-%{shortcommit}.tar.gz +# Pinned upstream Xorg tarballs the build stages headers/sources from +# (see scripts/sync-upstream-headers.py, which verifies their sha256). +# Declaring them as sources keeps the build fully offline in mock/koji. +Source1: https://xorg.freedesktop.org/archive/individual/lib/libX11-1.8.13.tar.xz +Source2: https://xorg.freedesktop.org/archive/individual/proto/xorgproto-2025.1.tar.xz +Source3: https://xorg.freedesktop.org/archive/individual/lib/libXt-1.3.1.tar.xz +Source4: https://xorg.freedesktop.org/archive/individual/lib/libXpm-3.5.19.tar.xz +Source5: https://xorg.freedesktop.org/archive/individual/lib/libXmu-1.3.1.tar.xz +Source6: https://xorg.freedesktop.org/archive/individual/lib/libXaw-1.0.16.tar.xz BuildRequires: gcc BuildRequires: make @@ -41,11 +50,11 @@ so a downstream build can link against the shim as an ordinary X11. %prep %autosetup -n %{name}-%{commit} -# Note: the build stages pinned upstream Xorg headers via -# scripts/sync-upstream-headers.py, which downloads cached tarballs. -# For a fully offline (mock/koji) build, pre-populate the download -# cache first (run `make upstream-sync` with network access). +# The staging script seeds the pinned upstream tarballs from +# LIBX11_COMPAT_TARBALL_DIR (sha256-verified) instead of the network, +# so the build works in an offline mock/koji chroot. %build +export LIBX11_COMPAT_TARBALL_DIR=%{_sourcedir} %make_build %install diff --git a/scripts/sync-upstream-headers.py b/scripts/sync-upstream-headers.py index 77dcb953..e4b49c82 100644 --- a/scripts/sync-upstream-headers.py +++ b/scripts/sync-upstream-headers.py @@ -12,7 +12,10 @@ ``fetch DEST [--force]`` Download (cached) tarballs and extract headers into ``DEST/X11/`` and the whitelisted libX11 ``src/`` files into ``DEST/../src/``. Idempotent - through ``DEST/.upstream-stamp``. + through ``DEST/.upstream-stamp``. For offline builds, set + ``LIBX11_COMPAT_TARBALL_DIR`` to a directory holding the pinned + tarballs; entries whose sha256 matches the pin are used instead of + downloading. ``diff`` Compare local ``include/X11/`` to upstream and classify each path as @@ -478,6 +481,23 @@ def download(url: str, expected_sha: str) -> Path: file=sys.stderr, ) dest.unlink(missing_ok=True) + # Offline builds (distro packaging, network-restricted chroots) can drop + # the pinned tarballs into a directory and point this variable at it; a + # tarball whose sha256 matches the pin is used instead of the network. + # The cache under build/ does not survive `make distclean`, so the seed + # directory should live outside the build tree. + seed_dir = os.environ.get("LIBX11_COMPAT_TARBALL_DIR") + if seed_dir: + candidate = Path(seed_dir) / dest.name + if candidate.is_file(): + if sha256_of(candidate) == expected_sha: + print(f" SEED {candidate}", file=sys.stderr) + shutil.copyfile(candidate, dest) + return dest + print( + f" WARN seed {candidate} has unexpected sha256; ignoring", + file=sys.stderr, + ) print(f" FETCH {url}", file=sys.stderr) tmp_fd, tmp_name = tempfile.mkstemp(dir=CACHE_DIR, prefix=".dl-") os.close(tmp_fd) @@ -509,8 +529,8 @@ def download(url: str, expected_sha: str) -> Path: if last_exc is not None: raise SystemExit( f"failed to download {url} after {attempts} attempts: {last_exc}\n" - f" pre-seed the cache at {CACHE_DIR}/{dest.name} " - f"to build offline" + f" to build offline, place {dest.name} in a directory and\n" + f" set LIBX11_COMPAT_TARBALL_DIR to that directory" ) from last_exc actual = sha256_of(tmp_path) if actual != expected_sha: From d3f4ac8ef3e0afa76a33def42bab2a78c70a31c4 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 05:20:20 +0000 Subject: [PATCH 4/4] Document sbuild env/tarball injection for offline Debian builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An env var exported in the caller's shell does not reach the inner make under sbuild's clean chroot; note that the tarballs and LIBX11_COMPAT_TARBALL_DIR must be injected into the chroot explicitly. Co-Authored-By: Erkin Alp Güney --- packaging/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packaging/README.md b/packaging/README.md index d6ecfd43..cbedf467 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -19,7 +19,12 @@ the pinned sha256 either way. The RPM spec declares the tarballs as PKGBUILD lists them in `source=()` (checksummed by makepkg) and points the variable at `$srcdir`; for Debian, place the tarballs in a directory outside the source tree (the clean target wipes the in-tree cache) and -export the variable before `dpkg-buildpackage`. +export the variable before a direct `dpkg-buildpackage`. Under sbuild +the build runs in a clean chroot where the caller's environment does +not reach the inner make, so inject both the tarballs and the variable +into the chroot explicitly (e.g. copy the tarballs in with +`--chroot-setup-commands` or a bind mount, and pass the variable via +`$build_environment` in `.sbuildrc`). ## Debian / Ubuntu / Pardus (`../debian/`)