Set up dual reference assembly build for WinRT.Runtime#2444
Merged
Sergio0694 merged 7 commits intoJun 17, 2026
Merged
Conversation
333dcf1 to
8ee5f6a
Compare
8ee5f6a to
8d17cee
Compare
This was referenced Jun 17, 2026
Prevent the SDK-produced reference assembly from leaking implementation-only types by customizing the ref-assembly build. When not building the explicit CsWinRT reference assembly, ProduceReferenceAssembly is disabled and WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY is defined to simplify #if usage. When CsWinRTBuildReferenceAssembly is true, WINDOWS_RUNTIME_REFERENCE_ASSEMBLY is defined and expected warnings (CS8597, IDE0005, IDE0380) are suppressed. A BeforeTargets CoreCompile target removes files that opt out of reference assemblies (via WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE), ABI sources, and several implementation-only folders so the packaged reference assembly omits private implementation details.
Wrap Windows runtime metadata and platform/contract attributes with build-time symbols to differentiate reference vs implementation assemblies. Many files now conditionally include Windows.Foundation.Metadata usings and apply [ContractVersion]/[SupportedOSPlatform] for WINDOWS_RUNTIME_REFERENCE_ASSEMBLY and [WindowsRuntimeMetadata]/[WindowsRuntimeClassName]/marshalling attributes for WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY. Removed unconditional SupportedOSPlatform/usings where appropriate and added #if guards across foundation, collections, streams, async adapters and task/asyncinfo helpers to allow building both reference and implementation variants. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Suppress CS1574 (XML doc 'cref' not found) warnings in WindowsRuntimeFeatureSwitches.cs by adding `#pragma warning disable CS1574` before the namespace declaration. This prevents spurious documentation warnings during the build, likely caused by cref references to internal or conditional types.
Rename/move WindowsRuntimeInspectable.cs from src/WinRT.Runtime2/ to src/WinRT.Runtime2/NativeObjects/ to reorganize project structure. File content unchanged (100% similarity).
Move the core implementation into a new partial file (src/WinRT.Runtime2/WindowsRuntimeObject.Impl.cs) and make WindowsRuntimeObject partial. The impl file contains caching, dynamic cast lookup, generated COM vtable handling, QueryInterface logic, activation constructors and an exceptions helper; redundant usings/implementation were removed from WindowsRuntimeObject.cs to keep the public surface unchanged.
Introduce compile-time guards to separate reference and implementation builds. Many files were marked as implementation-only by adding a WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE define; APIs and method bodies were wrapped with WINDOWS_RUNTIME_REFERENCE_ASSEMBLY / WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY conditionals (throw null in reference builds, real code in implementation builds). Adjustments touch attributes, interop/activation, marshalling, async helpers, buffer/stream utilities, and WindowsRuntimeMarshal/RestrictedErrorInfo/RestrictedErrorInfoExceptionMarshaller. Also updated the project file to exclude the Marshalling folder from the reference build. This enables producing lightweight reference assemblies while keeping full implementations in the implementation assembly.
…untime Replace the plain #else branch following #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY with an explicit #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY for clarity. The two constants are mutually exclusive and exhaustive, so the behavior is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8d17cee to
a27b766
Compare
manodasanW
approved these changes
Jun 17, 2026
2394cbf
into
staging/winrt-runtime-ref-assembly
11 checks passed
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
Set up the dual reference/implementation assembly build for
WinRT.Runtime. The normal build produces the full implementationWinRT.Runtime.dll, while an explicit, opt-in build (CsWinRTBuildReferenceAssembly=true) produces a lightweight reference assembly that exposes only the public API surface plus the WinRT metadata that reference projections need.This is the follow-up to #2434 (which added the
[WindowsRuntimeImplementationOnlyMember]marker and explicitly promised this change). A subsequent, final PR will wire this build into the packaging and build infrastructure so the reference assembly is actually produced and shipped.Motivation
Reference projections compile against a reference assembly for
WinRT.Runtime. That reference assembly must expose only the public API surface and the WinRT metadata attributes projections consume (e.g.[ContractVersion],[SupportedOSPlatform]), while completely omitting private implementation-detail types: ABI marshallers, native object wrappers, and the rest of the interop infrastructure.The SDK-generated reference assembly is not suitable here: it would include those implementation-only types (since
WINDOWS_RUNTIME_REFERENCE_ASSEMBLYis not defined in a normal build), leaking abstract members to downstreamProjectReferenceconsumers and breaking reference projections. This PR therefore disables the default SDK reference assembly and introduces a dedicated reference assembly build that strips implementation details at the source level, keeping the public surface identical between the two flavors.Changes
src/WinRT.Runtime2/WinRT.Runtime.csproj: Disable the SDK's defaultProduceReferenceAssemblyfor normal builds and defineWINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY. WhenCsWinRTBuildReferenceAssembly=true, defineWINDOWS_RUNTIME_REFERENCE_ASSEMBLY, suppress the warnings that are expected only in the reference build (CS8597,IDE0005,IDE0380), and add aBeforeTargets="CoreCompile"target that removes implementation-only sources from the compilation: files opting out via#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE, allABI\**sources, and the implementation-onlyExceptions\**,NativeObjects\**, andInteropServices\**subfolders.src/WinRT.Runtime2/: Mark implementation-only files with#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE; split type attributes so the reference assembly carries the Windows metadata ([ContractVersion],[SupportedOSPlatform]) and the implementation assembly carries the interop/marshalling attributes ([WindowsRuntimeMetadata],[WindowsRuntimeClassName],[WindowsRuntimeReferenceType],[ABI...Marshaller]); replace method bodies withthrow null;underWINDOWS_RUNTIME_REFERENCE_ASSEMBLY; and guard theusingdirectives accordingly. This avoids sprinkling thousands of#if-s by combining file-level removal with per-member guards only where needed.src/WinRT.Runtime2/WindowsRuntimeObject.csandWindowsRuntimeObject.Impl.cs: MakeWindowsRuntimeObjectpartialand move all implementation (caching, dynamic-cast lookup, generated COM vtable handling, QueryInterface logic, activation constructors, and the exceptions helper) into a newWindowsRuntimeObject.Impl.cs, so the implementation can be excluded from the reference assembly while the public surface remains inWindowsRuntimeObject.cs.src/WinRT.Runtime2/NativeObjects/WindowsRuntimeInspectable.cs: MoveWindowsRuntimeInspectableinto theNativeObjects/folder (content unchanged) so it is covered by the implementation-only folder removal.src/WinRT.Runtime2/InteropServices/Platform/ComCallData.csandHSTRING_HEADER.cs: Apply[StructLayout(LayoutKind.Sequential)](including the_Reservedunion) to guarantee the correct native layout for interop.src/WinRT.Runtime2/Properties/WindowsRuntimeFeatureSwitches.cs: SuppressCS1574(spurious XML-doccrefwarning) so the build stays clean.Validation
Verified locally that both flavors build and that the reference assembly is correctly stripped:
CsWinRTBuildReferenceAssembly=true) both compile cleanly.WindowsRuntimeDllModule,TaskAdapter,WindowsRuntimeInspectable,PointComWrappersMarshaller,IListAdapter, ABI marshallers) are present in the implementation.dllbut absent from the reference.dll.WindowsRuntimeObject,IAsyncAction,Point,AsyncStatus) are present in both, confirming the public API is unchanged..dllis substantially smaller than the implementation.dll(roughly 150 KB vs 800 KB).