Repository navigation
mcpp run recursively scans large submodules despite explicit source glob #225
Description
Summary
mcpp run performs a full recursive filesystem scan of large unrelated directories before running a cached root package. With large Git submodules under the repository root, this adds approximately 9.5 seconds to every invocation, even when no compilation is required.
This is especially visible for repositories that keep upstream test corpora or benchmarks as submodules under compat/.
Environment
- mcpp:
0.0.93 - host: Linux x86_64
- toolchain: GCC
16.1.0 - project: source-only C++26 workspace/package
- root package source pattern inferred by mcpp:
src/**/*.{cppm,cpp,cc,c}
The project has large read-only Git submodules which are not package sources:
compat/bun
compat/node
The root package sources are only under:
src/
Reproduction
From the project root:
/usr/bin/time -f 'real=%e user=%U sys=%S' mcpp run -- --version
/usr/bin/time -f 'real=%e user=%U sys=%S' mcpp run -- --versionObserved:
Finished release [optimized] in 0.03s
Running target/.../mbun
1.3.14
real=9.57 user=4.55 sys=4.99
Finished release [optimized] in 0.03s
Running target/.../mbun
1.3.14
real=9.50 user=4.61 sys=4.86
The same binary does not have this startup cost:
/usr/bin/time -f 'real=%e user=%U sys=%S' target/.../mbun --versionObserved:
1.3.14
real=0.00 user=0.00 sys=0.00
A regular cached build is also fast:
/usr/bin/time -f 'real=%e user=%U sys=%S' mcpp buildObserved:
Finished release [optimized] in 0.02s
real=0.04 user=0.03 sys=0.01
Filesystem evidence
Tracing only file-related syscalls for mcpp run for 15 seconds produced approximately 1,434,120 file operations before timeout. The paths were dominated by unrelated submodules:
compat/node 377,254 path references
compat/bun 133,626 path references
compat 67,084 path references
.mcpp/.xlings 44,676 path references
The command used was:
timeout 15s strace -f -qq -e trace=file \\
-o /tmp/mcpp-files.strace \\
mcpp run -- --versionProcess tracing also showed that mcpp only probes the compiler at the beginning (g++ --version, -dumpmachine, -print-sysroot). It does not start a real compile or the mbun binary during the long delay.
Expected behavior
Given an explicit source pattern such as:
src/**/*.{cppm,cpp,cc,c}
mcpp run should not recursively enumerate unrelated directories such as:
compat/bun
compat/node
target
.mcpp
The command should reuse the same source-discovery and dependency-resolution cache as mcpp build, then launch the already-built binary.
Possible implementation direction
- Derive the fixed directory prefix from a source glob and walk only that prefix. For
src/**/*, do not start traversal at.. - Treat Git submodule boundaries as excluded from package source discovery unless explicitly declared as a package/member.
- Skip generated/cache directories such as
targetand.mcppduring source discovery. - Cache source discovery and resolved dependency metadata so
mcpp rundoes not repeat the full scan aftermcpp build. - Add a regression test containing a large unrelated directory or submodule and assert that
mcpp runremains close to the cachedmcpp buildtime.
Impact
This makes the normal development command slow for every invocation and becomes worse as compatibility corpora grow. The runtime itself is fast; the delay is entirely in the mcpp run/resolve path.
Activity
Sunrisepeak commentedon Jul 18, 2026
✅ 已在 mcpp 0.0.97 修复(PR #236,
33e6d9a,簇 E)。expand_glob现从 glob 的字面前缀起遍历(src/**从src/起走,不再从项目根扫全树),并排除.git/target/ git 子模块边界;mcpp run复用mcpp build已解析的缓存(try_fast_run),不再每次重扫大子模块。验证:e2e
114_run_scan_scope.sh(断言mcpp run不再重扫,含大无关目录场景)+ 单测Scanner.GlobLiteralPrefixDerivation/ExcludesGitAndTargetAndMcpp。fix(modgraph): stop narrowing the walk's directory names; pin xlings …