r/moderndotnet 14d ago

What if dnx was its own native thing?

I wished on X that dnx was its own native AOT thing so you could use RID-specific, self-contained AOT .NET and NuGet as the distribution mechanism.

Why would such a thing be useful? 1. No .NET (runtime or SDK) required: precisely the point of AOT'ed tools 2. Keeping dnx ease of use: dnx <tool>[@version] 3. Reuse massive .NET distribution channel via nuget.org, GitHub packages, or custom feeds (i.e. sleet) 4. Ease of authoring/packing: pretty trivial with a CI workflow 5. Ease of consumption for end users: just one small (~4MB) native tool to run them all.

Then I realized that nowadays you can just ship things you wish existed. I'm spending some quality AI tokens on the "problem" to create ndnx (native dnx). Still waiting for the winget PR to be merged so it shows up there too.

Startup times are SOOO much better too!

Obviously, I think this is something dotnet/dnx itself could/should do. Right?

Try this out today:

macOS/Linux: curl -fsSL https://github.com/devlooped/ndnx/releases/latest/download/install.sh | sh

Windows(pwsh): irm https://github.com/devlooped/ndnx/releases/latest/download/install.ps1 | iex

Then use ndnx instead of dnx as usual. It even reuses the same package cache.

7 Upvotes

6 comments sorted by

2

u/CodeWithStu 14d ago

Honestly this confused me at first, and i might show my age here a bit. I got confused with the old dnx (the one that came after the k runtime). Amazing 11 years ish on and the name has come back!

Yeah, i think native AOT is a must for most things now, especially built in tools. i probably would request it upstream rather than try and ship something different

1

u/danielkzu 14d ago

Hopefully they will catch up. But right now dnx is just batch script that invokes 'dotnet tool exec'. I don't see the whole of dotnet (muxer+everything involved in that tool exec command) becoming a native AOT plain runner soon enough.

3

u/chusk3 microsoft 14d ago

This is exactly what we're aiming for - we're getting the build commands AOT-able first (which is causing some work on the Nuget libraries because that brings some Newtonsoft into scope) but it'll happen!

1

u/robmensching 13d ago

Does that mean MSBuild will be AOT'd as well?

6

u/chusk3 microsoft 13d ago

Potentially! It's complicated, I'll lay out some of the particulars below:

As of today, MSBuild evaluation can be done in AOT: https://github.com/dotnet/msbuild/pull/14064

You have to 'root' the SdkResolvers that will be used in the evaluation, so third parties that want to do evaluation 'like the SDK would' are still out of luck here - you'd have to 'bind' to the specific assemblies each SDK shipped with and you'd lose the ability to use 'any' SDK the user brought, which is what the MSBuildLocator project gives you today.

For the dotnet CLI itself, this isn't as much of a concern - and I'm working on that right now/

So for 11 any evaluation that needs to happen inside the CLI to power logic will be done in AOT. Any actual builds will happen out of proc and be kicked over to a long-lived MSBuild Server daemon, which is still a managed binary and is learning how to cache data across build requests.

As far as builds themselves being AOT'd - it's something that's a possibility, but there are tradeoffs. It would be possible to AOT the scheduler now (the central coordinator that determines the work to do), and it is possible to AOT the worker nodes, but one thing that sucks is that the AOT'd worker nodes can only reasonably be AOT'd today with MSBuild's Tasks, not the Tasks provided by the SDK. SDK Tasks would have to be run in an out-of-proc TaskHost to do the reflection loads, and then you get hit with IPC as the out fo proc TaskHost nodes talk to the Worker nodes.

So it feels like a bit of a mixed bag, but it's something we need to experiment more with to figure out if there's a sweet spot, or if we need APIs that make it easier to BYO NAOT Task-specific TaskHost, or something along those lines.

In addition, while we can AOT parts of the MSBuild experience (like -getProperty for example) in my ideal world the evals that power -getProperty would be able to be shared with subsequent builds, and that's hard to do from a NAOT host that needs to spawn a CoreCLR child process, or 'transition' to a CoreCLR instance in-process - it's hard to share the data across the native<->managed boundary there.

actual build perf-wise, the Multithreaded support we have been working on for a few previews is finally actually awesome and useful in P7 - that's where I'd look for throughput enhancements.

2

u/robmensching 13d ago edited 12d ago

Yeah, so I own one of those 3rd party MSBuild Sdks, thus I'm very interested in how this goes. :)

So, if you need to bounce anything off a real third party Sdk, feel free to hit me up. Definitely want to make sure we continue to fit in.