Open sudoudaisuke opened 5 years ago
Sorry, move this issue to dotnet/core-setup#7746.
Please see dotnet/core-setup#7746 for more details:
The targets file this package includes adds the duplicate items to the ReferenceCopyLocalPaths
, and only does so if the Platform
property is defined. So simple publish from command line actually doesn't invoke those targets - which in itself is probably a bug.
Additionally the native assets (the facades in this case) will be added by NuGet runtime resolution anyway, so there should be no need to add a custom build task to copy them again.
The targets file also has a minor issue with the error message (it supports ARM64, but the error message states x86 and x64 only).
I spent some time looking at this and I agree that if we remove our custom ReferenceCopyLocalPaths, dotnet core does copy our specific nuget references during publishing. But, this seems to break the scenario where you just build and hit F5 as dotnet core seems to copy the entire runtimes folder from our nuget with binaries for each runtime rather than copying the one for the specific runtime being built for.
@vitek-karas Do you know of any reason why dotnet core does this when building and how we can get it to copy the specific references similar to what it does during publishing and basically what we were trying to achieve with our custom copy commands.
By default .NET Core builds (F5 runs build for example) a "portable app" - that is app which can be copied as is and runs on any platform. In order to do this, it needs the native (RID specific) assets for all supported platforms.
Note that these will be in RID specific subfolders. The .deps.json
file contains records for all these assets, specifying in which case to use which assets. So it contains something like "When running on linux-x64
, use the asset from linux-x64
folder" and "When running on win-x64
use the one from win-x64
". At runtime the host will pick the right ones for the platform it's running on.
When you publish for a specific platform (RID, typically done via dotnet publish -r linux-x64
), this asset resolution is done by NuGet and the output will only get assets for the specified RID. There are no subdirectories in this case - all the files are in the output directly. The .deps.json
file is still there, but it's basically just listing the files in the directory - no special magic.
So the systems assumes that the NuGet package has assets:
The resolution then uses all those which are not runtime specific and then for all other assets it picks the one copy which is the best match for the given platform.
What is so special about these native libraries, that they have to live in the main output folder and not in subfolders for "portable apps"?
@vitek-karas Thanks for that explanation. The difference between build and publish makes sense now.
The issue is that in the build / F5 scenario, I am not seeing our native nuget libraries get resolved from the runtimes folder when a DLL that depends on it is loaded by LoadLibrary
. Based on loader snaps, it seems the native dependency directories from .deps.json
are not on the search path for LoadLibrary
to find. I was able to confirm by setting COREHOST_TRACE
that the folder with the dependency is detected by the host and is part of NATIVE_DLL_SEARCH_DIRECTORIES
, but I guess those directories are not included as a search directory for LoadLibrary
.
Are the native dependency directories in .deps.json
for the current RID expected to be included as part of search path for LoadLibrary
by the host and if not, how are those dependencies expected to be resolved by LoadLibrary
?
@swaroop-sridhar can you please take a look at this one?
@manodasanW: Do I understand the following correctly:
If so, can you please share a repro/instructions for the second issue? Thanks.
@swaroop-sridhar Right, we are able to resolve the issue with PublishSingleFile
by removing ReferenceCopyLocalPaths
, but we had put that there due to this 2nd problem where in a portable app our native nuget libraries are not picked up from the runtimes folder by LoadLibrary
.
Attached is a sample which should let you observe the issue. You should set ConsoleApp to be the startup project and you should delete all the ReferenceCopyLocalPath
entires from our vcrt-forwarders
target file for .net core (.nuget\packages\microsoft.vcrtforwarders.140\1.0.2-rc\build\netcoreapp2.0\Microsoft.VCRTForwarders.140.targets
). Once you build it and run the console app you should observe a file not found error and this is due to our native nuget libraries under the runtimes folder are not getting picked up. With the ReferenceCopyLocalPath
we had previously, they would have been copied alongside the app and be picked up.
I also built the app and attached the binaries which you should also be able to run and observe the issue with.
Thanks for sharing the repro @manodasanW. I also talked to @vitek-karas and @AaronRobinsonMSFT about the issue.
The resolution of the native library loads from within the WinRT component is not handled by the .net core runtime. The libraries need to be in the same directory, or a directory understood by LoadLibrary() or have a custom mechanism built-in to locate the DLL.
In order for ReferenceCopyLocalPaths
route to work, we need to fix dotnet/sdk#3510.
CC: @nguerrera
Hi, i know this is an old issue, but I stumbled upon it and was desperate to find a solution. In the end, i tried deleting 1 by 1 the nuget packages in my .csproj, and I found out that these 2 were the culprits!
`
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
`
I don't know if it's a matter of compatibility, but having even just one of those packages (either one) resulted in this issue's error while publishing.
Here's the full list of packages of the project
`
<ItemGroup>
<PackageReference Include="App.Metrics.AspNetCore.Health.Endpoints" Version="3.2.0" />
<PackageReference Include="AWSSDK.Core" Version="3.3.107.40" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="FluentFTP" Version="33.0.3" />
<PackageReference Include="JWT" Version="7.3.1" />
<PackageReference Include="Marten" Version="4.0.0-alpha.9" />
<PackageReference Include="MassTransit" Version="7.1.3" />
<PackageReference Include="MassTransit.AmazonSQS" Version="7.1.3" />
<PackageReference Include="MassTransit.AspNetCore" Version="7.1.3" />
<PackageReference Include="MediatR" Version="9.0.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="Minio" Version="3.1.13" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
<PackageReference Include="Npgsql.Json.NET" Version="5.0.3" />
<PackageReference Include="PuppeteerSharp" Version="2.0.4" />
<PackageReference Include="Quartz" Version="3.2.4" />
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.2.4" />
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.2.4" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0-dev-00909" />
<PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.1.0" />
<PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
<PackageReference Include="System.Threading.AccessControl" Version="5.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>
`
I tried removing all the source code (leaving only Program.cs and Startup.cs) along with all these packages (leaving only either "Microsoft.NET.Test.Sdk" or "BenchmarkDotNet") and it still gives the same error when publishing as a single file.
Here's some info on my system
I hope this helps somebody!
This should be improved or maybe even fixed in .NET 6. https://github.com/dotnet/runtime/pull/48336 adds a better error message exactly specifying which two file paths caused the problem (should help figuring out where it came from) https://github.com/dotnet/runtime/pull/50476 avoids the error if the input contains exact duplicates (which is by far the most common case for this error as far as we know).
Note that these fixes are all in the SDK (not in the runtime, ignore the repo). So you can try to build your app with .NET 6 Preview 3 SDK and it should fix it.
Hello. I got error dotnet publish with vcrt-forwarders. Is this dotnet/core-setup bug?
[environment] .NET Core 3.0 Preview 8 Microsoft.VCRTForwarders.140 Version=1.0.1-rc csproj has "PublishSingleFile" element Console app
[command] dotnet publish ConsoleApp1.csproj /p:PublishProfile=\PublishProfiles\FolderProfile.pubxml
[error message]
[Sample csproj] ConsoleApp1.zip