Skip to content

llvm toolchain: purview #include'd file edits don't retrigger module interface rebuild (stale BMI; #235-family gap on the clang path) #257

Description

@Sunrisepeak

Summary

Under the llvm toolchain, editing a file that a module interface pulls in via a purview #include (e.g. opencv-m's src/core.cppm doing #include "matx_ops.inc" after export module) does not retrigger the module interface rebuild: the next mcpp build/mcpp test reuses the stale BMI, so importers compile against the old surface. Reproduced twice in one session (opencv-m feat/vendor-single-repo, mcpp 0.0.101, llvm 20.1.7):

  1. edit src/matx_ops.inc (purview-included by src/core.cppm)
  2. mcpp test → prints Compiling opencv v0.0.7 (.) but target/<fp>/pcm.cache/opencv.core.pcm mtime predates the edit and its contents lack the new code (verified by grepping the pcm for a newly-added identifier)
  3. touch src/core.cppm && mcpp test → correct rebuild

This looks like the #235 family (purview textual #include → depfile tracking), which was fixed for the gcc path in 0.0.97 — the clang path seems to miss the same edge (different depfile/scanner flow?). gcc 16.1.0 in the same repo/session picked up .inc edits correctly.

Repro sketch

mcpp toolchain default llvm@20.1.7
# module interface with a purview include:
#   export module x;  #include "ops.inc"
mcpp build                      # cold, fine
echo '// change' >> ops.inc
mcpp build                      # BUG: x.pcm not rebuilt (mtime/content stale)

Workaround: touch the including .cppm. Harmless for CI (cold builds) but dangerous locally — during the clang debugging session in #256 it silently served a stale BMI and cost a misdiagnosis round.

Environment: mcpp 0.0.101, linux x86_64, llvm 20.1.7 from mcpp toolchain install.

Activity

  1. added 3 commits that reference this issue on Jul 21, 2026
  2. Sunrisepeak commented on Jul 21, 2026

    @Sunrisepeak
    MemberAuthor

    Fixed in 0.0.102 (PR #264, squashed to main as 5807e36).

    Root cause was a conflated predicate in 0.0.97: posixDepfile decided BOTH whether to emit a depfile at all AND whether to run the awk filter that strips GCC's reversed module-rules, and both were scoped to GCC because Clang's depfile shape was unverified. Measured on both bundled toolchains, Clang emits a single plain rule (x.o: x.cppm ops.inc) with nothing the filter would remove — so the gate was guarding against a shape that does not exist, at the cost of the correctness contract bundled with it.

    Split into posixDepfile (any POSIX non-MSVC toolchain) and needsGnuModuleFilter (GCC only). Clang now gets a depfile, and C/GAS edges get one too (they had none on any toolchain). Verified by hand under llvm 20.1.7 and 22.1.8, and e2e 118 drops # requires: gcc for a Clang leg.

    Windows + a GNU-dialect toolchain still cannot track textual includes (the GCC filter needs awk, which native Windows lacks), but that is now reported through diag::degraded with its user-visible impact instead of being silent — and e2e 118 asserts that report fires on Windows rather than asserting a capability the platform doesn't have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions