Open
Conversation
Add support for analyzing projects that use C++ Modules (named modules,
module partitions, and module implementation units) built with CMake.
Previously, the action passed each source file to cl.exe /analyze:only
independently, without awareness of module dependencies. This caused
failures on projects using C++ Modules because:
- Module interface units require -interface and -ifcOutput flags
- Sources that import modules need -reference flags to resolve imports
- Module interfaces must be analyzed before their consumers
The fix leverages two artifacts that CMake already generates during its
dependency scan phase:
1. P1689R5 dependency files (.ddi) — contain 'provides' and 'requires'
entries for each source, enabling construction of a dependency graph.
2. Module map files (.modmap) — contain the exact -interface, -ifcOutput,
and -reference flags needed for each source's compilation.
Changes:
- CompileCommand: new ddiFile and modmapFile fields to track the paths
of these CMake-generated artifacts alongside each source.
- loadCompileCommands: locate .ddi and .modmap files for each source
in the CMake build directory.
- resolveModuleDependencies (new): read .ddi files to build a module
dependency graph, add implicit partition-to-primary dependencies
(workaround for a possible CMake scanner gap), and topologically
sort sources so providers are analyzed before consumers.
- createAnalysisCommands: iterate in topological order and pass each
source's @<modmap> response file to cl.exe so it receives the correct
module flags.
For projects without C++ Modules, the behavior is unchanged: no .ddi or
.modmap files exist, so the new code paths are not taken.
Fixes microsoft#44
898b9b0 to
360ae8f
Compare
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
Add support for analyzing CMake projects that use C++ Modules (named modules, module partitions, and module implementation units).
Problem
The action fails on projects with C++ Modules because it passes each source file to
cl.exe /analyze:onlyindependently, without awareness of module dependencies. This causes errors because:-interfaceand-ifcOutputflags-referenceflags to resolve importsSee #44 for the original report.
Fix
The fix leverages two artifacts that CMake already generates during its dependency scan phase:
P1689R5 dependency files (
.ddi) — containprovidesandrequiresentries for each source, enabling construction of a module dependency graph.Module map files (
.modmap) — contain the exact-interface,-ifcOutput, and-referenceflags needed for each source's compilation.Changes to
index.js:CompileCommand: newddiFileandmodmapFilefields to track CMake-generated artifacts alongside each source.loadCompileCommands: locate.ddiand.modmapfiles for each source in the CMake build directory.resolveModuleDependencies(new function): read.ddifiles to build a module dependency graph, add implicit partition-to-primary dependencies, and topologically sort sources so providers are analyzed before consumers.createAnalysisCommands: iterate in topological order and pass each source's@<modmap>response file tocl.exeso it receives the correct module flags.Key design decisions:
.ddifor ordering and passes CMake's.modmapverbatim. If CMake changes its module support, the action follows automatically..ddifiles exist or none contain module providers, the new code paths are not taken and the original ordering is preserved.Xdepends onX:<part>).Testing
Tested locally against the IPR project (branch
modules/cxx-ipr-traversal-io) which has 7 C++ Module interface units, 4 module implementation units, and 4 non-module source files. All sources that exist on the branch pass analysis (10 passed, 1 pre-existinginput.cxxfailure unrelated to modules).Fixes #44