C++20 module support v2#1575
Conversation
…-> WINRT_IMPORT_MODULE
…t_base/winrt_numerics Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
…names and built ifc files. Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: YexuanXiao <bizwen@nykz.org> Co-authored-by: Copilot <copilot@github.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces v2 C++20 module support for C++/WinRT by generating per-namespace named modules (e.g., import winrt.Windows.Foundation;) with SCC (cycle) consolidation, updates the projection/base strings to be module-export-friendly, and adds MSBuild + test coverage for module generation/consumption.
Changes:
- Extend
cppwinrt.exeto generate per-namespace.ixxfiles (with Tarjan SCC cycle breaking) and emit module-aware guards/exports in generated headers. - Add MSBuild plumbing (
CppWinRTBuildModule, include/exclude filters,CppWinRTConsumeModule,.ixxdiscovery) plus docs describing usage and internals. - Add new standalone + NuGet integration test projects that build and consume the generated modules end-to-end.
Reviewed changes
Copilot reviewed 93 out of 93 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| test/test_cpp20_module/test_cpp20_module.vcxproj | New standalone VS project that runs cppwinrt with -modules and compiles generated .ixx files. |
| test/test_cpp20_module/pch.h | Catch2 PCH header for module test. |
| test/test_cpp20_module/pch.cpp | Builds the PCH for module test. |
| test/test_cpp20_module/main.cpp | Catch2 runner for module test using import winrt_base;. |
| test/test_cpp20_module/foundation.cpp | Module-mode tests for Windows.Foundation APIs. |
| test/test_cpp20_module/coroutines.cpp | Module-mode coroutine tests using IAsync* types. |
| test/test_cpp20_module/collections.cpp | Module-mode collections tests (vector/map/iterable). |
| test/nuget/TestModuleConsumerApp/pch.h | PCH header for NuGet consumer app test. |
| test/nuget/TestModuleConsumerApp/pch.cpp | Builds the PCH for NuGet consumer app test. |
| test/nuget/TestModuleConsumerApp/main.cpp | Consumer app importing platform + component modules. |
| test/nuget/TestModuleConsumerApp/TestModuleConsumerApp.vcxproj | Consumer app MSBuild config exercising CppWinRTConsumeModule. |
| test/nuget/TestModuleConsumerApp/PropertySheet.props | Minimal property sheet for NuGet consumer app project. |
| test/nuget/TestModuleComponent2/pch.h | PCH header for component 2 test. |
| test/nuget/TestModuleComponent2/pch.cpp | Builds the PCH for component 2 test. |
| test/nuget/TestModuleComponent2/TestModuleComponent2.vcxproj | Component 2 MSBuild config with module generation + consumption. |
| test/nuget/TestModuleComponent2/TestModuleComponent2.idl | IDL for GreeterGroup runtimeclass. |
| test/nuget/TestModuleComponent2/TestModuleComponent2.def | DEF exports for component DLL activation. |
| test/nuget/TestModuleComponent2/PropertySheet.props | Minimal property sheet for component 2. |
| test/nuget/TestModuleComponent2/GreeterGroup.h | Component implementation header for GreeterGroup. |
| test/nuget/TestModuleComponent2/GreeterGroup.cpp | Component implementation TU using module imports. |
| test/nuget/TestModuleComponent1/pch.h | PCH header for component 1 test. |
| test/nuget/TestModuleComponent1/pch.cpp | Builds the PCH for component 1 test. |
| test/nuget/TestModuleComponent1/TestModuleComponent1.vcxproj | Component 1 MSBuild config with module generation + consumption. |
| test/nuget/TestModuleComponent1/TestModuleComponent1.idl | IDL for Greeter runtimeclass. |
| test/nuget/TestModuleComponent1/TestModuleComponent1.def | DEF exports for component DLL activation. |
| test/nuget/TestModuleComponent1/PropertySheet.props | Minimal property sheet for component 1. |
| test/nuget/TestModuleComponent1/Greeter.h | Component implementation header for Greeter. |
| test/nuget/TestModuleComponent1/Greeter.cpp | Component implementation TU using module imports. |
| test/nuget/TestModuleBuilder/pch.h | PCH header for “builder” static lib project. |
| test/nuget/TestModuleBuilder/pch.cpp | Builds the PCH for module builder. |
| test/nuget/TestModuleBuilder/TestModuleBuilder.vcxproj | Static lib project that pre-builds platform modules. |
| test/nuget/TestModuleBuilder/PropertySheet.props | Minimal property sheet for module builder. |
| test/nuget/TestModuleApp/pch.h | PCH header for single-project module app test. |
| test/nuget/TestModuleApp/pch.cpp | Builds the PCH for single-project module app test. |
| test/nuget/TestModuleApp/main.cpp | Single-project app importing platform modules + exercising component types. |
| test/nuget/TestModuleApp/TestModuleApp.vcxproj | Single-project module build + consumption configuration. |
| test/nuget/TestModuleApp/TestModuleApp.idl | IDL for test component types including XAML inheritance scenario. |
| test/nuget/TestModuleApp/TestModuleApp.def | DEF exports for TestModuleApp DLL activation. |
| test/nuget/TestModuleApp/PropertySheet.props | Minimal property sheet for single-project module app. |
| test/nuget/TestModuleApp/ModuleTestHelper.h | Component implementation header for helper runtimeclass. |
| test/nuget/TestModuleApp/ModuleTestHelper.cpp | Component implementation TU using module imports. |
| test/nuget/TestModuleApp/CustomDependencyObject.h | Component implementation header for XAML-derived runtimeclass. |
| test/nuget/TestModuleApp/CustomDependencyObject.cpp | Component implementation TU importing XAML and foundation modules. |
| test/nuget/NuGetTest.sln | Adds the new module test projects to NuGetTest solution. |
| strings/base_xaml_typename.h | Switches winrt::impl namespace blocks to WINRT_EXPORT for module export. |
| strings/base_windows.h | Same: exports winrt::impl content under modules. |
| strings/base_types.h | Same: exports winrt::impl blocks under modules. |
| strings/base_string_operators.h | Same: exports winrt::impl blocks under modules. |
| strings/base_string_input.h | Same: exports winrt::impl blocks under modules. |
| strings/base_string.h | Same: exports winrt::impl blocks under modules. |
| strings/base_std_hash.h | Exports winrt::impl and std specializations via WINRT_EXPORT. |
| strings/base_reference_produce.h | Exports winrt::impl blocks under modules. |
| strings/base_natvis.h | Exports natvis helpers under WINRT_EXPORT winrt::impl. |
| strings/base_meta.h | Exports winrt::impl meta helpers under modules. |
| strings/base_marshaler.h | Exports winrt::impl marshaler helpers under modules. |
| strings/base_macros.h | Adds numerics include guard for module/import builds + exports winrt::impl. |
| strings/base_iterator.h | Exports winrt::impl iterator helpers under modules. |
| strings/base_implements.h | Exports winrt::impl implements helpers under modules. |
| strings/base_identity.h | Exports winrt::impl identity helpers under modules. |
| strings/base_foundation.h | Exports winrt::impl foundation helpers under modules. |
| strings/base_fast_forward.h | Exports winrt::impl fast-forward helpers under modules. |
| strings/base_events.h | Exports winrt::impl event helpers under modules. |
| strings/base_error.h | Exports winrt::impl error helpers under modules. |
| strings/base_delegate.h | Exports winrt::impl delegate helpers under modules. |
| strings/base_coroutine_threadpool.h | Exports winrt::impl and std coroutine specializations under modules. |
| strings/base_coroutine_foundation.h | Exports winrt::impl and std coroutine specializations under modules. |
| strings/base_composable.h | Exports winrt::impl composable helpers under modules. |
| strings/base_com_ptr.h | Exports winrt::impl com_ptr helpers under modules. |
| strings/base_collections_vector.h | Exports winrt::impl collections helpers under modules. |
| strings/base_collections_map.h | Exports winrt::impl and std tuple specializations under modules. |
| strings/base_collections_input_vector_view.h | Exports winrt::impl collections helpers under modules. |
| strings/base_collections_input_vector.h | Exports winrt::impl collections helpers under modules. |
| strings/base_collections_input_map_view.h | Exports winrt::impl collections helpers under modules. |
| strings/base_collections_input_map.h | Exports winrt::impl collections helpers under modules. |
| strings/base_collections_input_iterable.h | Exports winrt::impl collections helpers under modules. |
| strings/base_collections_base.h | Exports winrt::impl collections base helpers under modules. |
| strings/base_collections.h | Exports winrt::impl collections helpers under modules. |
| strings/base_array.h | Exports winrt::impl array helpers under modules. |
| strings/base_agile_ref.h | Exports winrt::impl agile_ref helpers under modules. |
| strings/base_activation.h | Exports winrt::impl activation helpers under modules. |
| strings/base_abi.h | Exports winrt::impl ABI helpers under modules. |
| nuget/readme.md | Documents new module-related MSBuild properties/metadata. |
| nuget/modules.md | Adds user guide for enabling/building/consuming modules. |
| nuget/Microsoft.Windows.CppWinRT.targets | Adds module properties, .ixx discovery target, and ProjectReference metadata flow. |
| docs/modules-design.md | Adds maintainer-focused design doc for per-namespace modules + SCC + MSBuild flow. |
| cppwinrt/settings.h | Adds generator settings for modules + include/exclude filter sets. |
| cppwinrt/main.cpp | Adds CLI flags, module filter construction, dependency collection, SCC detection, and .ixx generation. |
| cppwinrt/file_writers.h | Adds module writers (module.h, base/numerics/namespace .ixx), module-aware include guards, and component import/include dual-path. |
| cppwinrt/component_writers.h | Adjusts component module.g.cpp generation to avoid base include when modules enabled. |
| cppwinrt/code_writers.h | Adds module-aware include guard helper and exports winrt::impl namespace blocks via WINRT_EXPORT. |
| cppwinrt.sln | Adds new standalone module test project to main solution. |
| .github/instructions/modules.instructions.md | Adds module-specific agent instructions. |
| .github/instructions/cppwinrt.instructions.md | Adds repo-wide agent instructions including module notes and build/test steps. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <copilot@github.com>
0a5d1f6 to
d5d1821
Compare
Co-authored-by: Copilot <copilot@github.com>
|
I think we can append a module export list at the end of each base_*.h file and guard it with #ifdef WINRT_MODULE
export namespace winrt
{
using winrt::xxx;
}
#endifI think this approach is the most maintainable. I've tried this approach on my fork, and I think it's pretty good. It removes |
This comment was marked as resolved.
This comment was marked as resolved.
|
@DefaultRyan I discovered that the reason MSVC generates warning 5244 for windowsnumerics.impl.h is that it uses angle bracket #include instead of double quotes because compilers (MSVC and Clang) consider that system headers should not be treated as module implementation files. Therefore, it can be changed to double quotes and a comment can be added to prevent regression, instead of suppressing the warning. |
|
I believe I have discovered a bug in MSVC, but I am unable to reproduce it in a new project. In short, the pattern like this: |
|
@DefaultRyan Nine days after the last commit about module, I opened a new simple PR for my fork that does a basic cleanup of WINRT_EXPORT and extern "C++". Other cleanups require large scale modifications to base*.h. If you think it's time to do these cleanups, you should take a look, it's designed not to break the existing base*.h patterns. |
|
|
||
| // Module declaration (owner namespace) | ||
| w.write("// This module is an SCC owner (cycle breaker). The following namespaces\n"); | ||
| w.write("// form a dependency cycle and are consolidated into this single module:\n"); |
There was a problem hiding this comment.
I'm curious if there is data on what cycles exist and how big they are. Using the output of your build would probably make that pretty simple to grep for.
There was a problem hiding this comment.
Here's what I've got, assuming I scanned the ixx files correctly. Out of 342 Windows.* namespaces
- Most namespaces (248) don't participare in cycles.
- There are a few mini-cycles, like
Windows.Foundation<->Windows.Foundation.Collections, orWindows.AI.Actions<->Windows.AI.Actions.Hosting - A couple of mid-sized cycles.
Windows.UI.Xaml.*andWindows.Media.Audio.*tend to interconnect. - There is one massive cycle (62 namespaces!) encompassing cross-references all over the place. I'll see if I can easily cook up a diagram or something for it.
There was a problem hiding this comment.
For lolz, here's a table of the interdependencies. For extra lolz, I generated a mermaid diagram after that.
A quick perusal suggests that most of this is because tons of namespaces depend on Windows.Storage.Streams, Windows.Storage.Streams depends on Windows.System, and Windows.System depends on a surprising bunch of random bits.
| Source (Windows.) | Dependencies (Windows.) |
|---|---|
| ApplicationModel | ApplicationModel_Activation, ApplicationModel_Appointments, ApplicationModel_Appointments_AppointmentsProvider, ApplicationModel_AppService, ApplicationModel_Background, ApplicationModel_Calls, ApplicationModel_Contacts, ApplicationModel_Contacts_Provider, ApplicationModel_Core, ApplicationModel_DataTransfer, ApplicationModel_DataTransfer_ShareTarget, ApplicationModel_Email, ApplicationModel_Search, ApplicationModel_UserDataAccounts, ApplicationModel_UserDataAccounts_Provider, ApplicationModel_UserDataTasks, ApplicationModel_Wallet, Devices_Bluetooth_Background, Devices_Bluetooth_GenericAttributeProfile, Devices_Sensors, Devices_SmartCards, Devices_Sms, Security_Authentication_Web_Core, Security_Credentials, Storage, Storage_Streams, System, System_RemoteSystems, UI_Notifications |
| ApplicationModel_Activation | ApplicationModel, ApplicationModel_Appointments_AppointmentsProvider, ApplicationModel_Background, ApplicationModel_Calls, ApplicationModel_Contacts, ApplicationModel_Contacts_Provider, ApplicationModel_DataTransfer_ShareTarget, ApplicationModel_Search, ApplicationModel_UserDataAccounts_Provider, ApplicationModel_Wallet, Devices_Enumeration, Media_SpeechRecognition, Security_Authentication_Web_Provider, Storage, Storage_Pickers_Provider, Storage_Provider, Storage_Search, System, UI_Notifications, UI_ViewManagement |
| ApplicationModel_Appointments | ApplicationModel, ApplicationModel_Appointments_AppointmentsProvider, System |
| ApplicationModel_Appointments_AppointmentsProvider | ApplicationModel_Appointments |
| ApplicationModel_AppService | ApplicationModel, System, System_RemoteSystems |
| ApplicationModel_Background | ApplicationModel, ApplicationModel_Activation, Devices_Bluetooth, Devices_Bluetooth_Advertisement, Devices_Bluetooth_Background, Devices_Bluetooth_GenericAttributeProfile, Devices_Sensors, Devices_SmartCards, Devices_Sms, Networking, Networking_Sockets, Storage, Storage_Provider, System, UI_Notifications |
| ApplicationModel_Calls | ApplicationModel, ApplicationModel_Contacts, Devices_Enumeration, System |
| ApplicationModel_Contacts | ApplicationModel, ApplicationModel_Contacts_Provider, Data_Text, Storage_Streams, System, UI_ViewManagement |
| ApplicationModel_Contacts_Provider | ApplicationModel_Contacts |
| ApplicationModel_Core | ApplicationModel, ApplicationModel_Activation, System, UI_Core |
| ApplicationModel_DataTransfer | ApplicationModel, ApplicationModel_DataTransfer_ShareTarget, Security_EnterpriseData, Storage, Storage_Streams |
| ApplicationModel_DataTransfer_ShareTarget | ApplicationModel_Contacts, ApplicationModel_DataTransfer, Storage_Streams |
| ApplicationModel_Email | ApplicationModel, ApplicationModel_Appointments, Security_Cryptography_Certificates, Storage_Streams, System |
| ApplicationModel_Search | ApplicationModel, Storage, Storage_Streams |
| ApplicationModel_UserDataAccounts | ApplicationModel, ApplicationModel_Appointments, ApplicationModel_Contacts, ApplicationModel_Email, ApplicationModel_UserDataAccounts_Provider, ApplicationModel_UserDataTasks, Storage_Streams, System |
| ApplicationModel_UserDataAccounts_Provider | ApplicationModel_UserDataAccounts |
| ApplicationModel_UserDataTasks | ApplicationModel, System |
| ApplicationModel_Wallet | ApplicationModel, Storage_Streams |
| Data_Text | UI_Text_Core |
| Data_Xml_Dom | Storage, Storage_Streams |
| Devices_Bluetooth | Devices_Bluetooth_Advertisement, Devices_Bluetooth_Background, Devices_Bluetooth_GenericAttributeProfile, Devices_Bluetooth_Rfcomm, Devices_Enumeration, Networking, Storage_Streams |
| Devices_Bluetooth_Advertisement | Devices_Bluetooth, Storage_Streams |
| Devices_Bluetooth_Background | Devices_Bluetooth, Devices_Bluetooth_Advertisement, Devices_Bluetooth_GenericAttributeProfile, Devices_Bluetooth_Rfcomm, Networking_Sockets, Storage_Streams |
| Devices_Bluetooth_GenericAttributeProfile | Devices_Bluetooth, Devices_Enumeration, Storage_Streams |
| Devices_Bluetooth_Rfcomm | Devices_Bluetooth, Devices_Enumeration, Networking, Networking_Sockets, Storage_Streams |
| Devices_Enumeration | ApplicationModel_Background, Security_Credentials, Storage_Streams |
| Devices_Sensors | Graphics_Display |
| Devices_SmartCards | Security_Cryptography_Core, Storage_Streams |
| Devices_Sms | Storage_Streams |
| Globalization | System |
| Graphics_Display | Storage_Streams |
| Media_SpeechRecognition | Globalization, Storage |
| Networking | ApplicationModel_Activation, ApplicationModel_Background, Networking_Connectivity, Networking_Sockets, Storage_Streams, System |
| Networking_Connectivity | Networking, Storage_Streams |
| Networking_Sockets | ApplicationModel_Background, Networking, Networking_Connectivity, Security_Credentials, Security_Cryptography_Certificates, Storage_Streams, Web |
| Security_Authentication_Web_Core | Security_Credentials, System |
| Security_Authentication_Web_Provider | Security_Authentication_Web_Core, Security_Credentials, Security_Cryptography_Core, Storage_Streams, System, Web_Http |
| Security_Credentials | Security_Cryptography_Core, Storage_Streams, System |
| Security_Cryptography_Certificates | Networking, Storage_Streams |
| Security_Cryptography_Core | Security_Cryptography_Certificates, Storage_Streams |
| Security_EnterpriseData | Networking, Storage, Storage_Streams |
| Storage | Storage_FileProperties, Storage_Pickers_Provider, Storage_Provider, Storage_Search, Storage_Streams, System |
| Storage_FileProperties | Storage, Storage_Streams |
| Storage_Pickers_Provider | Storage |
| Storage_Provider | Storage, Storage_Search, Storage_Streams |
| Storage_Search | Data_Text, Storage, Storage_FileProperties, Storage_Streams |
| Storage_Streams | Storage, System |
| System | ApplicationModel, ApplicationModel_AppService, Networking, Security_Credentials, Storage, Storage_Search, Storage_Streams, System_Diagnostics, System_RemoteSystems, UI_ViewManagement |
| System_Diagnostics | ApplicationModel_AppService, System |
| System_RemoteSystems | ApplicationModel_AppService, Networking, Security_Credentials, System |
| UI_Composition | System, UI_Core |
| UI_Core | System, UI_Composition, UI_Input, UI_WindowManagement |
| UI_Input | ApplicationModel_Core, Storage_Streams, System, UI_Composition, UI_Core, UI_Text, UI_WindowManagement |
| UI_Notifications | ApplicationModel, Data_Xml_Dom, System |
| UI_Text | Storage_Streams, UI_Text_Core |
| UI_Text_Core | Globalization, UI_Text, UI_ViewManagement |
| UI_ViewManagement | Devices_Enumeration, UI_Core, UI_WindowManagement |
| UI_WindowManagement | System, UI_Composition |
| Web | Globalization, Security_Credentials, Storage_Streams, System, System_Diagnostics, Web_Http, Web_Http_Filters, Web_Http_Headers |
| Web_Http | Globalization, Networking_Sockets, Security_Cryptography_Certificates, Storage_Streams, System, System_Diagnostics, Web, Web_Http_Filters, Web_Http_Headers |
| Web_Http_Filters | Networking_Sockets, Security_Credentials, Security_Cryptography_Certificates, System, Web_Http |
| Web_Http_Headers | Globalization, Networking, Storage_Streams, Web_Http |
graph LR
ApplicationModel_Activation --> ApplicationModel
ApplicationModel_Activation --> ApplicationModel_Appointments_AppointmentsProvider
ApplicationModel_Activation --> ApplicationModel_Background
ApplicationModel_Activation --> ApplicationModel_Calls
ApplicationModel_Activation --> ApplicationModel_Contacts
ApplicationModel_Activation --> ApplicationModel_Contacts_Provider
ApplicationModel_Activation --> ApplicationModel_DataTransfer_ShareTarget
ApplicationModel_Activation --> ApplicationModel_Search
ApplicationModel_Activation --> ApplicationModel_UserDataAccounts_Provider
ApplicationModel_Activation --> ApplicationModel_Wallet
ApplicationModel_Activation --> Devices_Enumeration
ApplicationModel_Activation --> Media_SpeechRecognition
ApplicationModel_Activation --> Security_Authentication_Web_Provider
ApplicationModel_Activation --> Storage
ApplicationModel_Activation --> Storage_Pickers_Provider
ApplicationModel_Activation --> Storage_Provider
ApplicationModel_Activation --> Storage_Search
ApplicationModel_Activation --> System
ApplicationModel_Activation --> UI_Notifications
ApplicationModel_Activation --> UI_ViewManagement
ApplicationModel_Appointments_AppointmentsProvider --> ApplicationModel_Appointments
ApplicationModel_Appointments --> ApplicationModel
ApplicationModel_Appointments --> ApplicationModel_Appointments_AppointmentsProvider
ApplicationModel_Appointments --> System
ApplicationModel_AppService --> ApplicationModel
ApplicationModel_AppService --> System
ApplicationModel_AppService --> System_RemoteSystems
ApplicationModel_Background --> ApplicationModel
ApplicationModel_Background --> ApplicationModel_Activation
ApplicationModel_Background --> Devices_Bluetooth
ApplicationModel_Background --> Devices_Bluetooth_Advertisement
ApplicationModel_Background --> Devices_Bluetooth_Background
ApplicationModel_Background --> Devices_Bluetooth_GenericAttributeProfile
ApplicationModel_Background --> Devices_Sensors
ApplicationModel_Background --> Devices_SmartCards
ApplicationModel_Background --> Devices_Sms
ApplicationModel_Background --> Networking
ApplicationModel_Background --> Networking_Sockets
ApplicationModel_Background --> Storage
ApplicationModel_Background --> Storage_Provider
ApplicationModel_Background --> System
ApplicationModel_Background --> UI_Notifications
ApplicationModel_Calls --> ApplicationModel
ApplicationModel_Calls --> ApplicationModel_Contacts
ApplicationModel_Calls --> Devices_Enumeration
ApplicationModel_Calls --> System
ApplicationModel_Contacts_Provider --> ApplicationModel_Contacts
ApplicationModel_Contacts --> ApplicationModel
ApplicationModel_Contacts --> ApplicationModel_Contacts_Provider
ApplicationModel_Contacts --> Data_Text
ApplicationModel_Contacts --> Storage_Streams
ApplicationModel_Contacts --> System
ApplicationModel_Contacts --> UI_ViewManagement
ApplicationModel_Core --> ApplicationModel
ApplicationModel_Core --> ApplicationModel_Activation
ApplicationModel_Core --> System
ApplicationModel_Core --> UI_Core
ApplicationModel_DataTransfer_ShareTarget --> ApplicationModel_Contacts
ApplicationModel_DataTransfer_ShareTarget --> ApplicationModel_DataTransfer
ApplicationModel_DataTransfer_ShareTarget --> Storage_Streams
ApplicationModel_DataTransfer --> ApplicationModel
ApplicationModel_DataTransfer --> ApplicationModel_DataTransfer_ShareTarget
ApplicationModel_DataTransfer --> Security_EnterpriseData
ApplicationModel_DataTransfer --> Storage
ApplicationModel_DataTransfer --> Storage_Streams
ApplicationModel_Email --> ApplicationModel
ApplicationModel_Email --> ApplicationModel_Appointments
ApplicationModel_Email --> Security_Cryptography_Certificates
ApplicationModel_Email --> Storage_Streams
ApplicationModel_Email --> System
ApplicationModel_Search --> ApplicationModel
ApplicationModel_Search --> Storage
ApplicationModel_Search --> Storage_Streams
ApplicationModel_UserDataAccounts_Provider --> ApplicationModel_UserDataAccounts
ApplicationModel_UserDataAccounts --> ApplicationModel
ApplicationModel_UserDataAccounts --> ApplicationModel_Appointments
ApplicationModel_UserDataAccounts --> ApplicationModel_Contacts
ApplicationModel_UserDataAccounts --> ApplicationModel_Email
ApplicationModel_UserDataAccounts --> ApplicationModel_UserDataAccounts_Provider
ApplicationModel_UserDataAccounts --> ApplicationModel_UserDataTasks
ApplicationModel_UserDataAccounts --> Storage_Streams
ApplicationModel_UserDataAccounts --> System
ApplicationModel_UserDataTasks --> ApplicationModel
ApplicationModel_UserDataTasks --> System
ApplicationModel_Wallet --> ApplicationModel
ApplicationModel_Wallet --> Storage_Streams
ApplicationModel --> ApplicationModel_Activation
ApplicationModel --> ApplicationModel_Appointments
ApplicationModel --> ApplicationModel_Appointments_AppointmentsProvider
ApplicationModel --> ApplicationModel_AppService
ApplicationModel --> ApplicationModel_Background
ApplicationModel --> ApplicationModel_Calls
ApplicationModel --> ApplicationModel_Contacts
ApplicationModel --> ApplicationModel_Contacts_Provider
ApplicationModel --> ApplicationModel_Core
ApplicationModel --> ApplicationModel_DataTransfer
ApplicationModel --> ApplicationModel_DataTransfer_ShareTarget
ApplicationModel --> ApplicationModel_Email
ApplicationModel --> ApplicationModel_Search
ApplicationModel --> ApplicationModel_UserDataAccounts
ApplicationModel --> ApplicationModel_UserDataAccounts_Provider
ApplicationModel --> ApplicationModel_UserDataTasks
ApplicationModel --> ApplicationModel_Wallet
ApplicationModel --> Devices_Bluetooth_Background
ApplicationModel --> Devices_Bluetooth_GenericAttributeProfile
ApplicationModel --> Devices_Sensors
ApplicationModel --> Devices_SmartCards
ApplicationModel --> Devices_Sms
ApplicationModel --> Security_Authentication_Web_Core
ApplicationModel --> Security_Credentials
ApplicationModel --> Storage
ApplicationModel --> Storage_Streams
ApplicationModel --> System
ApplicationModel --> System_RemoteSystems
ApplicationModel --> UI_Notifications
Data_Text --> UI_Text_Core
Data_Xml_Dom --> Storage
Data_Xml_Dom --> Storage_Streams
Devices_Bluetooth_Advertisement --> Devices_Bluetooth
Devices_Bluetooth_Advertisement --> Storage_Streams
Devices_Bluetooth_Background --> Devices_Bluetooth
Devices_Bluetooth_Background --> Devices_Bluetooth_Advertisement
Devices_Bluetooth_Background --> Devices_Bluetooth_GenericAttributeProfile
Devices_Bluetooth_Background --> Devices_Bluetooth_Rfcomm
Devices_Bluetooth_Background --> Networking_Sockets
Devices_Bluetooth_Background --> Storage_Streams
Devices_Bluetooth_GenericAttributeProfile --> Devices_Bluetooth
Devices_Bluetooth_GenericAttributeProfile --> Devices_Enumeration
Devices_Bluetooth_GenericAttributeProfile --> Storage_Streams
Devices_Bluetooth_Rfcomm --> Devices_Bluetooth
Devices_Bluetooth_Rfcomm --> Devices_Enumeration
Devices_Bluetooth_Rfcomm --> Networking
Devices_Bluetooth_Rfcomm --> Networking_Sockets
Devices_Bluetooth_Rfcomm --> Storage_Streams
Devices_Bluetooth --> Devices_Bluetooth_Advertisement
Devices_Bluetooth --> Devices_Bluetooth_Background
Devices_Bluetooth --> Devices_Bluetooth_GenericAttributeProfile
Devices_Bluetooth --> Devices_Bluetooth_Rfcomm
Devices_Bluetooth --> Devices_Enumeration
Devices_Bluetooth --> Networking
Devices_Bluetooth --> Storage_Streams
Devices_Enumeration --> ApplicationModel_Background
Devices_Enumeration --> Security_Credentials
Devices_Enumeration --> Storage_Streams
Devices_Sensors --> Graphics_Display
Devices_SmartCards --> Security_Cryptography_Core
Devices_SmartCards --> Storage_Streams
Devices_Sms --> Storage_Streams
Globalization --> System
Graphics_Display --> Storage_Streams
Media_SpeechRecognition --> Globalization
Media_SpeechRecognition --> Storage
Networking_Connectivity --> Networking
Networking_Connectivity --> Storage_Streams
Networking_Sockets --> ApplicationModel_Background
Networking_Sockets --> Networking
Networking_Sockets --> Networking_Connectivity
Networking_Sockets --> Security_Credentials
Networking_Sockets --> Security_Cryptography_Certificates
Networking_Sockets --> Storage_Streams
Networking_Sockets --> Web
Networking --> ApplicationModel_Activation
Networking --> ApplicationModel_Background
Networking --> Networking_Connectivity
Networking --> Networking_Sockets
Networking --> Storage_Streams
Networking --> System
Security_Authentication_Web_Core --> Security_Credentials
Security_Authentication_Web_Core --> System
Security_Authentication_Web_Provider --> Security_Authentication_Web_Core
Security_Authentication_Web_Provider --> Security_Credentials
Security_Authentication_Web_Provider --> Security_Cryptography_Core
Security_Authentication_Web_Provider --> Storage_Streams
Security_Authentication_Web_Provider --> System
Security_Authentication_Web_Provider --> Web_Http
Security_Credentials --> Security_Cryptography_Core
Security_Credentials --> Storage_Streams
Security_Credentials --> System
Security_Cryptography_Certificates --> Networking
Security_Cryptography_Certificates --> Storage_Streams
Security_Cryptography_Core --> Security_Cryptography_Certificates
Security_Cryptography_Core --> Storage_Streams
Security_EnterpriseData --> Networking
Security_EnterpriseData --> Storage
Security_EnterpriseData --> Storage_Streams
Storage_FileProperties --> Storage
Storage_FileProperties --> Storage_Streams
Storage_Pickers_Provider --> Storage
Storage_Provider --> Storage
Storage_Provider --> Storage_Search
Storage_Provider --> Storage_Streams
Storage_Search --> Data_Text
Storage_Search --> Storage
Storage_Search --> Storage_FileProperties
Storage_Search --> Storage_Streams
Storage_Streams --> Storage
Storage_Streams --> System
Storage --> Storage_FileProperties
Storage --> Storage_Pickers_Provider
Storage --> Storage_Provider
Storage --> Storage_Search
Storage --> Storage_Streams
Storage --> System
System_Diagnostics --> ApplicationModel_AppService
System_Diagnostics --> System
System_RemoteSystems --> ApplicationModel_AppService
System_RemoteSystems --> Networking
System_RemoteSystems --> Security_Credentials
System_RemoteSystems --> System
System --> ApplicationModel
System --> ApplicationModel_AppService
System --> Networking
System --> Security_Credentials
System --> Storage
System --> Storage_Search
System --> Storage_Streams
System --> System_Diagnostics
System --> System_RemoteSystems
System --> UI_ViewManagement
UI_Composition --> System
UI_Composition --> UI_Core
UI_Core --> System
UI_Core --> UI_Composition
UI_Core --> UI_Input
UI_Core --> UI_WindowManagement
UI_Input --> ApplicationModel_Core
UI_Input --> Storage_Streams
UI_Input --> System
UI_Input --> UI_Composition
UI_Input --> UI_Core
UI_Input --> UI_Text
UI_Input --> UI_WindowManagement
UI_Notifications --> ApplicationModel
UI_Notifications --> Data_Xml_Dom
UI_Notifications --> System
UI_Text_Core --> Globalization
UI_Text_Core --> UI_Text
UI_Text_Core --> UI_ViewManagement
UI_Text --> Storage_Streams
UI_Text --> UI_Text_Core
UI_ViewManagement --> Devices_Enumeration
UI_ViewManagement --> UI_Core
UI_ViewManagement --> UI_WindowManagement
UI_WindowManagement --> System
UI_WindowManagement --> UI_Composition
Web_Http_Filters --> Networking_Sockets
Web_Http_Filters --> Security_Credentials
Web_Http_Filters --> Security_Cryptography_Certificates
Web_Http_Filters --> System
Web_Http_Filters --> Web_Http
Web_Http_Headers --> Globalization
Web_Http_Headers --> Networking
Web_Http_Headers --> Storage_Streams
Web_Http_Headers --> Web_Http
Web_Http --> Globalization
Web_Http --> Networking_Sockets
Web_Http --> Security_Cryptography_Certificates
Web_Http --> Storage_Streams
Web_Http --> System
Web_Http --> System_Diagnostics
Web_Http --> Web
Web_Http --> Web_Http_Filters
Web_Http --> Web_Http_Headers
Web --> Globalization
Web --> Security_Credentials
Web --> Storage_Streams
Web --> System
Web --> System_Diagnostics
Web --> Web_Http
Web --> Web_Http_Filters
|
|
||
| ## Requirements | ||
|
|
||
| - MSVC v145 toolset (Visual Studio 2026) or later recommended |
There was a problem hiding this comment.
Worth calling out a patch level on top of just v145? It seems like very recent fixes are needed for this to work at all. Even the RTM build of VS 2026 is too old (I think).
There was a problem hiding this comment.
I'm not sure. The runner image has "only" VS2026 18.2, with the 14.50 MSVC build tools. I know 18.0 RTM shipped with some version of 14.50, but not sure how much older it is, and what the differences are.
I think the main point is that this is building and running on the 14.50 MSVC build tools, and so far doesn't do anything that requires the newer 14.51 tools (which are planned for VS 18.6).
|
|
||
| TEST_CASE("module_events") | ||
| { | ||
| winrt::event<winrt::Windows::Foundation::EventHandler<int>> my_event; |
There was a problem hiding this comment.
Out of curiosity does slim_source_location still work with the module boundary in place (I assume yes)?
There was a problem hiding this comment.
I've added a test to test_cpp20_module. Are there other cases I should check, or is that sufficient to verify it's working?
There was a problem hiding this comment.
I would have been satisfied with a manual one-off, but a recurring regression test is even better.
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
…generates into winrt/macros.h Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
C++20 Module Support v2: Per-Namespace Modules (
import winrt.Windows.Foundation;)Overview
This PR adds per-namespace C++20 module support to C++/WinRT, building on the approach pioneered by @YexuanXiao's cppwinrtplus fork. Instead of a single monolithic
import winrt;module (v1), each WinRT namespace gets its own named module:This provides finer-grained imports, better build parallelism, and first-class support for component authoring with modules.
Key Design Decisions
1. Unconditional guards, flag-controlled generation
Module awareness (guards,
WINRT_EXPORT) is always present in projection headers. The-modulesflag controls.ixxgeneration and whether generated component files (module.g.cpp, stub.cpp) useimportvs#include. Projection headers themselves are identical regardless of-modules.2. All three projections generate modules uniformly
When
CppWinRTBuildModule=true,-modulesis passed to the platform, reference, and component projections. There is no special module-specific handling that distinguishes these projections — the existing differences (e.g.,-optfor components,-compfor component stubs) are pre-existing behavior.3. Per-ProjectReference IFC consumption
CppWinRTConsumeModuleis metadata on aProjectReference, not a project-level property. When set, it suppresses-moduleson the platform projection (since IFCs are already available from the referenced project) but does not affect the reference or component projections. This gives precise control over which pre-built IFCs to reuse.4. SCC consolidation for cyclic namespaces
Tarjan's algorithm groups cyclic namespaces. The alphabetically-first namespace owns the module; others re-export it. Users can
import winrt.AnyNamespace;regardless of SCC membership.What's in This PR
Code generator (
cppwinrt/)main.cpp-modules,-module_include,-module_excludeCLI options. Two-pass namespace loop: first populates module namespace set, then generates headers with dependency collection. Tarjan's SCC algorithm. .ixx generation loop.file_writers.hwrite_macros_h(),write_module_preamble(),write_base_ixx(),write_numerics_ixx(),write_namespace_ixx(),write_namespace_scc_owner_ixx(),write_namespace_reexport_ixx(). UnconditionalWINRT_IMPORT_MODULE/WINRT_IMPL_BUILD_MODULEguards on all generated headers. Component.g.hdual-path (import vs include).base.hnow#includeswinrt/base_macros.hinstead of inlining macros.code_writers.hwrap_module_aware_includes_guard()updated comment.wrap_impl_namespace()usesWINRT_EXPORT namespace winrt::impl.settings.hbool modules,std::set module_include/exclude,winmd::reader::filter module_filter.String literals (
strings/)namespace winrt::impl→WINRT_EXPORT namespace winrt::implnamespace std→WINRT_IMPL_STD_EXPORT namespace stdbase_macros.hrefactored as canonical shared macroswinrt/base_macros.h, used by bothbase.hand.ixxglobal fragmentsbase_source_location.hslim_source_location(split frombase_macros.h)base_module_ixx_preamble.h.ixxfilesbase_module_base_ixx.hwinrt_base.ixxtemplatebase_module_numerics_ixx.hwinrt_numerics.ixxtemplatebase_extern.hWINRT_EXPORTto handler function pointers for module/non-module linkagebase_fast_forward.hWINRT_EXPORTfallback definitionMSBuild integration (
nuget/)User-facing properties:
CppWinRTBuildModule-modulesfor all three projections, generating.ixxfiles alongside headersCppWinRTModuleIncludeCppWinRTModuleExcludeCppWinRTConsumeModule.ixxgeneration and uses pre-built IFCs from the referenced projectInternal targets (not directly configured by users):
CppWinRTAddModuleInterfaces.ixxfiles and adds them as ClCompile items with module compilation metadataCppWinRTGetModuleOutputsCppWinRTResolveModuleReferencesCppWinRTGetModuleOutputson ProjectReferences tagged withCppWinRTConsumeModuleTest projects
test/test_cpp20_module/test/nuget/TestModuleBuilder/test/nuget/TestModuleComponent1/test/nuget/TestModuleComponent2/test/nuget/TestModuleConsumerApp/test/nuget/TestModuleApp/Documentation
nuget/modules.mddocs/modules-design.md.github/instructions/cppwinrt.instructions.md.github/instructions/modules.instructions.mdBefore / After: User Code
Header mode (unchanged)
Module mode (new)
Component authoring with modules
Before / After: Generated Code
Namespace header (
winrt/Windows.Foundation.h) — guard changesBefore (no module awareness):
After (unconditional module guards):
New: Generated module interface (
winrt.Windows.Foundation.ixx)New: SCC owner module (cycle breaker)
When namespaces form dependency cycles (e.g.,
Windows.Foundation↔Windows.Foundation.Collections), the alphabetically-first namespace becomes the SCC owner:New: Component
.g.h(dual-path)Differences from the cppwinrtplus Fork
This implementation shares the same core architecture as @YexuanXiao's cppwinrtplus fork — per-namespace modules, Tarjan SCC cycle breaking,
WINRT_EXPORTmacro — but diverges in several areas:Module naming
winrt.basewinrt_basewinrt.numericswinrt_numerics<Namespace>.ixx(e.g.Windows.Foundation.ixx)winrt.<Namespace>.ixx(e.g.winrt.Windows.Foundation.ixx)The
winrt.prefix on namespace modules avoids potential collisions if other code generators produce modules with the same namespace names. Thewinrt_base/winrt_numericsunderscore form avoids a dotted name that could imply a namespace hierarchy.Module namespace filtering
cppwinrtplus uses a
CppWinRT.configXML file in the solution directory with<exclude><prefix>elements to exclude namespaces from module generation. This PR uses-module_include/-module_excludeCLI flags with prefix matching, exposed asCppWinRTModuleInclude/CppWinRTModuleExcludeMSBuild properties. The CLI approach integrates directly into MSBuild response files without needing a separate config file, and supports both include and exclude semantics.Guard macros
WINRT_MODULEWINRT_IMPL_BUILD_MODULEWINRT_CONSUME_MODULEWINRT_IMPORT_MODULE-modulesflagMaking guards unconditional means the
-modulesflag controls.ixxgeneration and module-aware component code generation (.g.cpp,module.g.cpp, stub.cpp), but does NOT change the content of projection headers — they work in both module and header mode without regeneration.Builder/consumer architecture
cppwinrtplus does not have a concept of sharing pre-built IFCs across projects — each project builds all its own modules. This PR introduces:
CppWinRTBuildModule— project-level property to enable module generation for all three projectionsCppWinRTConsumeModule— per-ProjectReference metadata that suppresses platform.ixxgeneration and lets the project use pre-built IFCs from the referenced project insteadCppWinRTGetModuleOutputs/CppWinRTResolveModuleReferences— Internal MSBuild targets for cross-project IFC path resolutionAcknowledgements
Credit to @YexuanXiao and the cppwinrtplus fork for the per-namespace module architecture, SCC algorithm, and initial demonstration of viability. Also @sylveon, @Scottj1s, and @zadjii-msft for early module exploration and feedback on v1.