Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microsoft.XmlSerializer.Generator does not support incremental build #53039

Closed
jeffreyrivor opened this issue May 20, 2021 · 4 comments
Closed
Assignees
Milestone

Comments

@jeffreyrivor
Copy link

Description

After adding XML serializer generation to an SDK-style project, the serialization DLL is always rebuilt even when incremental build skips the CoreCompile target because it has detected that no code has changed.

  • Run dotnet build which materializes the intermediate CS/DLL/PDB files (in obj) and copies output DLL/PDB files (in bin) for the serializer
  • Run dotnet build again, core compilation is skipped so no file timestamps are changed, but the serialization intermediate CS/DLL/PDB files are recreated with new timestamps which are copied to output (bin)
    • Additionally, the generated CS file is slightly different each time in the generated XmlSerializationReader1.InitIDs() method which appears to be non-deterministic. I'm not sure if being source-level deterministic on generated code is required to consider the overall build deterministic.

Configuration

.NET Core SDK 5.0.203 on Windows 10 x64

<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.XmlSerializer.Generator" Version="5.0.0" PrivateAssets="All" />
	</ItemGroup>

	<ItemGroup>
		<DotNetCliToolReference Include="Microsoft.XmlSerializer.Generator" Version="5.0.0" />
	</ItemGroup>
</Project>

Regression?

No, it seems like incremental build support was not part of the porting of .NET Framework SGen MSBuild task to Microsoft.XmlSerializers.Generator .NET Core tool.

Other information

It seems like more of the MSBuild logic for Compile (e.g. GenerateAssemblyInfo for #49003 and the logic for Inputs on the CoreCompile target) is needed to bring the serialization generator more in line with the features (assembly attributes, incremental build, deterministic build) of the normal compilation flow.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-Serialization untriaged New issue has not been triaged by the area owner labels May 20, 2021
@Latency
Copy link

Latency commented May 21, 2021

  <ItemGroup Condition="'$(TargetFramework)'=='net6.0-windows'">
    <PackageReference Include="Microsoft.XmlSerializer.Generator" Version="6.0.0-preview.3.21201.4" PrivateAssets="All" />
    <DotNetCliToolReference Include="Microsoft.XmlSerializer.Generator" Version="6.0.0-preview.3.21201.4" />
  </ItemGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='net6.0-windows'">
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
  </PropertyGroup>

Error: An attempt was made to load an assembly with an incorrect format: C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.0-preview.3.21201.4\ref\net6.0\Microsoft.CSharp.dll.


Remove the [GenerateSerializationAssemblies] or set to 'Auto' by default yields..... results below.


Compile
Run

var s = new XmlSerializer(objType);

System.IO.FileNotFoundException: 'Could not load file or assembly '~\bin\Debug\net6.0-windows\ [assemblyName].XmlSerializers.dll'. The system cannot find the file specified.'

@jeffreyrivor
Copy link
Author

  <ItemGroup Condition="'$(TargetFramework)'=='net6.0-windows'">
    <PackageReference Include="Microsoft.XmlSerializer.Generator" Version="6.0.0-preview.3.21201.4" PrivateAssets="All" />
    <DotNetCliToolReference Include="Microsoft.XmlSerializer.Generator" Version="6.0.0-preview.3.21201.4" />
  </ItemGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='net6.0-windows'">
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
  </PropertyGroup>

Error: An attempt was made to load an assembly with an incorrect format: C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.0-preview.3.21201.4\ref\net6.0\Microsoft.CSharp.dll.

Remove the [GenerateSerializationAssemblies] or set to 'Auto' by default yields..... results below.

Compile
Run

var s = new XmlSerializer(objType);

System.IO.FileNotFoundException: 'Could not load file or assembly '~\bin\Debug\net6.0-windows\ [assemblyName].XmlSerializers.dll'. The system cannot find the file specified.'

The SGen task that is invoked by setting GenerateSerializationAssemblies is only supported for .NET Framework (see dotnet/sdk#2456). The Microsoft.XmlSerializer.Generator dotnet tool runs without setting GenerateSerializationAssemblies. That said, I'm surprised that MSBuild didn't throw a more friendly error to indicate this (see dotnet/msbuild#3583).

@HongGit HongGit removed the untriaged New issue has not been triaged by the area owner label Jul 22, 2021
@StephenMolloy StephenMolloy added this to the 7.0.0 milestone Sep 30, 2021
@chm-tm
Copy link

chm-tm commented Apr 4, 2022

Work around:

  • Author a custom .targets file in your build where you copy the original GenerateSerializationAssembly to.
  • Add Inputs="@(ReferencePath);@(IntermediateAssembly)" and Outputs="$(_SerializerDllIntermediateFolder) to the GenerateSerializationAssembly target.
  • Import your custom .targets file in your project by using the CustomAfterMicrosoftCSharpTargets property. This way, our target can overwrite the original target.

@StephenMolloy
Copy link
Member

StephenMolloy commented Aug 13, 2022

Fixed in 7.0-rc1 by #73550

@ghost ghost locked as resolved and limited conversation to collaborators Sep 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants