feat: generate compile database without building - #387
Conversation
… replace - publish_compile_commands: treat a missing CDB (symlink_status type == not_found) as the normal first-build case instead of a fatal error. is_symlink sets ec on missing paths on every standard library (generic ENOENT on libstdc++/libc++, system ERROR_FILE_NOT_FOUND on MSVC), so no compile_commands.json was ever written on fresh workspaces and all CDB-dependent e2e tests failed. - close the existing-CDB ifstream before the atomic replace so Windows MoveFileExW can replace the destination (open handles cause Access denied / sharing violation). - unit tests: escape Windows backslash paths in the entry() JSON helper, write the mtime fixture in binary mode so on-disk bytes match on Windows, and add a regression test for publishing with no prior CDB.
Windows CDBs store file paths with backslashes, so `grep 'src/main.cpp'` never matched and the test failed on the Windows e2e shard once the CDB was actually being generated. Match either separator with `[\/]`.
Windows CDBs store paths with JSON-escaped backslashes (src\\main.cpp), so one-separator patterns still missed. Allow one or more separators.
9e6c8f3 to
c35f1b4
Compare
…g at its graph
The backend writes build.ninja before it honors dryRun, so `--configure-only`
rewrites the very file the P0 fast path replays — and a configure plan's graph
is not a normal build's graph: it carries the test targets and dev-dependencies,
so its `default` line names the TEST binaries and does not contain the package's
own target at all.
`target/.build_cache` was left untouched, and the fast path decides freshness by
comparing build.ninja's mtime against the SOURCES, never against the graph. So on
any already-built project:
mcpp build # default bin/app
mcpp build --configure-only # default bin/smoke <- same build.ninja
mcpp build # fast path -> links bin/smoke, never bin/app,
# prints `Finished dev in 0.04s`
which is the routine case, not a corner one: the whole point of the flag is that
an editor runs it continuously.
Drop the fast-path entry for the build dir whose graph was rewritten, before the
backend runs so a failed configure cannot leave the stale claim standing either.
Scoped to that one outputDir: other (target, profile, cache mode) triples own
different build dirs and keep their entries.
`write_build_cache`'s serializer is split out so the invalidation path rewrites
the file through the same spelling rather than a second one.
The e2e must NOT delete the built binary before the second build — a missing
output makes ninja fail in a way the fast path reads as a stale graph and falls
back to a full prepare, which hides the defect. Verified red (links `smoke`)
before the fix and green after.
Review:架构对,一个真缺陷已修并入本 PR从架构 / 稳定性 / 简洁性 / 跨平台 / 可观测性 / 测试覆盖六个方向核过。结论是方案选对了:复用真实 下面是实测发现的问题,已经在本 PR 上改完并验证。 一、真缺陷:configure-only 会把构建快路径指向自己的图(已修)backend 在 $ mcpp build # default bin/repro
$ mcpp build --configure-only # default bin/smoke <- 同一个 build.ninja
$ mcpp build
Finished dev in 0.04s
$ ls target/*/*/bin
repro smoke # 链了测试,没链 target,还报了成功这不是边角情形:这个 flag 的全部意义就是编辑器会不停地跑它。 修法是在 backend 跑之前丢掉指向该构建目录的快路径条目(configure.cppm),失败的 configure 也不会留下过期声明。只作用于被重写的那一个 outputDir,别的 (target, profile, cache mode) 三元组各有自己的构建目录,实测 dev+release 两条条目只掉 dev 那条。
二、E2E 编号撞车(已修)
三、新加的守卫差点是假绿(已修)我给 e2e 补的快路径断言最初写成「先 另外把首次调用的 四、补 CHANGELOG
五、核过没问题的部分
六、验证本机 x86_64-linux-gnu:unit 76 个测试二进制全过;e2e 🤖 Generated with Claude Code |
…uced Windows links `fastpath.exe`; the new fast-path section hardcoded the POSIX spelling and failed at the baseline check before reaching the assertion it exists for (e2e 2/2 windows). The suffix is a host constant, so take it off the artifact `find` actually returned rather than branching on the platform.
Summary
mcpp build --configure-only, reusing the real build plan and existing build selectors while skipping ordinary compilation, linking, BMI cache population, and build-success cache writestests/**/*.cpp, matching[build].flags, and test dev-dependencies in the generated CDB; stage only std and already-cached dependency BMIs needed by language toolingcompile_commands.jsonatomically across platforms, preserve last-known-good files and CDB symlinks, and keep normal build/test publication failures non-fatalbuild.mcpp, resolve/install dependencies or toolchains, and update lock/resolution metadataThis is the independently agreed A part from #379. It intentionally does not add JSON/NDJSON,
idesubcommands, snapshots,mcpp.wire,invalidatedBy, or new selector semantics. It does not close the RFC.Core impact
mcpp test; existing list/build/run behavior remains covered by unit and E2E testsrequireCompileDatabaseflag; default build/test behavior remains warning-onlyTest plan
mcpp build --no-color --no-cacheon macOS ARM64mcpp test --no-color: 70 passed, 0 failedtests/e2e/202_configure_only_cdb.sh: syntax-error source, test/dev-dependency flags, workspace fan-out,-p, no build artifacts/cache, publication failure preservation01,18,35,76,77,90,157,159Refs #379
Refs mcpp-community/mcpp-vscode#5