From 8f86585e87dcd4f28b652ffa71be9d5c6087d077 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 12:01:23 -0700 Subject: [PATCH] rm xvfb --- build.sh | 3 +- pyproject.toml | 1 - xvfb/build.sh | 133 ------------------------------------------ xvfb/pyproject.toml | 18 ------ xvfb/setup.py | 58 ------------------ xvfb/xvfb/__init__.py | 57 ------------------ 6 files changed, 1 insertion(+), 269 deletions(-) delete mode 100755 xvfb/build.sh delete mode 100644 xvfb/pyproject.toml delete mode 100644 xvfb/setup.py delete mode 100644 xvfb/xvfb/__init__.py diff --git a/build.sh b/build.sh index ffe2227..c6a4c29 100755 --- a/build.sh +++ b/build.sh @@ -55,8 +55,7 @@ if [[ -n "${BUILD_SH_IN_MANYLINUX:-}" ]]; then dnf install -y -q \ libX11-devel libXcursor-devel libXrandr-devel libXinerama-devel libXi-devel \ mesa-libGL-devel mesa-libEGL-devel mesa-libGLES-devel \ - wayland-devel wayland-protocols-devel libxkbcommon-devel \ - xorg-x11-server-Xvfb xorg-x11-xkb-utils xkeyboard-config + wayland-devel wayland-protocols-devel libxkbcommon-devel fi fi diff --git a/pyproject.toml b/pyproject.toml index 98ecbbf..e87485c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ members = [ "libyuv", "ncurses", "raylib", - "xvfb", "zeromq", "zstd", ] diff --git a/xvfb/build.sh b/xvfb/build.sh deleted file mode 100755 index 8913736..0000000 --- a/xvfb/build.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env bash -set -e - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -cd "$DIR" - -INSTALL_DIR="$DIR/xvfb/install" - -# macOS: Xvfb is Linux-only. Ship an empty install dir so the wheel still -# builds; smoketest() is a no-op on Darwin. -if [[ "$OSTYPE" == "darwin"* ]]; then - rm -rf "$INSTALL_DIR" - mkdir -p "$INSTALL_DIR"/{bin,lib,share/X11/xkb} - echo "xvfb: macOS not supported, shipping empty install dir" - exit 0 -fi - -# Linux: bundle the Xvfb binary, xkbcomp, xkb keymap data, and the closure -# of shared libraries it needs (minus libc/libpthread/etc which the host -# always provides). For CI/manylinux we pull from AlmaLinux 8 so the wheel -# works on any glibc >= 2.28 distro; on a Debian/Ubuntu dev host we accept -# whatever the system has (the local wheel just won't be as portable). -if command -v dnf >/dev/null 2>&1; then - dnf install -y -q xorg-x11-server-Xvfb xorg-x11-xkb-utils xkeyboard-config >/dev/null -elif command -v apt-get >/dev/null 2>&1; then - if [[ "$(id -u)" -eq 0 ]]; then SUDO="" - elif command -v sudo >/dev/null 2>&1; then SUDO=sudo - else echo "xvfb: need sudo or root to apt-get install" >&2; exit 1; fi - export DEBIAN_FRONTEND=noninteractive - $SUDO apt-get update -qq - $SUDO apt-get install -y -qq --no-install-recommends \ - xvfb x11-xkb-utils xkb-data patchelf -else - echo "xvfb: need dnf or apt-get to fetch upstream Xvfb" >&2 - exit 1 -fi - -if ! command -v patchelf >/dev/null 2>&1; then - echo "xvfb: patchelf is required but not found" >&2 - exit 1 -fi - -rm -rf "$INSTALL_DIR" -mkdir -p "$INSTALL_DIR"/{bin,lib,share/X11/xkb} - -# Xvfb may live in /usr/bin (RPM/Debian) — just locate it. -XVFB_SRC="$(command -v Xvfb || true)" -XKBCOMP_SRC="$(command -v xkbcomp || true)" -if [[ -z "$XVFB_SRC" || -z "$XKBCOMP_SRC" ]]; then - echo "xvfb: Xvfb or xkbcomp not found after install" >&2 - exit 1 -fi - -cp "$XVFB_SRC" "$INSTALL_DIR/bin/Xvfb" -cp "$XKBCOMP_SRC" "$INSTALL_DIR/bin/xkbcomp" -chmod u+w "$INSTALL_DIR/bin/Xvfb" "$INSTALL_DIR/bin/xkbcomp" -cp -a /usr/share/X11/xkb/. "$INSTALL_DIR/share/X11/xkb/" - -# Two binary patches to make Xvfb relocatable: -# -# 1. "/usr/bin" -> "" (null bytes) -# Xvfb's compile-time XkbBinDirectory points at /usr/bin and is used to -# build an absolute path to xkbcomp. Blanking it makes the spawned -# command just "xkbcomp", which popen() then resolves via PATH. Our -# Python wrapper prepends the bundled bin/ to PATH. -# -# 2. "-R%s" -> "-I%s" (in the xkbcomp argv format string) -# Xvfb passes its XkbBaseDirectory to xkbcomp via -R, expecting xkbcomp -# to chdir there *and* add "." to the include path. xkbcomp 1.4.x only -# chdirs — the include-path side was added later. Switching to -I makes -# 1.4.2 actually search the path we hand it via -xkbdir. -python3 - "$INSTALL_DIR/bin/Xvfb" <<'PY' -import sys -path = sys.argv[1] -with open(path, "r+b") as f: - data = bytearray(f.read()) - -def replace_unique(needle: bytes, replacement: bytes): - assert len(needle) == len(replacement) - idx = data.find(needle) - if idx < 0: - sys.exit(f"could not find {needle!r} in Xvfb binary") - if data.find(needle, idx + 1) >= 0: - sys.exit(f"multiple {needle!r} matches; refusing to patch") - data[idx:idx + len(needle)] = replacement - -replace_unique(b"/usr/bin\x00", b"\x00" * 9) -replace_unique(b'"-R%s"\x00', b'"-I%s"\x00') - -with open(path, "wb") as f: - f.write(data) -PY - -# bundle the shared library closure. Recursively walk ldd output to catch -# libs-of-libs (e.g. libXfont2 -> libfontenc -> libbz2). Skip core glibc -# pieces; everything else gets copied alongside the binary. -declare -A SEEN -collect_libs() { - local target="$1" - while IFS= read -r line; do - local lib - lib=$(echo "$line" | awk '{print $3}') - [[ -z "$lib" || "$lib" == "not" ]] && continue - [[ ! -e "$lib" ]] && continue - local base - base=$(basename "$lib") - case "$base" in - libc.so.*|libpthread.so.*|libm.so.*|librt.so.*|libdl.so.*|libgcc_s.so.*|libresolv.so.*|libutil.so.*|ld-linux-*.so.*|linux-vdso.so.*|linux-gate.so.*) - continue ;; - esac - [[ -n "${SEEN[$base]:-}" ]] && continue - SEEN[$base]=1 - cp -L "$lib" "$INSTALL_DIR/lib/$base" - chmod u+w "$INSTALL_DIR/lib/$base" - collect_libs "$INSTALL_DIR/lib/$base" - done < <(ldd "$target" 2>/dev/null || true) -} -collect_libs "$INSTALL_DIR/bin/Xvfb" -collect_libs "$INSTALL_DIR/bin/xkbcomp" - -# point the binaries (and the bundled libs) at our private lib dir so they -# don't accidentally resolve against an incompatible host copy. -patchelf --set-rpath '$ORIGIN/../lib' "$INSTALL_DIR/bin/Xvfb" -patchelf --set-rpath '$ORIGIN/../lib' "$INSTALL_DIR/bin/xkbcomp" -for so in "$INSTALL_DIR"/lib/*.so*; do - patchelf --set-rpath '$ORIGIN' "$so" 2>/dev/null || true -done - -strip --strip-unneeded "$INSTALL_DIR/bin/Xvfb" "$INSTALL_DIR/bin/xkbcomp" 2>/dev/null || true -find "$INSTALL_DIR/lib" -name '*.so*' -exec strip --strip-unneeded {} + 2>/dev/null || true - -echo "Installed xvfb to $INSTALL_DIR" -du -sh "$INSTALL_DIR" diff --git a/xvfb/pyproject.toml b/xvfb/pyproject.toml deleted file mode 100644 index 3e810fa..0000000 --- a/xvfb/pyproject.toml +++ /dev/null @@ -1,18 +0,0 @@ -[build-system] -requires = ["setuptools>=64", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "xvfb" -version = "1.20.11.post1" -description = "Xvfb (X virtual framebuffer) headless X server" -requires-python = ">=3.8" - -[project.scripts] -Xvfb = "xvfb:_run_xvfb" - -[tool.setuptools.packages.find] -include = ["xvfb*"] - -[tool.setuptools.package-data] -xvfb = ["install/**/*"] diff --git a/xvfb/setup.py b/xvfb/setup.py deleted file mode 100644 index b68017b..0000000 --- a/xvfb/setup.py +++ /dev/null @@ -1,58 +0,0 @@ -import os -import platform -import subprocess - -from setuptools.command.build_py import build_py - -try: - from wheel.bdist_wheel import bdist_wheel -except ImportError: - bdist_wheel = None - - -class BuildXvfb(build_py): - """Run build.sh to fetch and bundle Xvfb before collecting package data.""" - - def run(self): - pkg_dir = os.path.dirname(os.path.abspath(__file__)) - build_script = os.path.join(pkg_dir, "build.sh") - subprocess.check_call(["bash", build_script], cwd=pkg_dir) - - super().run() - - -cmdclass = {"build_py": BuildXvfb} - -if bdist_wheel is not None: - - class PlatformWheel(bdist_wheel): - """Produce a platform-specific, Python-version-agnostic wheel.""" - - def finalize_options(self): - super().finalize_options() - self.root_is_pure = False - - def get_tag(self): - system = platform.system() - machine = platform.machine() - - if system == "Linux": - plat = f"linux_{machine}" - elif system == "Darwin": - plat = "macosx_11_0_arm64" - else: - plat = f"{system.lower()}_{machine}" - - return "py3", "none", plat - - cmdclass["bdist_wheel"] = PlatformWheel - - -def setup(): - from setuptools import setup as _setup - - _setup(cmdclass=cmdclass) - - -if __name__ == "__main__": - setup() diff --git a/xvfb/xvfb/__init__.py b/xvfb/xvfb/__init__.py deleted file mode 100644 index 11b022b..0000000 --- a/xvfb/xvfb/__init__.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys - -DIR = os.path.join(os.path.dirname(__file__), "install") -BIN_DIR = os.path.join(DIR, "bin") -LIB_DIR = os.path.join(DIR, "lib") -XKB_DIR = os.path.join(DIR, "share", "X11", "xkb") - -XVFB_BIN = os.path.join(BIN_DIR, "Xvfb") -XKBCOMP_BIN = os.path.join(BIN_DIR, "xkbcomp") - - -# Common host paths where Mesa DRI drivers (e.g. swrast_dri.so) live. Xvfb -# was built on AlmaLinux 8 with /usr/lib64/dri baked in; on other distros -# (Debian/Ubuntu in particular) the drivers are elsewhere, and without them -# Xvfb fails to bring up a GL provider and silently disables the GLX -# extension. Probing the standard locations lets the host's drivers be -# found regardless of distro. -_DRI_PATHS = ( - "/usr/lib64/dri", - "/usr/lib/x86_64-linux-gnu/dri", - "/usr/lib/aarch64-linux-gnu/dri", - "/usr/lib/dri", -) - - -def _run_xvfb(): - # The bundled Xvfb has its compile-time XkbBinDirectory blanked out so it - # invokes xkbcomp via PATH lookup; prepend our bin dir so the bundled - # xkbcomp wins. -xkbdir points the server at the bundled keymap data. - env = os.environ.copy() - env["PATH"] = BIN_DIR + os.pathsep + env.get("PATH", "") - if "LIBGL_DRIVERS_PATH" not in env: - found = [p for p in _DRI_PATHS if os.path.isdir(p)] - if found: - env["LIBGL_DRIVERS_PATH"] = os.pathsep.join(found) - args = sys.argv[1:] - if not any(a == "-xkbdir" for a in args): - args = ["-xkbdir", XKB_DIR] + args - os.execvpe(XVFB_BIN, [XVFB_BIN] + args, env) - - -def smoketest(): - if sys.platform == "darwin": - return - assert os.path.isfile(XVFB_BIN), f"Xvfb not found at {XVFB_BIN}" - assert os.path.isfile(XKBCOMP_BIN), f"xkbcomp not found at {XKBCOMP_BIN}" - assert os.path.isdir(XKB_DIR), f"xkb data not found at {XKB_DIR}" - - import subprocess - # Xvfb prints usage to stderr and exits non-zero on `-help`; the banner - # mentions Xvfb-specific flags like -screen and -fbdir. If those appear, - # the binary loaded its bundled libs and ran far enough to print help. - result = subprocess.run([XVFB_BIN, "-help"], capture_output=True, text=True) - output = result.stderr + result.stdout - assert "-screen scrn WxHxD" in output, \ - f"Xvfb -help did not produce expected output: {output}"