Replace the 'known remaining inefficiency' section with the layout that
now exists, plus the measured before/after (clean release build: 2m14s
-> 1m46s wall, keydr units 61.0s -> 32.4s, peak ~2.0 GB unchanged).
Add a maintenance note: new modules go in src/lib.rs, not src/main.rs.
Re-declaring them in the binary would silently restore the double
compile this refactor removed.
The previous text claimed restructuring main.rs to use the lib crate
would 'roughly halve' build time. Measured with --timings on a clean
release build, that was wrong:
33.7s keydr (bin)
26.0s keydr (lib)
1.4s generate_test_profiles (bin)
61.0s of 292.2s total unit-seconds (21%)
The duplicated units are indeed the two slowest in the graph, but the
saving is ~26s of unit-work (less in wall time, since they overlap with
dependency compilation across 3 jobs), not half the build. The other
~79% is one-time dependency compilation that incremental builds skip.
Replace the estimate with the measurement.
systemd-oomd is desktop-only on Ubuntu (reverse-deps are ubuntu-desktop*);
'systemctl is-enabled systemd-oomd' returns not-found on this server, so
the previous advice to enable it would simply have failed. Recommend
earlyoom instead, with --avoid/--prefer tuned to protect the shell and
target rustc.
Also document the machine-wide alternatives to per-project tuning:
- sudo systemctl set-property user-1000.slice MemoryHigh=/MemoryMax=
(covers every shell and build; sshd lives in system.slice so it can
never lock you out)
- global ~/.cargo/config.toml, which does support [profile.*]
Clarify that the MemoryHigh warning applies to short-lived build scopes,
not to slice-level limits where gradual throttling is appropriate.
Release builds consumed 5+ GB and never completed on a 4-core / 7.6 GB
VM, thrashing the machine badly enough to lose SSH access.
Root cause was a codegen bug in rust-i18n v3, not machine size. Its
macro emitted one HashMap::from([...]) and one add_translations() call
per translation string, all in a single function body -- 8,652 of each
for our 21 locales / ~9,000 keys. LLVM scales superlinearly on function
size, so optimising that one initialiser took ~4.5 GB.
Verified via cargo expand (lib target):
v3.1.5 v4.2.1
HashMap::from 8,652 0
add_translations 8,652 21 (one per locale)
expanded lines 93,026 73,444
Fixed upstream in v4.0.0.
Clean release builds, same machine:
v3, opt-level=3, thin LTO 5.2 GB stalled >18m, never finished
v3, opt-level=1, no LTO 1.8 GB 15m30s (previous workaround)
v4, opt-level=3, thin LTO 2.08 GB 3m25s
v4, stock cargo defaults 1.92 GB 2m17s
Also:
- Remove the opt-level=1 / lto=false workaround; cargo's release
defaults are correct now. No shipped code is de-optimised.
- Keep only genuine small-machine hygiene in .cargo/config.toml:
jobs=3 (keeps the box interactive), lld linker, and trimmed debug
info on dev/test profiles.
- Document the diagnosis, the cargo expand / llvm-lines workflow that
found it, and the systemd-based safety nets in docs/BUILDING.md.
- Note in main.rs why i18n! must appear in both crate roots (t! expands
to crate::_rust_i18n_t, and main.rs re-declares the module tree
rather than depending on the lib target).
Test suite passes; release binary verified working.