dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.75k stars 1.07k forks source link

Building with SDK 8.0.403 unexpectedly generates WinRT-related code #44026

Open chris-white-wtw opened 1 month ago

chris-white-wtw commented 1 month ago

Describe the bug

After updating the .NET SDK from 8.0.402 to 8.0.403, some projects that target net8.0-windows10.0.19041.0 have started generating unexpected WinRT-related code via source generator WinRT.SourceGenerator.

The generated code uses language features only available in C# 9+, which in this case causes compilation to fail, but the main issue is that this source generator generates anything at all: this is not a project that uses WinRT, and with SDK 8.0.402 this doesn't happen.

Additionally, we are seeing diagnostics CsWinRT1028 and CsWinRT1030, which we do not see with 8.0.402.

To Reproduce

See https://github.com/chris-white-wtw/dotnet-sdk-winrt-issue.

Using SDK 8.0.403, build test.csproj.

Exceptions (if any)

No exceptions, just a compilation error:

C:\git\dotnet-sdk-winrt-issue\test\obj\Debug\net8.0-windows10.0.19041.0\generated\WinRT.SourceGenerator\Generator.WinRT
AotSourceGenerator\WinRTGlobalVtableLookup.g.cs(11,10): error CS8370: Feature 'module initializers' is not available in
 C# 7.3. Please use language version 9.0 or greater. [C:\git\dotnet-sdk-winrt-issue\test\test.csproj]

Further technical details

dotnet --info:

.NET SDK:
 Version:           8.0.403
 Commit:            c64aa40a71
 Workload version:  8.0.400-manifests.18f19b92
 MSBuild version:   17.11.9+a69bbaaf5

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19045
 OS Platform: Windows
 RID:         win-x64
 Base Path:   c:\work\dotnet\dotnet\sdk\8.0.403\

.NET workloads installed:
Configured to use loose manifests when installing new manifests.
 [aspire]
   Installation Source: VS 17.10.35013.160
   Manifest Version:    8.0.0-preview.1.23557.2/8.0.100
   Manifest Path:       c:\work\dotnet\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.0.0-preview.1.23557.2\WorkloadManifest.json
   Install Type:        FileBased

Host:
  Version:      8.0.10
  Architecture: x64
  Commit:       81cabf2857

.NET SDKs installed:
  8.0.403 [c:\work\dotnet\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.10 [c:\work\dotnet\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.10 [c:\work\dotnet\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 8.0.10 [c:\work\dotnet\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  C:\git\dotnet-sdk-winrt-issue\global.json

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

No particular IDE - running from command line.

AliveDevil commented 1 month ago

Related: https://github.com/microsoft/CsWinRT/blob/2.1.5.241003.1/nuget/Microsoft.Windows.CsWinRT.targets#L21

Set <CsWinRTAotOptimizerEnabled> to false.

chris-white-wtw commented 1 month ago

Thanks @AliveDevil, I can confirm that setting this property works around the issue for our affected projects

27k1 commented 1 month ago

I can confirm this fix works

Balkoth commented 1 month ago

So what's the deal here? Is it ok to disable the optimizer or should the warnings be fixed? Why is this enabled by default even when no other trimmer option is enabled in the project? And how many of those trimmer options is dotnet going to introduce? There are already so many that no one can remember them.

AliveDevil commented 1 month ago

Hopefully, they'll make this Opt-In to all the interfaces you want exposed to WinRT/AOT: https://github.com/microsoft/CsWinRT/issues/1814

rjsams commented 1 month ago

CsWinRT1028 is being generated for simple classes. Ex: Create an empty class, implement IDispose, and the warning will be generated. IMO, foundational interfaces should not be triggering this.

Neither AOT nor trimming was enabled in that test case.

thirstyape commented 1 month ago

The fix by @AliveDevil worked for me too.

For others, I saw this issue in another variety, error logs were not clear, as with the original post WinRTGlobalVtableLookup.g.cs was mentioned.

~\WinRT.SourceGenerator\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs(5,20): error CS0116: A namespace cannot directly contain members such as fields, methods or statements [~\my_project.csproj::TargetFramework=net8.0-windows10.0.19041.0]
~\WinRT.SourceGenerator\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs(5,29): error CS0116: A namespace cannot directly contain members such as fields, methods or statements [~\my_project.csproj::TargetFramework=net8.0-windows10.0.19041.0]
~\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs(5,19): error CS1514: { expected [~\my_project.csproj::TargetFramework=net8.0-windows10.0.19041.0]
~\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs(5,28): error CS1022: Type or namespace definition, or end-of-file expected [~\my_project.csproj::TargetFramework=net8.0-windows10.0.19041.0]
~\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs(6,1): error CS1022: Type or namespace definition, or end-of-file expected [~\my_project.csproj::TargetFramework=net8.0-windows10.0.19041.0]
paulpv commented 1 month ago

Posting this to hopefully help others that start seeing this.

I am not certain of the OP issue, but on a relatively simple personal hobby project I am working on I started to see these error when compiling:

Type Code Description File Line
Error CS0116 A namespace cannot directly contain members such as fields, methods or statements obj\Debug\net8.0-windows10.0.26100.0\WinRT.SourceGenerator\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs 5
Error CS1022 Type or namespace definition, or end-of-file expected obj\Debug\net8.0-windows10.0.26100.0\WinRT.SourceGenerator\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs 6
Error CS1514 { expected obj\Debug\net8.0-windows10.0.26100.0\WinRT.SourceGenerator\Generator.WinRTAotSourceGenerator\WinRTGlobalVtableLookup.g.cs 5

My C# WinForms app and libs do not explicitly use WinRT (they do pinvoke some user32.dll calls).

I found this issue and then https://github.com/microsoft/CsWinRT/issues/1814.

I edited my .csproj file to add CsWinRTAotOptimizerEnabled as follows:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework>
    ...
    <CsWinRTAotOptimizerEnabled>false</CsWinRTAotOptimizerEnabled>
  </PropertyGroup>
...

The problem went away.

I changed CsWinRTAotOptimizerEnabled to true.

The problem came back.

I will be leaving CsWinRTAotOptimizerEnabled set to false.

ekalchev commented 1 month ago

None of the proposed solution in the linked issues doesn't work for me. The only thing that worked was to uninstall .net sdk 8.0.403

awakecoding commented 1 month ago

Same as @ekalchev here - the issue occurs with .NET SDK 8.0.403, and I double checked with a diagnostic build log that CsWinRTAotOptimizerEnabled was properly set to false, it simply has no effect: the WinRT source generator keeps getting called, wasting a good 30 seconds doing nothing useful in our builds. This commit between 8.0.402 and 8.0.403 appears to be the relevant: https://github.com/dotnet/sdk/commit/ec0ad19377bc77ea1d394220bd6a76c01191341d

baronfel commented 1 month ago

Tagged @Sergio0694 and @manodasanW for follow-up - Sergio said this should be fixed soon but they may have more details.

awakecoding commented 1 month ago

Is there a temporary hack? I literally edited C:\Program Files\dotnet\sdk\8.0.403\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Windows.targets to first comment out the potentially offending line, then decided to just explicitly set false, and guess what? The WinRT source generator still gets called in our builds. This tells me that the bug could be in Microsoft.Windows.SDK.NET.Ref which is supposed to consume the CsWinRTAotOptimizerEnabled variable, but I have no idea where the right files to locally modify are.

Image

awakecoding commented 1 month ago

We found a temporary hack. We've explicitly removed the Microsoft.Windows.SDK.NET.Ref framework reference in one of our core csproj files by adding this:

<ItemGroup>
    <FrameworkReference Remove="Microsoft.Windows.SDK.NET.Ref" />
</ItemGroup>

Since we apparently don't need Microsoft.Windows.SDK.NET.Ref and it was getting added automatically, removing it works around the issue entirely. CsWinRTAotOptimizerEnabled does seem to be set to false properly, but Microsoft.Windows.SDK.NET.Ref appears to be ignoring it.

Sergio0694 commented 1 month ago

Why did you have to do this? Was setting CsWinRTAotOptimizerEnabled to false not working in your project?

awakecoding commented 1 month ago

Why did you have to do this? Was setting CsWinRTAotOptimizerEnabled to false not working in your project?

Exactly, setting CsWinRTAotOptimizerEnabled to false has no effect, we've tried every way possible, enabled diagnostic logging to ensure it was set to false, and even went as far as modifying Microsoft.NET.Windows.targets directly to force it to false. Our conclusion is that CsWinRTAotOptimizerEnabled is simply ignored by Microsoft.Windows.SDK.NET.Ref

ekalchev commented 1 month ago

I can confirm that settings CsWinRTAotOptimizerEnabled = false on the project that emit the error doesn't help

ekalchev commented 4 weeks ago

To work around this issue, I initially uninstalled .NET SDK 8.0.403. However, when I set up a new development machine with a fresh Visual Studio installation, it automatically installed the latest SDK, which is 8.0.403. This led to the same build issue. Unfortunately, I cannot uninstall SDK 8.0.403 this time because it was installed via Visual Studio. Windows requires uninstallation through the Visual Studio Installer, but this process tries to remove all dependent components, including .NET Desktop Development. Essentially, there is no workaround for a new Visual Studio installation. I have been struggling with this for two days and am out of ideas on how to resolve it.

ekalchev commented 4 weeks ago

For the people like me that cannot uninstall SDK 8.0.403. Here workaround I found.

    <Target Name="DisableWinRTSourceGenerator" BeforeTargets="CoreCompile">
        <ItemGroup>
            <Analyzer Remove="@(Analyzer)"
                      Condition="'%(FileName)%(Extension)' == 'WinRT.SourceGenerator.dll'"/>
        </ItemGroup>
    </Target>
awakecoding commented 4 weeks ago

Has this been acknowledged as an issue by anybody from Microsoft yet? We're quite a few people that can confirm this really is an issue, and workarounds are required to regain build performance. @Sergio0694

ekalchev commented 4 weeks ago

@awakecoding, @baronfel from Microsoft is looking at this. He asked me for logs. See my response in the other issue here https://github.com/dotnet/sdk/issues/44145