Package scoot offline
Build scoot the way a distro builder does: from a source tree that
needs no network, with a toolchain and system libraries you provide.
Start here if you maintain the Arch, deb or rpm package. The Arch
PKGBUILDs (release and -git) build on this page
(packaging/arch/). The deb (packaging/deb, deb.)
and rpm recipes also exist (deb, rpm). All three
workflows are manual-only, and no packages are shipped yet.
Get the sources
Section titled “Get the sources”Releases ship a vendored tarball: the exact tagged tree plus vendor/
(every dependency, crates.io and git alike), .
(source replacement pointing at vendor/), THIRD-PARTY-LICENSES (every
locked crate and its license) and OFFLINE-BUILD. (the same build
below, readable with no network). One command makes the same tarball
from any clean checkout:
scripts/vendor-release.sh --out ./dist --check-offline--check-offline builds the staged tree under an empty CARGO_HOME
with CARGO_NET_OFFLINE before tarring it, so any network access fails
the run. The tree it stages is git archive HEAD: reproducible from
the commit, never the working tree.
Unpack and build (from the unpacked source/ directory):
cargo build --workspace --locked --offline--locked is required: Cargo. is committed, and every build here
and in CI uses it, so the tree you audit is the tree that builds. The
two git dependencies (the Smithay fork and the wayland-backend fork)
resolve out of vendor/ through this snippet. It is already in the
tarball’s .; it is the part most likely to break, and
CI’s vendor job re-proves it on every dependency change:
[source.crates-io]replace-with = "vendored-sources"
[source."git+https://github.com/scoot-sh/smithay?rev=fdf424d633fc15736a4a9c967b4e04a9e1e90077"]git = "https://github.com/scoot-sh/smithay"rev = "fdf424d633fc15736a4a9c967b4e04a9e1e90077"replace-with = "vendored-sources"
[source."git+https://github.com/scoot-sh/wayland-rs?rev=70f81e005179463fb4d46ac68045a7f21eb5aff2"]git = "https://github.com/scoot-sh/wayland-rs"rev = "70f81e005179463fb4d46ac68045a7f21eb5aff2"replace-with = "vendored-sources"
[source.vendored-sources]directory = "vendor"What you need
Section titled “What you need”A Rust toolchain at or past the workspace floor, and the system
libraries below. They are what ldd reported on a release build
(cargo build --release -p scoot, aarch64, 2026-10-07). Your package
depends on the sonames; store paths are NixOS’s, not yours.
| Feature set | Links (sonames) | Release scoot |
|---|---|---|
default (GPU scanout tier + xwayland, both on) |
libinput.so.10, libseat.so.1, libudev.so.1, libpixman-1.so.0, libxkbcommon.so.0 (plus glibc, libgcc_s and their transitive closure: libevdev, libmtdev, libwacom, libgudev, libsystemd, glib); no new system library for xwayland (pure-Rust X protocol over a socket), but needs the Xwayland binary on PATH at run time |
8.3 MB |
--no-default-features (CPU-only minimal) |
as default, minus nothing linked (there is neither GBM nor X11 code to link) | 6.7 MB |
Notes on the table: sizes are cargo build --release -p scoot on
aarch64. The default build compiles the scanout tier but links no GPU
stack, because it must run on a box with no GPU libraries installed;
CI fails a default build that references libgbm. libEGL and
libGLESv2 never appear in ldd for any build: the GLES renderer
loads them with dlopen. The scanout tier provides the
GBM scanout tier;
without it (--no-default-features) --tty presents through DRM dumb
buffers. On Debian 13 the sonames above resolve to libinput10,
libseat1, libudev1, libpixman-1-0, libxkbcommon0 (plus
libgbm1, libdrm2 as run-time Suggests, never Depends), checked
against trixie’s own Contents-amd64.. Other distros map the same
sonames through their own file search.
scootlaunch links two system libraries past the C library:
libxkbcommon. for its panel keyboard and libm. (through
the default-on SVG icon stack). A release build’s NEEDED is
libxkbcommon., libgcc_s., libm., libc.
(measured 2026-10-19 on aarch64 at 2167544 bytes stripped).
libm. ships inside the C library package everywhere, so the
packaging delta is one name: libxkbcommon. resolves to
libxkbcommon0 on Debian, Ubuntu and openSUSE and to libxkbcommon
on Fedora and Arch, the name each of the four package recipes depends
on. The headless commands (--list, --query, --run-id) never call
either library, but the loader needs them present to start the binary
at all.
scootnotify links nothing past the C library, like the bar and the
wallpaper daemon (the deb allow-list and the rpm and Arch recipes carry
no other name for it). Its cards draw text only with a font; without
one the daemon stays headless and the bus still serves. So the font is
a suggestion (deb Suggests, Arch optdepends; the rpm names none),
never a dependency. The same holds for the look swap: apply carries a
missing family through the fallback chain with a note instead of
refusing, so no font package becomes a dependency on any channel.
Bookworm ships no package for the Nerd families the shipped looks name
(fonts-firacode is the unpatched family), so the suggestion stays
DejaVu plus the fallback.
scoot-globalshortcuts-portal links nothing past the C library either.
It draws nothing, so it needs no font, not even as a suggestion.
Toolchain floor: Rust 1.88
Section titled “Toolchain floor: Rust 1.88”The workspace sets rust-version = "1.. This table shows which
distro releases ship at least that, checked 2026-10-07 against each
distro’s own package metadata. Verify again at packaging time, because
toolchains move:
| Distro | rustc | Builds from the distro toolchain? |
|---|---|---|
| Debian 13 trixie | 1.85.1 | No — use rustup or trixie-backports/sid |
| Debian 12 bookworm | 1.63 | No |
| Debian sid | 1.96.1 | Yes |
| Ubuntu 24.04 noble | 1.75 | No |
| Ubuntu 25.10 questing | 1.85.1 | No |
| Ubuntu 26.04 resolute | 1.93.1 | Yes |
| Fedora 43 | 1.99.0 | Yes |
| Arch | 1.99.0 | Yes |
| Alpine edge | 1.99.0 | Yes |
| openSUSE Tumbleweed | 1.98.1 | Yes |
| Nix / NixOS | the flake’s pinned toolchain | Yes (never the distro’s) |
Debian stable and Ubuntu up to 25.10 cannot build scoot from their own toolchain today; they need rustup or a newer distro.
Forks: what is pinned and why
Section titled “Forks: what is pinned and why”Two dependencies are scoot-sh forks, pinned by exact rev. The full list, with the alternatives considered for each, is in dev/forks.md:
| Fork | Pinned rev | Why it exists |
|---|---|---|
scoot-sh/smithay (scoot/cursor-dmabuf-storage, on upstream 0ff00983) |
fdf424d6 |
27 carried commits: a syncobj-timeline Drop, XWayland selection/drag fixes, a pixman upscale-edge clamp, a buffer-scale-without-new-buffer fix, an XSETTINGS flush, compositor-owned dma-buf scanout, and a clean shutdown on a lost seat |
scoot-sh/wayland-rs (scoot/server-fd-queue-cap-adaptive, on the 0.3.17 release) |
70f81e00 |
bounds the backend’s queue of received-but-unclaimed fds, so one idle client cannot fill the compositor’s fd table; pinned as [patch. |
A fork is the last resort, and each entry records what was tried instead. Nothing is sent upstream from this project; whether to offer a fix upstream is the maintainer’s later decision. Repinning either fork changes its checkout hash: the Nix build records both hashes and fails on drift, and the vendor job re-proves the offline build.
Licenses and advisories
Section titled “Licenses and advisories”scoot itself is MIT. Every third-party crate in the tarball is listed
with its license in THIRD-PARTY-LICENSES, generated by cargo deny list at staging time. CI enforces the allow-list in deny.
(permissive only: MIT, Apache-2.0, ISC, BSD-3-Clause, Unicode-3.0,
Zlib, Unlicense, 0BSD) and fails on anything outside it. Copyleft
needs an explicit maintainer decision recorded in that file before it
can land. The same tool checks RustSec advisories on
every dependency change and on a weekly schedule; two accepted risks
are recorded in deny. with reasons (an archived proc-macro with
no runtime exposure, and an unmaintained font parser that reads only
local fonts); anything new fails CI.
Symptoms
Section titled “Symptoms”- The offline build tries the network.
.is missing or not this file: the build must run from the unpacked tarball (or acargo/config. toml vendor-release.staging tree), not from a baresh git clone. With the config in place and--offline, cargo fails rather than fetching, and the failure names the crate it could not find vendored. error: the lock file needs updating. The build was run without--locked, or the tree was modified after staging. Re-stage from a clean checkout and keep--locked.rustc 1.. The toolchain predates the floor (see the table above): rustup to 1.88 or newer, or a distro release whose toolchain qualifies.XX is not supported Xwayland must be on PATHat run time. An--features xwaylandbuild on a box without XWayland installed: the feature builds fine anywhere, but starting it needs the X server binary beside it.
