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

.NET Framework 4.8 build with SGen.exe fails when referencing a .NET Standard 2.0 project #23225

Open MaaadMax opened 2 years ago

MaaadMax commented 2 years ago

Describe the bug

After I have ported some class libraries to .NET Standard 2.0, I get the following error message when building a .NET Framework 4.8 project which references a .NET Standard 2.0 project: The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.

After some investigation I found out that the build only fails when GenerateSerializationAssemblies is set to On and SGenUseProxyTypes is set to false in the .NET Framework project. When I set SGenUseProxyTypes to true or remove it the build succeeds.

I hope this is the right place for this bug report.

To Reproduce

Attached you'll find a small repro with both projects.

Exceptions

CS0012 The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'

Further technical details

.NET SDK (reflecting any global.json): Version: 6.0.101 Commit: ef49f6213a

Runtime Environment: OS Name: Windows OS Version: 10.0.19042 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\6.0.101\

Host (useful for support): Version: 6.0.1 Commit: 3a25a7f1cc

KalleOlaviNiemitalo commented 2 years ago

The error happens regardless of whether the project targeting .NET 4.8 is a legacy project or a .NET SDK project.

MSBuild runs C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\sgen.exe with a /reference option that includes C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\Facades\netstandard.dll, but sgen.exe then runs csc.exe with a series of /R options that does not include /R:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\Facades\netstandard.dll". If I run csc.exe directly, with the same command line plus that option, then it succeeds.

I think this would need a fix in sgen.exe, but is that even open source?

KalleOlaviNiemitalo commented 2 years ago

https://github.com/dotnet/sdk/issues/10255#issuecomment-597749427 suggests using Microsoft.XmlSerializer.Generator instead of sgen.exe. If I remove the GenerateSerializationAssemblies MSBuild property, and add both a PackageReference and a DotNetCliToolReference as instructed in https://docs.microsoft.com/dotnet/core/additional-tools/xml-serializer-generator, then the build succeeds and the generated serializer does read the Class1.NetStandard property.

It's a bit surprising though; I thought DotNetCliToolReference was being deprecated (https://github.com/dotnet/sdk/issues/3115) and replaced with tool manifests. https://github.com/dotnet/docs/issues/26253 has been filed.

MaaadMax commented 2 years ago

#10255 (comment) suggests using Microsoft.XmlSerializer.Generator instead of sgen.exe. If I remove the GenerateSerializationAssemblies MSBuild property, and add both a PackageReference and a DotNetCliToolReference as instructed in https://docs.microsoft.com/dotnet/core/additional-tools/xml-serializer-generator, then the build succeeds and the generated serializer does read the Class1.NetStandard property.

It's a bit surprising though; I thought DotNetCliToolReference was being deprecated (#3115) and replaced with tool manifests. dotnet/docs#26253 has been filed.

With the XML serializer generator it actually works. It isn't the best solution because I have to update 20+ projects but if SGEN.exe won't be ported to .NET Core, it may be the only solution.

Thanks for your help!