Description
The Publish logic that computes the assemblies to postprocess misses assemblies which were picked by conflict resolution during publish. This results for example in illink not getting a chance to process such assemblies.
To Reproduce
Add a reference to Microsoft.Diagnostics.Tracing.TraceEvent
version 3.0.2
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<SelfContained>true</SelfContained>
<!-- <PublishTrimmed>true</PublishTrimmed> -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.0.2" />
</ItemGroup>
</Project>
dotnet publish -v:d
. Note that the output has:
Encountered conflict between 'CopyLocal:/home/svbomer/.nuget/packages/microsoft.diagnostics.tracing.traceevent/3.0.2/lib/netstandard2.0/Dia2Lib.dll' and 'CopyLocal:/home/svbomer/.nuget/packages/microsoft.diagnostics.tracing.traceevent/3.0.2/lib/netstandard1.6/Dia2Lib.dll'. Choosing 'CopyLocal:/home/svbomer/.nuget/packages/microsoft.diagnostics.tracing.traceevent/3.0.2/lib/netstandard1.6/Dia2Lib.dll' arbitrarily as both items are copy-local and have equal file and assembly versions.
There is a conflict between the netstandard1.6 and netstandard2.0 versions of Dia2Lib.dll
, and the conflict resolution picks one and continues.
Now uncomment the <PublishTrimmed>
setting in the project file and publish again. Notice that the illink.dll
invocation in the log does not pass Dia2Lib.dll
.
Further technical details
I see that RuntimeCopyLocalItems
has a netstandard2.0 version of Dia2Lib, but ResolvedFileToPublish
has a netstandard1.6 version, so the two don't unify in the logic which computes the set of assemblies to postprocess:
sdk/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets
Lines 952 to 954 in be20b69
_AssemblyToPostprocessOnPublish
doesn't contain Dia2Lib.
Compare this to the Publish conflict resolution logic:
sdk/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets
Lines 544 to 549 in 3786af2
This compares ResolvedFileToPublish
with _ResolvedCopyLocalPublishAssets
(which is populated earlier from RuntimeCopyLocalItems
), and chooses one to include in the output.
I think the root cause is this discrepancy between the filtering in these two places. Seems like the logic that computes assemblies to postprocess should operate on the previously filtered set, without doing its own different filtering.