Search code examples
c#visual-studio.net-corenuget.net-core-2.1

How can I find where a specific SDK dependency is coming from in a dotnet core solution that fails to build because of it?


I'm working on a .Net Core 2.1 codebase (it needs upgrading but time constraints have prevented that so far).

I added a Nuget package, FFMpegCore, which had a dependency on System.Text.Json 7.0.1. The solution built locally in VS2017, but when using dotnet build on the build server it failed with errors about System.Runtime.CompilerServices.Unsafe not being compatible with netcore2.1.

This all ok, I first downgraded the package to a version using System.Text.Json 6.0.1 (to find that that's also not supported by 2.1), but then to one using 5.0.1, which itself has a dependency on System.Runtime.CompilerServices.Unsafe 5.0.0, which looks compatible.

I'm now seeing this error on the build server:

/home/build/.nuget/packages/system.runtime.compilerservices.unsafe/6.0.0/buildTransitive/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.targets(4,5): error : System.Runtime.CompilerServices.Unsafe doesn't support netcoreapp2.1. Consider updating your TargetFramework to netcoreapp3.1 or later. [/opt/build/develop/site/site.csproj]

Visual Studio now shows FFMpegCore as only having the 5.0.0 dependency for unsafe via System.Text.Json, but it looks as though there's still something left over from the incompatible versions. Is there a way to find out what or where it is? Or could it be some kind of caching problem?

Update

I read this article and it seemed related, so tried going back to a much earlier version of FFMpegCore which didn't use System.Text.Json (Newtonsoft instead, which is used everywhere else in the same solution) - but same build errors.

Then tried switching branch to the version of the code without any FFMpegCore at all, which was built ok a few weeks ago and is running on the server, and .. same build errors.

Seemed to be something persisting in the build environment, so tried:

dotnet nuget locals all --clear

..and the build is working again, both for the previous code and for that using the Newtonsoft-dependent version of FFMPegCore, so the fix was not to use System.Runtime.CompilerServices.Unsafe at all with 2.1.


Solution

  • I can reproduce your situation:

    enter image description here

    This situation is expected.

    The issue you encountered comes from the targets file under 'buildTransitive\netcoreapp2.0' folder of the package:

    <Project InitialTargets="NETStandardCompatError_System_Runtime_CompilerServices_Unsafe_netcoreapp3_1">
      <Target Name="NETStandardCompatError_System_Runtime_CompilerServices_Unsafe_netcoreapp3_1"
              Condition="'$(SuppressTfmSupportBuildWarnings)' == ''">
        <Error Text="System.Runtime.CompilerServices.Unsafe doesn't support $(TargetFramework). Consider updating your TargetFramework to netcoreapp3.1 or later." />
      </Target>
    </Project>
    

    Normally(I mean if it is not in this folder), This error is emitted unconditionally for all target frameworks, unless the $(SuppressTfmSupportBuildWarnings) property is set. It means that this error will be emitted for all projects that reference this package, regardless of their target framework.

    But since it is in the netcoreapp2.0 folder, it will only affect netcoreapp2.0 projects/packages.

    This is no matter with the net standard compatible mechanism. The package configure a limitation in it, and if you match the limitation, it pop out the configured error, this is just what it is.

    You just need to set your csproj file like this:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFramework>netcoreapp2.1</TargetFramework>
        <SuppressTfmSupportBuildWarnings>xxx</SuppressTfmSupportBuildWarnings>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="FFMpegCore" Version="5.0.1" />
      </ItemGroup>
    
    </Project>
    

    And it works:

    enter image description here

    Your situation comes from dependency package configuration. Package compatible is not a mystery thing, and the checking steps is just based on the structure of the package content, nothing else.

    Take a look of this answer:

    https://stackoverflow.com/a/76926018/6261890

    I can even make a package compatible with any framework of .net, I even don't need any code, I just need to match the structure it needs. So net standard just give you a framework, whether it suitable for you is another things. It just like a convention/constraint for people, and people follow this regulation.

    Generally, net standard 2.0 package should suitable and compatible for your net core 2.1 app.

    Reason:

    Net standard 2.0 supported frameworks

    enter image description here

    The situation you encountered comes from the limition of the root package configuration.