Skip to content

PublishAot doesn't do conflict resolution between references #116595

Closed as duplicate of#108909
@eerhardt

Description

@eerhardt

Description

A technique that is commonly used to test local changes to a PackageReference is to reference the nuget package and also add a <Reference to the local assembly that you built on disk. This is an easy way to prototype changes in a referenced package without rebuilding the NuGet package and messing with the nuget cache.

However, when you use this approach with PublishAot, the conflicting assemblies aren't filtered out. And instead both assemblies are passed to ILC, causing problems.

To fix this, we should ensure the references passed to ILC take the conflict resolution into account.

Reproduction Steps

dotnet publish the following project (change the path to a locally built clone of https://github.com/microsoft/vs-streamjsonrpc

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAot>true</PublishAot>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="StreamJsonRpc" Version="2.22.11" />
    <Reference Include="D:\git\vs-streamjsonrpc\bin\StreamJsonRpc\Release\net8.0\StreamJsonRpc.dll" />
  </ItemGroup>
  
</Project>

Inspect the obj\Release\net9.0\win-x64\native\app.ilc.rsp file

Expected behavior

There should only be 1 StreamJsonRpc.dll passed to ilc - specifically the local built one from D:\git\vs-streamjsonrpc\bin\StreamJsonRpc\Release\net8.0\StreamJsonRpc.dll.

Actual behavior

Both are passed:

-r:D:\packages\NuGet\cache\streamjsonrpc\2.22.11\lib\net8.0\StreamJsonRpc.dll
-r:D:\git\vs-streamjsonrpc\bin\StreamJsonRpc\Release\net8.0\StreamJsonRpc.dll

Regression?

N/A

Known Workarounds

To workaround, you can add a target like the following:

  <Target Name="HackIt" BeforeTargets="PrepareForILLink">
    <ItemGroup>
      <IlcReference Remove="D:\packages\NuGet\cache\streamjsonrpc\2.22.11\lib\net8.0\StreamJsonRpc.dll" />
    </ItemGroup>
  </Target>

Configuration

No response

Other information

In "normal publish" without AOT'ing, these conflicts are removed here:

https://github.com/dotnet/sdk/blob/59c8a03f55dec858536c832299af32665c3fef34/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets#L558-L565

But this target runs too late in PublishAot, so the conflict resolution doesn't take place. Notice it runs after IlcCompile.

Image

cc @agocke @MichalStrehovsky @sbomer

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions