Skip to content

Conversation

@manodasanW
Copy link
Member

  • With this change, projection projects need CsWinRTGenerateReferenceProjection set to true. When this is set, a reference assembly and a forwarder assembly is generated (replaces the output DLL that gets built).
  • Components would distribute both these binaries and with project references they would just flow through.
  • On the final app project which consumes all the reference projection assemblies, cswinrt is triggered to generate a merged projection of all of them. The forwarders are also included in the output folder which means any references to the projection DLL are forwarded to the merged projection DLL.
  • In the reference projections, we exclude the entire ABI namespace. This was achieved via changes to codewriters based on detecting a reference projection is being generated. The changes here could have been more scoped if we just built only a reference assembly with ProduceOnlyReferenceAssembly which is possible but that relied on an assumption that if we generated sources which referenced ABI namespaces that aren't there that they will continue to build like they do today and also have more msbuild target changes to enable (seen here). So, to keep it straight forward, we do the equivalent in codewriters instead.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for reference projections in CsWinRT, enabling a new build configuration where projection projects can generate reference assemblies and forwarder assemblies, with a merged projection created at the final application level.

Key Changes:

  • Adds new CsWinRTGenerateReferenceProjection property and CSWINRT_REFERENCE_PROJECTION conditional compilation symbol
  • Introduces code generation modifications to exclude ABI namespace types when generating reference projections
  • Implements new generator tools (cswinrtprojectiongen and cswinrtimplgen) with supporting infrastructure

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/cswinrt/settings.h Adds reference_projection boolean flag to settings
src/cswinrt/main.cpp Implements command-line argument parsing and conditional ABI namespace generation
src/cswinrt/code_writers.h Modifies code writers to conditionally generate throw null stubs and exclude ABI-related attributes
src/cswinrt/strings/ComInteropHelpers.cs Wraps interop helper implementations with preprocessor directives
src/cswinrt/strings/additions/* Conditionally excludes marshaller attributes for reference projections
src/WinRT.Projection.Generator/* New projection generator tool for creating merged projections
src/RunCsWinRTGeneratorTask/* New MSBuild tasks for running generator tools
nuget/Microsoft.Windows.CsWinRT.targets Configures build properties and targets for reference projection support
src/cswinrt.slnx Updates solution configuration
src/Directory.Packages.props Updates Roslyn package versions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

manodasanW and others added 2 commits December 6, 2025 19:02
…Generate.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
if (settings.reference_projection)
{
w.write(R"(
private static WindowsRuntimeObjectReference %
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WindowsRuntimeObjectReference is a private implementation detail type, so we shouldn't use it in the ref assembly. Can we skip emitting this property entirely, since it's private anyway? Like, we shouldn't need to emit any non-public members in general.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal was to leave as much as to the .NET reference assembly thing to remove things that are not on the public API surface. So these should still be removed in the reference assembly. But I will note that the protected constructors do show up which do reference WindowsRuntimeObjectReference. I wonder if we should remove those in ref assemblies or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmmhhhhh. I would think we should be able to remove them, since at runtime the method would still be there anyway. The only difference is that user code would not be able to see them. Which honestly is even better. @jkoritzinsky can you confirm that it's fine for us to omit those constructors in the ref assemblies?

Comment on lines 6 to 7
[WindowsRuntimeMetadata("Microsoft.UI")]
[WindowsRuntimeClassName("Windows.Foundation.IReference<Microsoft.UI.Xaml.Media.Animation.KeyTime>")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these attributes should also be hidden from reference assemblies, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically we use these in cswinrtgen right?

/// </summary>
public AssemblyReference WinRTProjection => field ??= new AssemblyReference(
name: "WinRT.Projection"u8,
version: new Version(0, 0, 0, 0),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking this should rather match the .dll version with WinRT.Interop.dll? You can copy the logic we use for that.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants