-
Notifications
You must be signed in to change notification settings - Fork 224
Support consuming and producing nuget packages with native binaries #402
Comments
Finally someone echoes my 3-years old issue: see Rafael Teixeira On Tue, Jul 1, 2014 at 1:32 AM, David Fowler [email protected]
|
Data points: Here are some existing projects using native dependencies:
Kestrel has binaries committed to source control in this format:
It also keeps the same structure in the nupkg itself: https://github.com/aspnet/KestrelHttpServer/blob/dev/build/_custom-goals.shade#L12 The build script above puts the native binaries at the root of the nuget package with the same layout. At runtime, it loads the native library using the following method: Ideally, with the KRuntime, we should have conventions around what directories we automatically add for loading native binaries (we the option of specifying this in the project.json). Of course the library author can always manually load library, but that only really works if you can package all native dependencies in the nuget package. This doesn't work well on *nix, see aspnet/KestrelHttpServer#10 for more details. SqlLite is a bit more interesting: The build process downloads sqlite dynamically and for packaging, it uses an msbuild script on net451 so that nuget will automagically copy the binaries into the bin folder of the project. https://github.com/aspnet/DataCommon.SQLite/blob/dev/makefile.shade#L46 At runtime it uses load library (similar to kestrel): |
@lodejard and @GrabYourPitchforks Need your POV on this. Assuming we invent a convention for determining where native assets get loaded from within a package based on OS and Bitness, we'll either modify |
Thou shalt not modify the environment block (including environment variables) while the application is running. It's not yours to mess with. |
Another option might be to call LoadLibrary (and dlopen on *nix) on the appropriate binary. The only downside to this might be that we would load the library eagerly instead of lazily. |
Another project that uses native dependencies is Microsoft.SqlServer.Compact, which @davideboo says works pretty well. The scripting in that package is a bit hairy. Moving that responsibility off of package developers and onto tooling would be great - as it's all tooling specific, and if an interface changes, old packages will become unusable. I've been collecting thoughts on github here; hopefully I'll be able to reorganize them as a set of best practices after some more thorough testing of the various assumptions and hypothesis. |
We're moving to a model where packages are declarative and client can do the right thing for the platform. |
Is there any documentation of this model? If I submit a PR to paket that enables this workflow, I'd like to keep the nuget syntax compatible or consistent with what you guys are doing. |
Is there any more information on this? Seems like there are a few issues out there about this but no resolution. An update would be much appreciated. |
pinging @davidfowl and @yishaigalatzer Would love to get a quick status report on this topic. My use case is for a c++/cli project i maintain: https://github.com/jbrwn/NET-Mapnik. My current nuget strategy is to copy all dependant native dlls to the output dir using a .props file in the build directory of my nuget package. This model falls apart with dnx and would love to find an alternative solution. |
We should have something out within a week or so. Still working on documenting the details |
I will try to post a sample today or tomorrow |
@yishaigalatzer - thanks for the response and posting the sample package. I'll be keeping my eye out for documentation. In the mean time, is it possible for you to elaborate a little on how this all works? I see an "any" TFM directory and a runtime.json file in the root of the package. It would be great to hear about how this all comes together so i can start experimenting with it even if complete documentation is not ready. |
The any folder is going to probably be renamed before we are done. The runtimes is about bringing implementation that are runtime target appropriate. We can probably post more preliminary info here to get you going, let me see if we have something useful |
We are talking about a package that has a managed assembly that needs to invoke stuff from a native assembly that it carries, right? If that's the case then the current plan, as far as I understand it, is to be able to create a package like the following:
The build system responsible for consuming this package would need to know to copy the native assembly to your build output when building for the given runtime. You could put @davidfowl or @anurse might have more detailed comments. There should be more docs on how it all fits together coming at some point soon. |
@glennc Any news on which build systems will be supporting this? Will native package support be exclusive to VS2015 and dnx-based systems? Also, have there been corresponding changes in the .NET full framework to allow native libraries to be located even when the managed libraries are loaded with shadow-copying? |
@glennc Thanks for your input.
That's right.
I think this is the primary question for me and others - how will dnx/dnu/visual studio handle native assemblies in a nuget package? In the past we could always just make up our own convention for including native dlls in a nuget package and then copy them wherever we want using a Install.ps1/init.ps1 script or a .props file. However, the game is changing because, as far as i know, there is no "output directory" in dnx - everything is loaded into memory from the dependent nuget packages. |
@moozzyk are their issues/PRs on the dotnet repos we can follow to track this? |
@natemcmaster - I think the change on the CoreClr side went in last week so is no longer blocking. |
@moozzyk awesome. |
Can someone writeup the status of native binary packages across all 2015 platforms (full .NET framework, VS 2105, VS code, DNX, etc)? |
@nathanaeljones - the support in DNX is scheduled for RC. Can you elaborate more on what your expectations are with regards to "VS 2015 and VS Code" ? |
|
@nathanaeljones - I see. No. This bug is only about being able to consume packages containing native dlls in Side note - it is possible to create nuget packages containing native binaries even today (examples:cpprestsdk, SignalR C++ client, some documentation). I have not tried creating a NuGet package containing both native and managed dlls nor have I tried creating a package that contains a native dll that is being consumed by managed code but I think you can make it work just by adding a build step that copies the native dll to the same folder where the managed dll is copied. I believe CLR ( |
@moozzyk Any updates on this? |
Build steps do not work for classic ASP.NET or projects with unit tests (which should be all of them!), as those assemblies get left behind by the shadow copier. |
Finally, I didn't understand what should I do to make it works? For example I reference Gtk# package (https://www.nuget.org/packages/GtkSharp.Win32) and target dnx46. When I run project Gtk.Application.Init complains that native library wasn't loaded. May be this package hasn't upgraded to the some new conventions for DNX (as I see it has only old plain MSBuild steps to copy native dll-s). I can update it myself but I need to understand how it can be done? |
That will still work in RC2. |
@davidfowl Does this still work? I'm trying to create a wrapper library (netstandard1.6) for a C++ dll from another company. I've put the dll files in the appropriate folders ( |
No this doesn't work. You need to put it in a package. Or copy it to the output folder on build |
Oh, that's a shame, but at least it explains why I couldn't get it to work. Forgive my ignorance, but is there an optimal way to make a post-publish copy script that will have access to the publish architecture (x86/x64) and platform (windows/linux/etc.)? |
@davidfowl , can you explain how ?! Thanks |
@paolo8417 - take a look at the post I wrote some time ago. This was written before RC1 shipped and some things no longer work the same way but it should give you the general idea. Then look at how we build the libuv package: https://github.com/aspnet/libuv-package |
We need a convention for both consuming and adding native binaries to nuget packages.
When you're developing a project and need to take a dependency on a native binary, you need to put it in a path that is loadable. This scenario needs to take bitness and OS into account.
You also need to be able to produce a package that has these native binaries inside of it.
The text was updated successfully, but these errors were encountered: