microsoft / microsoft/cppwinrt

Bug: Incremental build with C++/WinRT 3.0 modules loses CppWinRTPlatformWinMDReferences, causing Windows.Foundation.Point could not be found

Open
#1,587 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
1.9k
Forks
281
PR merge metrics
No merged PRs in 30d

Description

Version

3.0.260520.1

Summary

I am migrating a WinAppSDK C++/WinRT project to the new C++/WinRT 3.0 module build.

The solution uses a dedicated module provider project:

<ProjectReference Include="..\..\CppWinRTModules\CppWinRTModules.vcxproj">
  <Project>{...}</Project>
  <CppWinRTConsumeModule>true</CppWinRTConsumeModule>
</ProjectReference>

A clean/rebuild works, but an incremental build fails during the C++/WinRT reference projection step.

The failure occurs when cppwinrt processes Microsoft.Graphics.winmd from the WinAppSDK experimental packages:

cppwinrt : error Type 'Windows.Foundation.Point' could not be found
 method: RedPrimary
 type: Microsoft.Graphics.Display.IDisplayAdvancedColorInfo
 database: ...\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.2.0.14-experimental\metadata\10.0.18362.0\Microsoft.Graphics.winmd

The project does not use RedPrimary directly. This appears to happen while processing the metadata database.

Environment

Visual Studio: 18 Professional
MSVC: 14.51.36231
C++/WinRT NuGet: Microsoft.Windows.CppWinRT 3.0.260520.1
Windows SDK: 10.0.26100.0
Configuration: x64 Release / x64 Debug
WindowsAppSDK packages include:
  Microsoft.WindowsAppSDK.2.1.4-experimental8
  Microsoft.WindowsAppSDK.Foundation.2.0.22-experimental
  Microsoft.WindowsAppSDK.WinUI.2.1.1-experimental
  Microsoft.WindowsAppSDK.InteractiveExperiences.2.0.14-experimental
  Microsoft.WindowsAppSDK.AI.2.1.13-experimental
  Microsoft.WindowsAppSDK.Search.2.1.13-experimental
  Microsoft.WindowsAppSDK.Widgets.2.0.6-experimental
Reproducible example

Expected behavior

During the failing incremental build, the C++/WinRT diagnostic output shows that the direct WinMD references are present, but the platform WinMD references are empty:

CppWinRTPlatformWinMDReferences:
CppWinRTDirectWinMDReferences:
  ...\Microsoft.Graphics.winmd
  ...\Microsoft.UI.winmd
  ...\Microsoft.UI.Xaml.winmd
  ...

Then the generated command runs:

cppwinrt @"x64\Release\CppWinRTModules.vcxproj.cppwinrt_ref.rsp"

The tool output shows many in: entries for WinAppSDK package WinMDs, but no corresponding Windows SDK ref: entries. Therefore Microsoft.Graphics.winmd cannot resolve Windows.Foundation.Point.

After adding a workaround target, the same build succeeds. The log then shows CppWinRTPlatformWinMDReferences and CppWinRTPlatformWinMDInputs populated with the Windows SDK contract WinMDs such as Windows.Foundation.FoundationContract.winmd, Windows.Foundation.UniversalApiContract.winmd, Windows.Networking.Connectivity.WwanContract.winmd, etc.

Actual behavior

Clean/rebuild succeeds.

Incremental build fails because CppWinRTPlatformWinMDReferences is empty when CppWinRTMakeReferenceProjection runs, causing cppwinrt_ref.rsp to omit Windows SDK references.

Additional comments

Workaround

Adding this target to the project repairs the incremental build:

<Target Name="ForceCppWinRTPlatformWinMDReferences"
        BeforeTargets="CppWinRTMakeReferenceProjection">

  <ItemGroup Condition="'@(CppWinRTPlatformWinMDReferences)' == ''">
    <CppWinRTPlatformWinMDReferences Include="$(WindowsSDK_MetadataPathVersioned)\**\*.winmd" />
  </ItemGroup>

  <Message Text="Forced CppWinRTPlatformWinMDReferences from $(WindowsSDK_MetadataPathVersioned)"
           Importance="High"
           Condition="'@(CppWinRTPlatformWinMDReferences)' != ''" />

</Target>

After this, the build succeeds because the Windows SDK WinMDs are passed into the C++/WinRT projection step.

Notes

I also tried:
<CppWinRTEnableReferenceProjection>false</CppWinRTEnableReferenceProjection>
but that is not viable because the module provider then no longer generates required modules such as:

import winrt.Microsoft.UI;
import winrt.Microsoft.UI.Dispatching;
import winrt.Microsoft.UI.Xaml;
import winrt.Microsoft.UI.Xaml.Controls;
import winrt.Microsoft.UI.Xaml.Media;

I also tried excluding Microsoft.Graphics.Display, but that caused the module provider to generate almost no WinRT namespace modules, so that is not a usable workaround either.

The issue seems to be specifically that the incremental CppWinRTMakeReferenceProjection path does not populate CppWinRTPlatformWinMDReferences, while clean/rebuild does.

Minimal question

Is this expected behavior for C++/WinRT 3.0 module provider projects using true?

If not, should Microsoft.Windows.CppWinRT.targets ensure that CppWinRTPlatformWinMDReferences is populated before CppWinRTMakeReferenceProjection during incremental builds?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Inspect Microsoft.Windows.CppWinRT.targets around CppWinRTMakeReferenceProjection and the CppWinRTPlatformWinMDReferences inputs. Reproduce both clean and incremental builds for a module provider using CppWinRTConsumeModule, then compare the generated cppwinrt_ref.rsp contents. Done means incremental builds include the Windows SDK contract WinMD references and no longer fail to resolve Windows.Foundation.Point.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
build-system, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.