chore: bound target/ growth — incremental off, line-tables debug
target/ had reached 38 GB, dominated by a 16 GB incremental cache (~28 compilation units × every historical config, never evicted) and ~25 separate integration-test binaries each statically embedding the bundled engine + full debug info. [profile.dev] (inherited by the test profile): - incremental = false: the cache earns little in a full-suite workflow and never self-evicts; off, target/ stays bounded. - debug = "line-tables-only": keeps file:line in panics/backtraces (we debug via tracing logs) at a fraction of debug=2's size. Net: a clean full build dropped from 38 GB to ~1.6 GB. Document the rationale plus the cargo-sweep workflow (the GC cargo lacks) under a new CLAUDE.md "Build hygiene" section; also drop the now-shipped H1 from CLAUDE's deferred list (H1a remains).
This commit is contained in:
@@ -187,6 +187,60 @@ Key invariants in the code:
|
||||
`git commit` is preceded by an explicit message proposal
|
||||
and user approval. No AI attribution in commit messages.
|
||||
|
||||
## Build hygiene
|
||||
|
||||
`target/` is git-ignored and 100% regenerable, but it grows
|
||||
without bound — cargo never garbage-collects old hash-suffixed
|
||||
artifacts, so stale test binaries (each ~100 MB, statically
|
||||
linking the bundled engine + debug info), incremental-compile
|
||||
caches, and orphaned example binaries pile up across sessions
|
||||
(it reached **~38 GB** before the first sweep).
|
||||
|
||||
Two prevention levers are configured in `Cargo.toml` `[profile.dev]`
|
||||
(the `test` profile inherits both):
|
||||
|
||||
- **`incremental = false`** — the incremental cache alone reached
|
||||
**16 GB** here (≈28 compilation units × every historical config,
|
||||
never evicted), for little benefit in a full-`cargo test` workflow.
|
||||
Off, it never regrows; the cost is whole-crate recompiles instead of
|
||||
partial — seconds for a crate this size.
|
||||
- **`debug = "line-tables-only"`** — the default `debug = 2` is
|
||||
~85–90 % of each test binary; line tables keep file:line in panics
|
||||
and backtraces (we debug via `tracing` logs) at a fraction of the
|
||||
size.
|
||||
|
||||
Even with those, stale artifacts still accumulate (cargo has no
|
||||
target/ eviction). **Run `cargo sweep` every now and then** to reclaim
|
||||
that — `cargo-sweep` (installed) prunes everything *except* the current
|
||||
build's artifacts:
|
||||
|
||||
- **Keep only the current build (the usual sweep):** stamp,
|
||||
build, then delete everything the build didn't touch —
|
||||
```
|
||||
cargo sweep --stamp
|
||||
cargo build --all-targets # touch the artifacts to keep
|
||||
cargo sweep --file # remove everything older than the stamp
|
||||
```
|
||||
Add `--dry-run` to `--file` first to preview what goes. Caveat:
|
||||
`build --all-targets` only updates the mtime of what it
|
||||
actually (re)builds, so already-fresh *dependency* artifacts
|
||||
fall before the stamp and get swept too — they recompile once
|
||||
on the next build (a one-time cost; everything is regenerable).
|
||||
The first 38 GB → 20 GB sweep freed **19 GiB** this way.
|
||||
- **Lighter routine options:** `cargo sweep --time 30` drops
|
||||
artifacts untouched for 30+ days; `cargo sweep --maxsize 10GB`
|
||||
trims oldest until under a size cap.
|
||||
- **`--installed` is *not* the tool for same-toolchain cruft.**
|
||||
It keeps only artifacts from currently-installed rustup
|
||||
toolchains, so it frees space *only after you uninstall/replace
|
||||
a toolchain*. For the usual "many builds, one toolchain"
|
||||
accumulation it cleans **nothing** (verified: it would free 0
|
||||
here) — use the stamp/file workflow instead.
|
||||
|
||||
A good cadence is a sweep between major milestones (e.g. at
|
||||
session handoff). `cargo clean` remains the nuclear option (wipes
|
||||
all of `target/`, forcing a full from-scratch rebuild).
|
||||
|
||||
## Things deliberately deferred
|
||||
|
||||
These are explicitly tracked (mostly in `requirements.md`) but
|
||||
@@ -202,11 +256,11 @@ not yet implemented:
|
||||
- **m:n convenience** (C4): auto-generates a junction table
|
||||
with appropriate FKs — depends on relationships being solid
|
||||
(they are).
|
||||
- **Friendly error layer** (H1): partial — FK errors are
|
||||
enriched both ways; full SQL→English translation pending.
|
||||
- **Strong syntax-help in parse errors** (H1a): point users at
|
||||
missing keywords/clauses rather than the unexpected
|
||||
character.
|
||||
character. *(H1 — the friendly **database**-error layer — is
|
||||
done, ADR-0019; H1a is its separate parse-error sibling,
|
||||
ADR-0021, still partial.)*
|
||||
- **Tutorial/lesson system**: acknowledged as in scope for
|
||||
design; needs its own ADR.
|
||||
- **Session log + Markdown export** (V4): the bigger UX
|
||||
|
||||
+15
@@ -45,6 +45,21 @@ insta = { version = "1.47.2", features = ["yaml"] }
|
||||
pretty_assertions = "1.4.1"
|
||||
tempfile = "3.27.0"
|
||||
|
||||
# Dev/test build hygiene (see CLAUDE.md "Build hygiene"). `cargo test`
|
||||
# links ~25 separate integration-test binaries, each statically
|
||||
# embedding the bundled engine + every dependency; the `test` profile
|
||||
# inherits these from `dev`.
|
||||
# - incremental = false: the incremental cache reached 16 GB here for
|
||||
# little benefit in a full-suite workflow; disabling it keeps target/
|
||||
# bounded.
|
||||
# - debug = "line-tables-only": full debug info (the default `debug = 2`)
|
||||
# is ~85-90% of each test binary; line tables keep file:line in panics
|
||||
# and backtraces (we debug via `tracing` logs, not a step-debugger) at
|
||||
# a fraction of the size.
|
||||
[profile.dev]
|
||||
incremental = false
|
||||
debug = "line-tables-only"
|
||||
|
||||
[lints.rust]
|
||||
unsafe_code = "forbid"
|
||||
unreachable_pub = "warn"
|
||||
|
||||
Reference in New Issue
Block a user