You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
emit build-database rewrites the build program's host mcpp.lock on every run and lists it in data.watch, so a watcher re-runs emit forever #807
mcpp emit build-database --format json lists a file in data.watch that the same command rewrites on every run. The file is the mcpp.lock of the build program's synthesized host package:
The content stays the same; only the mtime changes. A tool that watches data.watch and runs emit again when a watched file changes never settles: each emit "changes" the file that triggers the next one.
Seen in mcpp-language-server 0.0.15 on a project with a build.mcpp and [build-dependencies] (a Qt Widgets demo using mcpp:pluginsrules-qt). It runs mcpp emit every 2 seconds for as long as the project is open. The log repeats project model loaded again: unchanged, each run preceded by a didChangeWatchedFiles for this mcpp.lock (type 2, changed).
Reproduce (mcpp 2026.10.11.1, Linux x86_64)
Any project whose build.mcpp has build dependencies, for example:
[build-dependencies.mcpp]
plugins = { version = "0.15.2", features = ["rules-qt"], host-module = true }
mcpp emit build-database --format json > /tmp/emit.json
python3 -c "import json; print([w for w in json.load(open('/tmp/emit.json'))['data']['watch'] if w.endswith('mcpp.lock')])"# ['…/.mcpp/cache/build-database/5042b60d2f765ba8/target/.build-mcpp/host/e50cbbe8641b/mcpp.lock', 'mcpp.lock']
f=~/.mcpp/cache/build-database/5042b60d2f765ba8/target/.build-mcpp/host/e50cbbe8641b/mcpp.lock
stat -c %Y "$f"; md5sum <"$f"# 1791919945 0c27208d1dd09132234081d90d03aa3e
sleep 1; mcpp emit build-database --format json > /dev/null
stat -c %Y "$f"; md5sum <"$f"# 1791919946 0c27208d1dd09132234081d90d03aa3e <- rewritten, same bytes
Where
src/build/prepare/records.cpp:314: (void)mcpp::lockfile::write(lock, lockPath); runs unconditionally, so a resolution that did not change still rewrites the lock.
src/build/build_database.cppm:591: watch_file(ctx.projectRoot / "mcpp.lock");. For the build-program member, projectRoot is the synthesized host package under the build-database cache, so a file mcpp itself writes is reported as an input.
Suggested fix
Write the lock only when its bytes differ from what is on disk (write-if-changed). This also helps anything else that watches a project's own mcpp.lock: editors, cargo watch-style tools, file sync.
Optionally, leave the synthesized host package's mcpp.lock out of data.watch. It is an output of the plan, not something a person edits. The inputs that decide it (the root mcpp.toml, build.mcpp, the root mcpp.lock) are already listed.
mcpp-language-server will also stop reacting to a watched file whose content did not change, so it no longer depends on this. Other consumers of data.watch still would.
Activity
fix: preserve image resources and stable planning inputs (2026.10.21.1)