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.
42 lines
1.0 KiB
TOML
42 lines
1.0 KiB
TOML
[package]
|
|
name = "keydr"
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
description = "Terminal typing tutor with adaptive learning"
|
|
license = "AGPL-3.0-only"
|
|
|
|
[dependencies]
|
|
ratatui = { version = "0.30", features = ["crossterm_0_28"] }
|
|
crossterm = "0.28"
|
|
clap = { version = "4.5", features = ["derive"] }
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0"
|
|
toml = "0.8"
|
|
rand = { version = "0.8", features = ["small_rng"] }
|
|
dirs = "6.0"
|
|
rust-embed = "8.5"
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
anyhow = "1.0"
|
|
thiserror = "2.0"
|
|
reqwest = { version = "0.12", features = ["blocking"], optional = true }
|
|
icu_normalizer = { version = "2.1", default-features = false, features = ["compiled_data"] }
|
|
rust-i18n = "4"
|
|
|
|
[dev-dependencies]
|
|
tempfile = "3"
|
|
serde_yaml = "0.9"
|
|
regex = "1"
|
|
criterion = { version = "0.5", features = ["html_reports"] }
|
|
|
|
[[bench]]
|
|
name = "ngram_benchmarks"
|
|
harness = false
|
|
|
|
[[bin]]
|
|
name = "generate_test_profiles"
|
|
path = "src/bin/generate_test_profiles.rs"
|
|
|
|
[features]
|
|
default = ["network"]
|
|
network = ["reqwest"]
|