diff options
| author | Adam Malczewski <[email protected]> | 2026-06-14 01:20:04 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-14 01:20:04 +0900 |
| commit | 4fd36d643f9c66455e245eb65f5f9f916200ed5a (patch) | |
| tree | 31ebb46a86ade056d5fc0915d131672beedf6df2 | |
| parent | 74578ea9257ff9118f732bb90599cfc44101da4f (diff) | |
| download | unbox-4fd36d643f9c66455e245eb65f5f9f916200ed5a.tar.gz unbox-4fd36d643f9c66455e245eb65f5f9f916200ed5a.zip | |
packaging: pacman PKGBUILD + static toml++ + remote build script
- host-bin: install the `unbox` binary (install: true) so `meson install`
(and the package) ship /usr/bin/unbox. Assets already install via the
top-level install_subdir to /usr/share/unbox.
- ext-keybindings: force the toml++ subproject to default_library=static.
Its wrapped meson.build hardcodes default_library=shared, which made the
installed binary NEED libtomlplusplus.so.3 at runtime (only resolvable in
the dev tree via LD_LIBRARY_PATH). Static-linking bakes it in.
- packaging/PKGBUILD: builds the working tree (reuses synced subprojects, no
network), plain meson (no devtools needed), options=(!debug), and ALWAYS
configures a fresh build dir — a reused/stale dir silently drops subproject
option overrides (this is what reintroduced the shared-toml regression).
- packaging/start-unbox: dbus-run-session -- unbox (mirrors start-labwc.sh).
- packaging/build-remote.sh: rsync the tree to the fast box (builder),
makepkg there, ferry the .pkg.tar.zst back, pacman -U here. Self-verifies
the packaged + installed binary has no unresolved/shared-toml dependency
(extracting to a real file — readelf can't read a non-seekable pipe).
Runtime NEEDED is now only system libs (wlroots-0.20, wayland, xkbcommon,
freetype, EGL, GLESv2, libstdc++/m/gcc_s/c) — installs + runs on the CF-AX3.
| -rw-r--r-- | packages/ext-keybindings/meson.build | 11 | ||||
| -rw-r--r-- | packages/host-bin/meson.build | 1 | ||||
| -rw-r--r-- | packaging/PKGBUILD | 66 | ||||
| -rwxr-xr-x | packaging/build-remote.sh | 73 | ||||
| -rwxr-xr-x | packaging/start-unbox | 10 |
5 files changed, 158 insertions, 3 deletions
diff --git a/packages/ext-keybindings/meson.build b/packages/ext-keybindings/meson.build index 4573810..d56af40 100644 --- a/packages/ext-keybindings/meson.build +++ b/packages/ext-keybindings/meson.build @@ -11,9 +11,14 @@ ext_keybindings_inc = include_directories('include') -# toml++ (header-only): an APPROVED dep (notes/plan.md §2), first use here as a -# Meson wrap kept private to THIS unit (subprojects/tomlplusplus.wrap). -tomlplusplus_dep = dependency('tomlplusplus') +# toml++: an APPROVED dep (notes/plan.md §2), a Meson wrap kept private to THIS +# unit (subprojects/tomlplusplus.wrap). Force default_library=static: the wrapped +# subproject's own meson.build hardcodes default_library=shared, which would make +# the installed `unbox` binary NEED libtomlplusplus.so.3 at runtime (only found in +# the dev build via LD_LIBRARY_PATH; absent from a system install). Linking it +# statically bakes it into the binary — correct for both dev and the package. +tomlplusplus_dep = dependency('tomlplusplus', + default_options: ['default_library=static']) # Glue library. Needs the kernel ABI, ext-xdg-shell's public contract (the glue # includes its header to consume the Service + Toplevel), ext-stage-dock's public diff --git a/packages/host-bin/meson.build b/packages/host-bin/meson.build index 1c1b5a1..76f0e75 100644 --- a/packages/host-bin/meson.build +++ b/packages/host-bin/meson.build @@ -5,4 +5,5 @@ executable( 'unbox', 'src/main.cpp', dependencies: [kernel_dep, ext_xdg_shell_dep, ext_layer_shell_dep, ext_keybindings_dep, ext_stage_dock_dep], + install: true, ) diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD new file mode 100644 index 0000000..312e715 --- /dev/null +++ b/packaging/PKGBUILD @@ -0,0 +1,66 @@ +# Maintainer: user +# +# Local PKGBUILD for the unbox Wayland desktop environment. Builds the CURRENT +# WORKING TREE (the repo this PKGBUILD lives in), not a clean VCS checkout — so +# `makepkg` packages exactly what is checked out, and reuses the already-fetched +# meson subprojects (RmlUi/doctest/toml++) under ../subprojects with no network. +# +# Build + install on this machine: +# cd packaging && makepkg -si +# Rebuild after changes: makepkg -sif Remove: pacman -R unbox + +pkgname=unbox +pkgver=0.0.1 +pkgrel=1 +pkgdesc="Experimental Wayland desktop environment: monolithic wlroots compositor + embedded RMLUi" +arch=('x86_64') +url="https://github.com/anomalyco/opencode" +license=('custom') +# Runtime libraries (RMLUi, doctest, toml++ are static meson subprojects, so they +# are NOT runtime deps). dbus provides dbus-run-session for the session wrapper. +depends=('wlroots0.20' 'wayland' 'libxkbcommon' 'pixman' 'libglvnd' 'freetype2' + 'seatd' 'dbus') +makedepends=('meson' 'ninja' 'cmake' 'wayland-protocols' 'pkgconf') +provides=('unbox') +conflicts=('unbox-git') +# No separate -debug package (buildtype=plain, no -g); keep it to one artifact. +options=('!debug') +source=() + +# NOTE: $srcdir/$startdir/$pkgdir are only set INSIDE the functions, so the build +# dir + source root are computed there (the repo root is packaging/..). + +build() { + # Plain meson (no devtools/arch-meson dependency, so this builds on any Arch + # box). Source is the WORKING TREE; the build dir is private to makepkg + # ($srcdir/build) so the dev build/ and build-asan/ trees are untouched. The + # meson subprojects (RmlUi/doctest/toml++) come along in the synced tree. + # + # ALWAYS configure fresh: the toml++ default_library=static override (and any + # other subproject option) only applies on a subproject's FIRST configuration, + # so a reused/stale build dir would silently fall back to the wrapped default + # (shared) and reintroduce the libtomlplusplus.so runtime dependency. + rm -rf "$srcdir/build" + meson setup --prefix=/usr --libexecdir=lib --buildtype=plain \ + -Db_pie=true "$startdir/.." "$srcdir/build" + meson compile -C "$srcdir/build" +} + +package() { + # Installs /usr/bin/unbox + /usr/share/unbox/<unit>/*.rml,*.rcss (the assets + # the compiled-in UNBOX_ASSET_DIR_DEFAULT=/usr/share/unbox resolves at runtime). + meson install -C "$srcdir/build" --destdir "$pkgdir" + + # The session wrapper (dbus-run-session -- unbox), mirroring start-labwc.sh. + install -Dm755 "$startdir/start-unbox" "$pkgdir/usr/bin/start-unbox" + + # A wayland-sessions entry so a display manager (if ever used) can list unbox; + # harmless on a bare-TTY setup. + install -Dm644 /dev/stdin "$pkgdir/usr/share/wayland-sessions/unbox.desktop" <<'EOF' +[Desktop Entry] +Name=unbox +Comment=Experimental wlroots + RMLUi Wayland desktop +Exec=start-unbox +Type=Application +EOF +} diff --git a/packaging/build-remote.sh b/packaging/build-remote.sh new file mode 100755 index 0000000..b522284 --- /dev/null +++ b/packaging/build-remote.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# build-on-builder.sh — build the unbox pacman package on the fast box (builder) +# and install it here on the slow CF-AX3. +# +# 1. rsync the working tree to builder:~/unbox +# 2. makepkg -s there (installs build deps via sudo ON builder — you'll be +# prompted for that machine's sudo password) +# 3. scp the built .pkg.tar.zst back to /tmp here +# 4. pacman -U here (you'll be prompted for THIS machine's sudo password) +# +# Re-runnable: edit code, run again. Safe to Ctrl-C. + +set -euo pipefail + +REMOTE="${REMOTE:-builder}" +REMOTE_DIR="${REMOTE_DIR:-unbox}" # ~/unbox on builder +LOCAL_REPO="${LOCAL_REPO:-/home/user/projects/unbox}" +PKGOUT="${PKGOUT:-/tmp/unbox-pkg}" + +echo "==> [1/4] Sync source -> $REMOTE:$REMOTE_DIR" +rsync -az --info=progress2 \ + --exclude 'build*/' \ + --exclude '.git/' \ + --exclude '.cache/' \ + --exclude 'packaging/src/' \ + --exclude 'packaging/pkg/' \ + --exclude 'packaging/*.pkg.tar.zst' \ + "$LOCAL_REPO/" "$REMOTE:$REMOTE_DIR/" + +echo "==> [2/4] Build package on $REMOTE (installs makedeps via its sudo)" +# -t: give makepkg a tty so the remote sudo password prompt works. +# -Cf: -C cleans $srcdir first (no stale build dir -> subproject options like +# toml++ default_library=static always apply), -f overwrites the package. +# Then verify the packaged binary links NO shared toml (extract to a real file; +# readelf cannot read a non-seekable pipe). Abort loudly if it still does. +ssh -t "$REMOTE" " + set -e + cd '$REMOTE_DIR/packaging' + makepkg -sCf --noconfirm + f=\$(mktemp) + bsdtar -xOf unbox-*.pkg.tar.zst usr/bin/unbox > \"\$f\" + if readelf -d \"\$f\" | grep -qi tomlplusplus; then + echo '!! packaged binary STILL links libtomlplusplus.so — build did not go static' >&2 + rm -f \"\$f\"; exit 1 + fi + rm -f \"\$f\" + echo '==> remote package verified: toml is static (no .so dependency)' +" + +echo "==> [3/4] Ferry the built package back -> $PKGOUT" +mkdir -p "$PKGOUT" +scp "$REMOTE:$REMOTE_DIR/packaging/unbox-*.pkg.tar.zst" "$PKGOUT/" + +PKG="$(ls -t "$PKGOUT"/unbox-*.pkg.tar.zst | head -1)" +if [ -z "$PKG" ]; then + echo "!! no package was produced" >&2 + exit 1 +fi + +echo "==> [4/4] Install here: $PKG" +sudo pacman -U "$PKG" + +# Post-install sanity check on the actually-installed binary. +if ldd /usr/bin/unbox 2>/dev/null | grep -qi 'not found'; then + echo "!! installed /usr/bin/unbox still has unresolved libraries:" >&2 + ldd /usr/bin/unbox | grep -i 'not found' >&2 + exit 1 +fi + +echo +echo "==> Done. Installed $(basename "$PKG") — all libraries resolve." +echo " Binary: /usr/bin/unbox Session wrapper: /usr/bin/start-unbox" +echo " Assets: /usr/share/unbox/" diff --git a/packaging/start-unbox b/packaging/start-unbox new file mode 100755 index 0000000..d90a2f6 --- /dev/null +++ b/packaging/start-unbox @@ -0,0 +1,10 @@ +#!/bin/sh +# start-unbox — launch the unbox Wayland session (mirrors start-labwc.sh). +# +# Wraps unbox in `dbus-run-session` so unbox and everything its session spawns +# (PipeWire, WirePlumber, future portals) share a single D-Bus *session* bus. +# Without this there is no session bus on Artix/s6, which breaks portals and +# makes PipeWire spam RTKit "ServiceUnknown" warnings. +# +# Usage: from a TTY, run start-unbox +exec dbus-run-session -- unbox |
