Closed pauldotknopf closed 4 years ago
This has always been done like that. One of the reasons being that full frameworkdoes not know how to handle the runtimes
folder and only load the native assemblies directly in your bin
folder.
Also - since you are publishing for a specific runtime, there is no reason to put things in the runtimes
folder. The runtimes
folder exists so assets for different platforms can sit side-by-side.
Have you considered using contentFiles instead, of you want a specific layout in your output folder?
Thanks @eerhardt, this is straight up a copy of his wisdom.
I fail to see how dotnet publish -r osx-x64
would have anything to do with full framework, but hey, idk. IMO, a NuGet package shouldn't work in some ways, but fail in others. If it isn't all or nothing, I'd say it is a bug.
I will take a look at contentFiles
and see if it gives me what I'm looking for.
Thanks.
I'm looking into contentFiles
now, and there doesn't seem to be a way to add files that are os specific, like runtimes/linux-x64/libs/file.so
.
So, I'm not seeing a proper work around for this issue.
A workaround could be to split packages for the different runtimes. So the native assets would be contentFiles
in a runtime.osx-x64.my.pkg
nuget package and the my.pkg
package would have a runtime.json
that declares this RID-specific dependency. I don't know if that's even documented though.
Microsoft.NETCore.App
uses this RID-specific package splitting to pull in packages for self-contained deployment.
@pauldotknopf Like stated above, this is currently by design and we don't have plans to change it. It would be very significant and would lead to other scenarios being broken. Please try @dasMulli's suggestion above.
Quoting my reply from NuGet dotnet/sdk#8748 here:
I just wanted to point out that the suggested solution with contentFiles has it's drawbacks:
dotnet run
(not dotnet publish
) contentFiles
can be made to copy the files next to the native files in the .nuget/packages
folder. I think copyToOuput="true"
makes them to be copied to the project output folder (like bin/debug
) only. This will be a problem in cases when existing native libraries require subfolders next to them (in a .nuget/packages<package_name>/native/..
folder).contentFiles
can be published depending on target runtime. I.e. when we need to have one set of files for Windows and another for MacOS.@livarcocc To me it reads like the quoted text is a response as to why runtimes/x/native got flattened. The issue is not that the runtimes/x/native
part was flattened, but that what's after that got flattened.
E.g. a file in runtimes/win-x64/mydir/lib.dll
will be published to publish/lib.dll
instead of the expected publish/mydir/lib.dll
. That seems like a bug to me. I don't see any reason for why this would be by design.
cc @eerhardt (because he wrote the quoted text)
Filed a doc issue at https://github.com/NuGet/docs.microsoft.com-nuget/issues/2322. Hopefully someone from the .NET Core or NuGet team can help answer whether this behavior (as @Jjagg says, the flattening of files within native
, not
of runtimes/{platform}
) is by design, and document it as such and/or reopen this issue.
This popped up in https://github.com/microsoft/playwright-sharp/issues/1145 where it broke the ability to publish platform-specific / self-contained projects.
/cc @eerhardt
@eerhardt Any update on this issue?
Also - since you are publishing for a specific runtime, there is no reason to put things in the
runtimes
folder. Theruntimes
folder exists so assets for different platforms can sit side-by-side.
While I appreciate the logic here, the ramifications are that assembly detection and loading must use different logic depending on the settings used with the command dotnet publish
. Ideally, the publish command should not alter the output directory, or at least should provide an option to opt out of this behavior. As it is currently implemented, selecting any option other than "Portable" breaks interoperability between managed and native code if you have native code that has fragile relative pathing (CEF comes to mind).
Also, flattening directory structure breaks when you have multiple files with the same name in different sub-directories.
Bump @eerhardt, is any progress being made on this?
Steps to reproduce
Expected behavior
I expect both methods of publishing to preserve the NuGet package's file structure, like this.
Original NuGet package directory structure.
Actual behavior
dotnet publish
produces a proper folder structure, mimicking the original NuGet package.dotnet publish -r osx-x64
produces an invalid folder structure. It flattens everything into the root. My libraries have specific rpath's that require them to be in certain directories to work properly."dotnet publish -r osx-x64" directory structure
Take note that the
/lib
,/plugins
and/qml
directories were flattened.Environment data