dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.7k stars 1.06k forks source link

Is it possible to alter dotnet publish structure? #8888

Open JustArchi opened 6 years ago

JustArchi commented 6 years ago

I'm publishing self-contained netcoreapp2.0. The resulting structure is a huge mess, as it includes over 150 different dll libraries, and in addition to that over 70 folders for resx resources related to localization in my case. I'm wondering if it's possible through any current means to alter this structure, by moving all localization folders such as de-DE to resources folder or similar, and all dll libraries to lib folder or likewise. This would lead to a single Application.exe binary, resources folder and lib folder, making entire thing look much better.

If it's currently not possible, perhaps it'd be a worth addition to the SDK?

Thank you in advance for response.

nguerrera commented 6 years ago

I don't think this is possible without runtime support. cc @eerhardt @steveharter

eerhardt commented 6 years ago

Some of the dll libraries can be moved to different directories if you create a custom AssemblyLoadContext, but you won't be able to get rid of them all. You'll still need libcoreclr, dotnethostpolicy.dll, etc.

Yes, to implement this fully as asked, there would need to be runtime support.

Other ideas that help here are things like ILLinker: https://github.com/dotnet/core/issues/915

JustArchi commented 6 years ago

I'm already using ILLinker, great tool, managed to shrink size of my published app down to almost 50% of original size, but it's size itself and not necessarily app folder organization in this case.

The biggest issue is probably with localization files, since user is opening app's folder and he sees thing like that:

1

And this is not even a half of that, since we have another huge amount of things.

If we're able to move majority of .NET Core dlls such as System.Threading.dll or api-ms-win-crt-math-l1-1-0 with AssemblyLoadContext then I'd say this is good enough since it won't be a problem to keep only a few dlls around.

Another possibility would be the ability to create a single native binary when publishing, I mentioned it in issue dotnet/sdk#8443. In .NET Framework I used il-repack and Costura.Fody for this, but it's impossible to apply to .NET Core just like that.

Could it be a possibility for some future version of .NET Core to have a tool or build option that would produce a single binary that would contain all necessary parts inside, just as pointed out in dotnet/sdk#8443? Or maybe at least we could have some better-organized structure that would move at least non-critical dlls into some subdirectory, likewise with resources? It'd be already a huge relief compared to current situation - I have exactly 71 folders and 158 dll files in my app's directory, where generic build includes only 9 of them (still 71 folders for resources though that I want to move somewhere deeper).

I'd really appreciate if some solution could be considered regarding this, as even as simple step as telling user to launch the app could be problematic if he doesn't have a working shortcut and has to search for the exe across hundreds of different files.

dasMulli commented 6 years ago

Could it be a possibility for some future version of .NET Core to have a tool or build option that would produce a single binary that would contain all necessary parts inside, just as pointed out in dotnet/sdk#8443?

That's the goal of CoreRT.

A feature to filter satellites assemblies to a predefined set of languages would make sense though. Not just for self-contained apps, but also filtering satellites assemblies coming from NuGet / referenced libraries. Based on the ReferenceSatellitePaths items emitted by RAR maybe.

JustArchi commented 6 years ago

Thanks! I took a quick look at CoreRT and it's awesome that something like this is being created, sadly I didn't have luck using it just yet for my app, but it's obvious considering CoreRT is in heavy alpha state.

Even though I still believe that we should do something in .NET Core itself regarding this. ReferenceSatellitePaths idea by @dasMulli would probably be decent regarding resources folders, and if we can do something about libraries by moving then to lib folder and altering default AssemblyLoadContext proposed by @eerhardt then we should be able to get rid of hundreds of dlls as well, even if just some crucial low-level libraries are left, this is still better than hundreds of them.

I'm going to keep the issue open, thanks in advance for considering my idea or any other solution that would improve organization of self-contained app structure.

EatonZ commented 5 years ago

I would like to see this. I'm not sure I like the PublishSingleFile feature - I'd like to keep things in one folder instead of extracting everything to some temp folder. That's also slower - it's faster to have everything on the file system already, and having a feature to move the dlls into a subfolder would make it easier for users to find the main exe.

Also, @JustArchi, try adding this to your csproj file: <SatelliteResourceLanguages>en-US</SatelliteResourceLanguages> Put in whatever language you want and it won't include all the other dlls/folders. It worked great for me.

bugproof commented 4 years ago

FYI dnSpy does this by patching AppHost exe: image

All the .dll files are inside bin and main .exe to launch it is outside. It looks very clean IMO.

https://github.com/0xd4d/dnSpy/blob/5c810b6243f9aab34436f631f85dd362dc486998/build.ps1#L58

https://github.com/0xd4d/dnSpy/tree/master/Build/AppHostPatcher

obskyr commented 4 years ago

Chipping in with a use case for a lib/ directory: I'm building an app that has both a CLI and a GUI executable, with all the back-end code shared between them (just like dnSpy, it seems). Since they share almost all of the code, it'd be nice to have them both use the same DLLs – so the single-executable option is suboptimal – but distributing the two executables in a forest of DLLs would be a bit rough for the end user.

I hope something comes of this, and that we can eventually stuff the DLLs in a directory without having to jury rig AppHost.exe!

Vercidium commented 3 years ago

Bumping this issue, I'd love to be able to move the large list of DLLs to a folder called lib/ and specify in my deps.json to look in there when searching for DLLs.

NN--- commented 3 years ago

This might be not a serious problem on Windows/Linux, however for Mac the Application Bundle structure requires to separate executable from resources. Without making it right, the codesign tool refuses to sign.

MacOS/ exectuable Resources/ all other files including dll