#!/bin/sh # Root-side half of the packaging/void container harness. Runs inside the # pinned Void container as root: system setup, the void-packages checkout, # then the builder half (container-build.sh) as the builder user, then the # install plus import smoke as root again. # # Not executed directly: build.sh mounts this file and runs it. PKGNAME, # XBPS_ARGS, EXPECT_VULKAN and VOID_COMMIT arrive via the environment. set -eu export PATH=/usr/bin:/bin:/usr/sbin:/sbin xbps-install -Suy xbps >/dev/null xbps-install -y git base-devel xtools binutils zstd >/dev/null git clone --quiet --depth 1 https://github.com/void-linux/void-packages /void-packages git -C /void-packages fetch --quiet --depth 1 origin "$VOID_COMMIT" git -C /void-packages checkout --quiet "$VOID_COMMIT" cp -r /overlay/. /void-packages/srcpkgs/ id builder >/dev/null 2>&1 || useradd -m builder cp /mnt/container-build.sh /run-build.sh chown builder:builder /void-packages /run-build.sh chmod +x /run-build.sh su -s /bin/sh builder -c /run-build.sh echo "== install $PKGNAME from the local repository" PKGFILE=$(ls /void-packages/hostdir/binpkgs/"$PKGNAME"-*.x86_64.xbps /host/binpkgs/"$PKGNAME"-*.x86_64.xbps 2>/dev/null | head -n1) [ -n "$PKGFILE" ] || { echo "built package not found" >&2 exit 1 } echo "built: $PKGFILE" xbps-install -Sy >/dev/null xbps-install -y --repository="$(dirname "$PKGFILE")" "$PKGNAME" >/dev/null case "$PKGNAME" in voculinux) echo "== payload $PKGNAME: desktop entry, icons, packaged marker" tar -tf "$PKGFILE" 2>/dev/null | grep -q "usr/share/applications/voculinux.desktop" || { echo "renamed desktop entry missing from the built package" >&2 exit 1 } tar -tf "$PKGFILE" 2>/dev/null | grep -q "usr/share/icons/hicolor/scalable/apps/voculinux.svg" || { echo "renamed icons missing from the built package" >&2 exit 1 } tar -tf "$PKGFILE" 2>/dev/null | grep -q "usr/share/voculinux/packaged" || { echo "packaged-install marker missing from the built package" >&2 exit 1 } echo "== payload $PKGNAME: no speech models, no vendored wheels" if tar -tf "$PKGFILE" 2>/dev/null | grep -E "models/|\.ggml$|\.bin$|\.pt$|\.whl$"; then echo "package payload carries models or wheels" >&2 exit 1 fi echo "no models or wheels in the shipped package" echo "== payload $PKGNAME: no pre-rename leftovers" if tar -tf "$PKGFILE" 2>/dev/null | grep -E "usr/share/applications/vocalinux|usr/share/icons/.*/vocalinux"; then echo "pre-rename file names in the OS-visible payload" >&2 exit 1 fi echo "no pre-rename leftovers in the shipped package" echo "== version and import smoke $PKGNAME" voculinux --version cat > /voculinux-smoke.py <<'PYEOF' # The 0.18.5 sdist predates the rename: the importable top-level package # and the distribution metadata still carry the old name. The first # release cut after the rename moves these to voculinux. import importlib MODULES = ( "vocalinux.main", "vocalinux.ui.tray_indicator", "vocalinux.speech_recognition.recognition_manager", "vocalinux.speech_recognition.command_processor", "vocalinux.text_injection.text_injector", "vocalinux.text_injection.ibus_engine", "vocalinux.ui.keyboard_backends", "pywhispercpp.model", ) for module in MODULES: importlib.import_module(module) print("import-smoke OK:", ", ".join(MODULES)) from importlib.metadata import version print("vocalinux", version("vocalinux")) PYEOF python3 /voculinux-smoke.py ;; python3-pywhispercpp) echo "== compiler flag scan of the shipped ggml library" LIBMEMBER=$(tar -tf "$PKGFILE" 2>/dev/null | grep -E "libggml-cpu\.so" | head -n1) [ -n "$LIBMEMBER" ] || { echo "libggml-cpu missing from the built package" >&2 exit 1 } echo "member: $LIBMEMBER" mkdir -p /flagscan tar -xf "$PKGFILE" -C /flagscan "$LIBMEMBER" LIBSCAN="/flagscan/${LIBMEMBER#./}" echo "-- .GCC.command.line:" readelf -p .GCC.command.line "$LIBSCAN" 2>/dev/null || echo "(section absent)" echo "-- .comment:" readelf -p .comment "$LIBSCAN" 2>/dev/null || echo "(section absent)" if readelf -p .GCC.command.line "$LIBSCAN" 2>/dev/null | grep -E "march=native|mcpu=native|mtune=native"; then echo "host-native CPU tuning in the shipped library" >&2 exit 1 fi echo "no host-native tuning in the shipped library" echo "== import smoke $PKGNAME" python3 -c "from pywhispercpp.model import Model; print('model submodule ok')" cat > /smoke.py <<'PYEOF' import glob import os import pywhispercpp pkgdir = os.path.dirname(pywhispercpp.__file__) sitedir = os.path.dirname(pkgdir) libs = sorted(os.path.basename(p) for p in glob.glob(sitedir + "/lib*.so*")) print("shipped libraries:", libs) assert any(n.startswith("libwhisper") for n in libs), "libwhisper missing" exts = [n for n in os.listdir(sitedir) if n.startswith("_pywhispercpp") and n.endswith(".so")] assert exts, "compiled extension missing" print("extension:", exts) has_vulkan = any("vulkan" in n for n in libs) want_vulkan = bool(int(os.environ["EXPECT_VULKAN"])) assert has_vulkan == want_vulkan, "vulkan backend present=%s, expected=%s" % (has_vulkan, want_vulkan) print("smoke ok") PYEOF EXPECT_VULKAN="$EXPECT_VULKAN" python3 /smoke.py ;; python3-PyAudio) echo "== import smoke $PKGNAME" python3 -c "import pyaudio; print('pyaudio', pyaudio.__version__)" ;; python3-pynput) # pynput selects a display backend at import and raises without one; # the container has no display, so presence plus the installed # version (the same proof the native smoke accepts) is the smoke. echo "== import smoke $PKGNAME" python3 -c "import importlib.metadata, importlib.util; assert importlib.util.find_spec('pynput'), 'pynput not importable'; print('pynput', importlib.metadata.version('pynput'))" ;; *) echo "no smoke recipe for package '$PKGNAME' — add one alongside the template" >&2 exit 1 ;; esac