Skip to main content

max / alloy

Let a rust image rebuild shop, not just alloy A LANGS=rust image had cargo, rustc and cc and still could not build the terminal it ships and runs. Measured 2026-09-07 on the fw12 mint: pkg-config found none of wayland-client, xkbcommon or fontconfig. The runtime libraries were always there, only the headers were missing. So the rust arm now carries wayland-devel, libxkbcommon-devel and fontconfig-devel, asserted afterwards through pkg-config rather than assumed. They hang off that arm rather than the base because headers with no compiler are weight nobody can use. 79 MiB across 61 packages, beside the 610 MiB of the toolchain they arrive with. This restores, for one tier, the "you can rebuild what we ship" rule this file dropped when the Go tier was priced. The objection that killed it stands: the C tier wants meson, ninja, wayland-protocols and a -devel spread no language toggle models, and nothing here changes that. What changed is the judgement about an uneven rule, which is worth more than no rule when the even part is the software Alloy writes rather than packages.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01WFBzMprSmNCfvdj2cGZyka
Author: Max Johnson <me@maxj.phd> · 2026-09-07 18:02 UTC
Signed with PGP, not checked
Commit: 187fdecfc2c2cc683ea28a2c6abb5aa6659706ed
Parent: ebeba0e
1 file changed, +39 insertions, -2 deletions
M Containerfile +39 -2
@@ -878,6 +878,14 @@
878 878 # the trade, and it is reversible at zero cost, which most things here are
879 879 # not.
880 880 #
881 + # PARTLY REVISITED 2026-09-07. The hole described above is why the rule was
882 + # dropped, and it is still there for the C tier. The Rust tier is not: the
883 + # language block below now carries wayland-devel, libxkbcommon-devel and
884 + # fontconfig-devel on the rust arm, so a LANGS=rust image can rebuild alloy
885 + # and shop, the two programs Alloy writes rather than packages. The reasoning
886 + # is beside that install; the short version is that an uneven rule beats no
887 + # rule when the even part is our own software.
888 + #
881 889 # python and zig are off for the same reason, which is the rule: nothing
882 890 # in the image requires them.
883 891 #
@@ -2105,10 +2113,35 @@
2105 2113 # which is most of why the build-host role works at all. The empty
2106 2114 # default is profile-blind for the same reason — a client image has no
2107 2115 # more claim on a compiler than a server one.
2116 + #
2117 + # THREE -devel PACKAGES RIDE WITH rust, and they are not the language's.
2118 + # wayland-devel, libxkbcommon-devel and fontconfig-devel are what shop
2119 + # links against, and shop is the terminal this image ships and runs. The
2120 + # runtime libraries were always here; only the headers were missing, so a
2121 + # machine with a full Rust toolchain still could not rebuild its own
2122 + # terminal. Measured 2026-09-07 on a LANGS=rust image: cargo, rustc and
2123 + # cc all present, and pkg-config found none of the three.
2124 + #
2125 + # Attached to the rust arm rather than installed unconditionally, because
2126 + # headers with no compiler are weight nobody can use. 79 MiB installed
2127 + # across 61 packages, beside the 610 MiB of the toolchain they arrive with.
2128 + #
2129 + # THIS RESTORES A RULE THIS FILE ONCE DROPPED, for the tier it covers.
2130 + # The rule was "you can rebuild what we ship", and it was dropped where
2131 + # the Go tier was priced, because it had never been applied evenly: the C
2132 + # tier (sway, mako, swaylock) wants meson, ninja, wayland-protocols and a
2133 + # -devel spread no language toggle models, so the rule was two thirds true
2134 + # and quietly false for the rest. That objection stands and is not
2135 + # answered here. What changed is the judgement about it: an uneven rule is
2136 + # worth more than no rule when the even part is the software Alloy itself
2137 + # writes. alloy and shop are that part, and a LANGS=rust image now builds
2138 + # both. The Go tier still needs LANGS=rust,go and the C tier still has no
2139 + # dial.
2108 2140 RUN set -eu; \
2109 2141 for lang in $(echo "$LANGS" | tr ',' ' '); do \
2110 2142 case "$lang" in \
2111 - rust) dnf install -y rust cargo ;; \
2143 + rust) dnf install -y rust cargo \
2144 + wayland-devel libxkbcommon-devel fontconfig-devel ;; \
2112 2145 go) dnf install -y golang ;; \
2113 2146 python) dnf install -y python3 python3-pip ;; \
2114 2147 zig) dnf install -y zig ;; \
@@ -2118,7 +2151,11 @@
2118 2151 dnf clean all; \
2119 2152 for lang in $(echo "$LANGS" | tr ',' ' '); do \
2120 2153 case "$lang" in \
2121 - rust) command -v cargo >/dev/null || { echo "rust was asked for and cargo is not in the image" >&2; exit 1; } ;; \
2154 + rust) command -v cargo >/dev/null || { echo "rust was asked for and cargo is not in the image" >&2; exit 1; }; \
2155 + for mod in wayland-client xkbcommon fontconfig; do \
2156 + pkg-config --exists "$mod" \
2157 + || { echo "rust was asked for and $mod has no pkgconfig file; shop cannot be rebuilt on this image" >&2; exit 1; }; \
2158 + done ;; \
2122 2159 go) command -v go >/dev/null || { echo "go was asked for and the go binary is not in the image" >&2; exit 1; } ;; \
2123 2160 python) command -v python3 >/dev/null || { echo "python was asked for and python3 is not in the image" >&2; exit 1; } ;; \
2124 2161 zig) command -v zig >/dev/null || { echo "zig was asked for and the zig binary is not in the image" >&2; exit 1; } ;; \