-
Notifications
You must be signed in to change notification settings - Fork 274
C++20 module support v2 #1575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DefaultRyan
wants to merge
29
commits into
master
Choose a base branch
from
feature/modules_v2
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
C++20 module support v2 #1575
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
5f7d2f5
Initial implementation of vs modules based on cppwinrtplus fork
DefaultRyan 469c963
Rename WINRT_MODULE -> WINRT_IMPL_BUILD_MODULE; WINRT_CONSUME_MODULE …
DefaultRyan 84da05a
Namespace modules are winrt.Namespace. Non-namespace modules are winr…
DefaultRyan ab72882
Bootstrap basic unit test
DefaultRyan 464a75c
Fix coroutine export. A few more unit tests.
DefaultRyan b6d6186
module_include, module_exclude
DefaultRyan 717754a
Rename test_module to test_cpp20_module
DefaultRyan d9ec817
Nuget test project with module include/exclude
DefaultRyan ca0090a
Refine generated files in component.
DefaultRyan 1aceeed
Added a type deriving from DependencyObject
DefaultRyan 05a845e
Basic module build/consume support
DefaultRyan 6fffa1d
Prefix namespace ixx files with "winrt." for consistency with module …
DefaultRyan b8b9715
IFC needs better per-project scoping. Now it fully works end to end.
DefaultRyan 25ce335
Minor fix to TestModuleComponent2
DefaultRyan ccfee65
Documentation and polish.
DefaultRyan f4073d3
Fix CI failures
DefaultRyan d5d1821
Try for better std hygiene
DefaultRyan 4d91f75
Address some PR feedback
DefaultRyan 79eb574
Better automation of AdditionalBMIDirectories
DefaultRyan b0d4656
Missed fallback definition of WINRT_IMPL_STD_EXPORT
DefaultRyan 392a1c3
Wrap base.h and extern the handler pointers
DefaultRyan 9207cf9
Uniform namespace filtering
DefaultRyan 9a98166
Write trailing comments for #endif
DefaultRyan c4e1b06
Clarify language version requirement
DefaultRyan 5889c9e
Add source_location test
DefaultRyan 2c83d42
Refactor/cleanup some string writers
DefaultRyan cb62bc7
Add arm64 configs and replace bogus project guids with real guids.
DefaultRyan 054fdf5
More cleanup of strings. Collected common macros into base_macros.h, …
DefaultRyan 9322551
More strings cleanup. Emit a canonical winrt/base_macros.h
DefaultRyan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # C++/WinRT Codebase — Agent Instructions | ||
|
|
||
| ## Repository Structure | ||
|
|
||
| - `cppwinrt/` — The cppwinrt.exe code generator (C++ source) | ||
| - `main.cpp` — CLI parsing, namespace iteration, SCC detection, .ixx orchestration | ||
| - `file_writers.h` — All file generation functions (headers, .ixx modules, component stubs) | ||
| - `code_writers.h` — Code-level writing utilities (guards, namespace wrappers, type writers) | ||
| - `type_writers.h` — Type formatting (ABI signatures, names, GUIDs) | ||
| - `component_writers.h` — Component authoring code generation | ||
| - `helpers.h` — Metadata reading helpers | ||
| - `settings.h` — Global settings populated from CLI args | ||
| - `text_writer.h` — Core text writer infrastructure | ||
| - `strings/` — String literal `.h` files embedded by the prebuild step. Changes require: delete prebuild.exe → rebuild solution | ||
| - `nuget/` — MSBuild targets, props, and NuGet packaging | ||
| - `Microsoft.Windows.CppWinRT.targets` — Main MSBuild integration (projections, module support) | ||
| - `test/` — Test projects | ||
| - `test/test_cpp20_module/` — Standalone module test (in main solution) | ||
| - `test/nuget/` — NuGet integration tests (multi-project module chain) | ||
| - `docs/` — Documentation | ||
| - `natvis/` — Visual Studio debug visualizer (includes strings/*.h in its pch.h — add new files there too) | ||
|
|
||
| ## Build Process | ||
|
|
||
| - Use VS Developer Shell for correct toolset environment | ||
| - `cmake --build build --config Release --target cppwinrt` for cppwinrt.exe (or MSBuild: `msbuild cppwinrt\cppwinrt.vcxproj /p:Configuration=Release /p:Platform=x64`) | ||
| - NuGet tests: `msbuild test\nuget\NuGetTest.sln /p:Configuration=Release /p:Platform=x64` | ||
| - Module test projects require v145 toolset (VS 2026). Directory.Build.Props sets v143 by default — override with `<PlatformToolset>v145</PlatformToolset>` in Configuration PropertyGroup | ||
|
|
||
| ## Key Patterns | ||
|
|
||
| ### Prebuild Embedding | ||
| The `strings/*.h` files are embedded as string literals by the prebuild step. If you modify any `strings/*.h` file, you must delete `prebuild.exe` and rebuild the entire solution for changes to take effect. | ||
|
|
||
| ### Module Guard Macros | ||
| - `WINRT_IMPL_BUILD_MODULE` — Defined in .ixx global fragment. Makes `WINRT_EXPORT` expand to `export extern "C++"` and suppresses `#include` of dependencies | ||
| - `WINRT_IMPORT_MODULE` — Defined by consumers who import modules. Makes namespace headers and base.h no-op (types come from module import) | ||
| - `WINRT_EXPORT` — Empty in header mode, `export extern "C++"` in module mode. Defined in `winrt/base_macros.h` | ||
| - `WINRT_IMPL_STD_EXPORT` — Empty in header mode, `extern "C++"` (without export) in module mode. Used for `namespace std` specializations | ||
|
|
||
| ### Generated Header Structure | ||
| Each namespace produces four header files: | ||
| - `impl/<ns>.0.h` — Forward declarations, ABIs, GUIDs, categories | ||
| - `impl/<ns>.1.h` — Interface definitions | ||
| - `impl/<ns>.2.h` — Delegates, structs, class implementations | ||
| - `<ns>.h` — Public API surface (consume definitions, class wrappers, operators) | ||
|
|
||
| ### Dependency Collection | ||
| When generating headers with `-modules`, writer.depends is inspected after each header to build a namespace dependency graph. This graph drives SCC detection and module import lists. | ||
|
|
||
| ## Common Gotchas | ||
|
|
||
| - Module IFCs are NOT compatible across toolset versions — always clean rebuild when switching | ||
| - PCH and modules can coexist but PCH should NOT include winrt headers when using modules | ||
| - `/ifcSearchDir` works for the module dependency scanner to find IFCs, but cross-component modules may need explicit `/reference "name=path.ifc"` flags | ||
| - `import std;` requires `BuildStlModules=true` | ||
| - `strings/base_macros.h` is the single source of truth for shared macros (generated as `winrt/base_macros.h`). New macros go in `base_macros.h` only | ||
| - When adding, removing, or heavily refactoring `strings/*.h` files, always rebuild the natvis project (`natvis/cppwinrtvisualizer.sln`) to verify — it includes strings/*.h directly in its pch.h |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # C++/WinRT Modules — Agent Instructions | ||
|
|
||
| ## Module Architecture (v2 — Per-Namespace) | ||
|
|
||
| Each WinRT namespace gets its own C++20 named module (`winrt.<Namespace>`). Base infrastructure is in `winrt_base` and `winrt_numerics`. | ||
|
|
||
| ### Code Generator Flow | ||
|
|
||
| 1. `-modules` flag enables .ixx generation in cppwinrt.exe | ||
| 2. `-module_include`/`-module_exclude` filter which namespaces get modules | ||
| 3. Headers are generated with dependency tracking (deps_ptr parameter) | ||
| 4. Tarjan's SCC algorithm detects cyclic namespace groups | ||
| 5. Standalone namespaces get individual .ixx; cyclic groups get consolidated SCC owner + re-export stubs | ||
|
|
||
| ### MSBuild Flow | ||
|
|
||
| 1. `CppWinRTBuildModule=true` adds `-modules` to cppwinrt.exe invocations | ||
| 2. `CppWinRTAddModuleInterfaces` discovers `$(GeneratedFilesDir)winrt\*.ixx` and adds to ClCompile | ||
| 3. `CppWinRTConsumeModule` metadata on ProjectReference controls per-reference IFC sharing | ||
| 4. `CppWinRTResolveModuleReferences` calls `CppWinRTGetModuleOutputs` on tagged references | ||
| 5. Platform projection suppresses `-modules` when consuming pre-built IFCs | ||
|
|
||
| ### Critical Invariants | ||
|
|
||
| - Module guards are unconditional in codegen — `-modules` controls .ixx generation and component codegen (module.g.cpp, stub .cpp) | ||
| - SCC owner is alphabetically first namespace in the cycle | ||
| - All .ixx filenames use `winrt` prefix: `winrt.Windows.Foundation.ixx`, `winrt_base.ixx` | ||
| - Shared macros live in `strings/base_module.h` → generates `winrt/macros.h`. `base_macros.h` includes it via `#include "winrt/macros.h"` | ||
|
|
||
| ### Testing Changes | ||
|
|
||
| After modifying cppwinrt.exe code: | ||
| 1. Rebuild cppwinrt.exe: `msbuild cppwinrt\cppwinrt.vcxproj /p:Configuration=Release /p:Platform=x64` | ||
| 2. Run standalone test: build `test_cpp20_module` in main solution | ||
| 3. Run NuGet tests: `msbuild test\nuget\NuGetTest.sln /p:Configuration=Release /p:Platform=x64` | ||
|
|
||
| After modifying targets: | ||
| 1. Clean NuGet test obj dirs | ||
| 2. Build with `/v:normal` and check "Module providers:" diagnostic messages | ||
| 3. Inspect `.rsp` files in `obj/` to verify correct `-modules` flag placement |
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
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
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
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.