perf: build optimization (P0/P1/P2)#26
Merged
Merged
Conversation
…nged On a successful build, writes target/.build_cache with the output dir and ninja binary path. On the next invocation, if build.ninja in that dir is newer than all source files and mcpp.toml, invokes ninja directly without re-running toolchain resolve, scanner, make_plan, or emit. Reduces no-change builds from ~10s to <0.5s.
Replace the global build.ninja.dd (one dyndep file for all modules) with per-file .dd files. Each .cppm gets its own .ddi → .dd conversion via the new cxx_dyndep rule, and each compile edge references only its own .dd file. Before: touching one file → all 39 modules dirty → full rebuild (~21s) After: touching one file → only that file's .dd dirty → incremental New `mcpp dyndep --single --output <file.dd> <file.ddi>` mode added for the per-file conversion. Legacy multi-file mode still available.
GCC always updates the .gcm (BMI) file's timestamp even when the module interface hasn't changed. This causes all downstream modules to be recompiled unnecessarily. Fix: the cxx_module rule now backs up the BMI before compilation, and if the new BMI is byte-identical to the backup, restores the old file (preserving its timestamp). Combined with restat = 1 in the per-file dyndep entries, ninja skips downstream modules when only the implementation changed. This means modifying a function body without changing the module interface no longer triggers a cascade rebuild of all importers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three build performance optimizations for incremental compilation:
P0: Frontend dirty check — skip
prepare_build(toolchain resolve, scanner, make_plan) whenbuild.ninjais newer than all source files +mcpp.toml. Reduces no-change builds from ~10s to <0.5s.P1: Per-file dyndep — replace the global
build.ninja.ddwith per-file.ddfiles. Each.cppmgets its own.ddi → .ddconversion. Modifying one file no longer marks all 39 modules dirty.P2: BMI copy_if_different — backup
.gcmbefore compilation, restore old file if byte-identical. Combined withrestat = 1, prevents cascade rebuilds when only implementation changes (not interface).Test plan
mcpp buildsucceeds (full build)mcpp test— all 86 unit tests pass.ddfiles