shimat / opencvsharp

OpenCV wrapper for .NET
Apache License 2.0
5.39k stars 1.15k forks source link

NuGet packages are copying native dlls incorrectly with .net 6 #1349

Closed awardle closed 2 years ago

awardle commented 2 years ago

Summary of your issue

If you target a project to .net 6 and include the windows runtime package (OpenCvSharp4.runtime.win), extra native dlls are copied to the build directory. This does not happen in .net 5

The build copies the dll folder as well as the runtimes folder. It should only copy the runtimes folder

Environment

Windows 10 with .net 6 SDK

Example

Project targeting .net 5

image

Project targeting .net 6

image

Possible issue

opencvsharp/nuget/OpenCvSharp4.runtime.win.props includes the following checks

<ItemGroup Condition="!$(TargetFramework.Contains('netstandard')) And !$(TargetFramework.Contains('netcoreapp')) And !$(TargetFramework.Contains('net5'))">
        <Content Include="$(NativeDlls)\win-x86\native\OpenCvSharpExtern.dll">
            <Link>dll\x86\OpenCvSharpExtern.dll</Link>
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
        <Content Include="$(NativeDlls)\win-x86\native\opencv_videoio_ffmpeg453.dll">
            <Link>dll\x86\opencv_videoio_ffmpeg453.dll</Link>
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
</ItemGroup>

This does not check if the target framework contains net6 so copies the dll folder.

shimat commented 2 years ago

Thank you. I'm not sure how to write the conditionšŸ¤”

<ItemGroup Condition="$(TargetFramework.Contains('net2')) Or $(TargetFramework.Contains('net3')) Or $(TargetFramework.Contains('net4'))">
awardle commented 2 years ago

I think the condition may not be needed if you only copy the prop file into the build/net folder, but you will still need to create empty folders like build/netcoreapp and build/netstandard so nuget knows not to include the prop file if the project doesn't target netFramework.

It looks like nuget supports copying a whole empty folder using nuspec, so maybe if the files section in https://github.com/shimat/opencvsharp/blob/master/nuget/OpenCvSharp4.runtime.win.nuspec was change to

 <files>
        <file src="..\src\Release\x64\OpenCvSharpExtern.dll"   target="runtimes\win-x64\native" />
        <file src="..\src\Release\Win32\OpenCvSharpExtern.dll" target="runtimes\win-x86\native" />
        <file src="..\opencv_files\opencv453_win_x64\x64\vc16\bin\opencv_videoio_ffmpeg453_64.dll" target="runtimes\win-x64\native" />
        <file src="..\opencv_files\opencv453_win_x86\x86\vc16\bin\opencv_videoio_ffmpeg453.dll"    target="runtimes\win-x86\native" />
        <file src="OpenCvSharp4.runtime.win.props" target="build\net\OpenCvSharp4.runtime.win.props" />
        <file src="empty\" target="build\netstandard\" />
        <file src="empty\" target="build\netcoreapp\" />
    </files>

And an empty folder called empty is created in the same folder as the nuspec file.

shimat commented 2 years ago

With your suggested code, I get warning NU1701 when TargetFramework=net5.0 or netcoreapp. The nupkg always seems to be installed as not net5.0 but net461. I don't know what the solution is.