-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use runtime packs for NativeAOT on .NET 10 or higher #37872
base: main
Are you sure you want to change the base?
Conversation
I am not confident on how to validate this end-to-end aside from modifying my local SDK and hoping for the best. Any other ideas? /cc @akoeplinger |
One easy way is to use this script: https://gist.github.com/am11/afc2787bdecb9592663f4eae405d9116 (download at |
@am11 That's essentially what I do. :-) |
I think this testing is enough and we can move this forward if local testing passed. After @jtschuster's dotnet/runtime#96858 goes in, source build will be able to validate more interesting runtimepack scenarios (for linux and freebsd etc.) |
I'm hesitant to call it "ready" unless someone else confirms that it actually works on their machine (tm). It requires a .NET 9 SDK setup like instrumented above, and then running |
Just tested on osx-arm64 (host), linux-musl-arm64 (container) and win-x64 (host); seems to work. 👍 |
@filipnavara, a separate / existing but related issue: I just noticed that from runtime pack, we expect it to be present in the installation directory, such as |
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props
Outdated
Show resolved
Hide resolved
Wasn't it always working this way? I assumed it did for NativeAOT cross-compilation on .NET 8, and for macOS platform. Similarly for other platforms the ILCompiler package was not part of the bundle and that's where the "runtime pack" files were located. |
Pretty sure it was. What I understand from known packs is that it'd be available as a preloaded packages in the binary bundle (installer, zip, tar, whatever installer produces); otherwise the first time it will download the workload, it will store those packs to the same location where apphost packs are. But it does not seem to be the case for crossgen2 (for a longer time) and ilc (relatively recently). I checked with e.g. if we clear the nuget caches |
Known packs do not need to ship with the SDK, e.g. the normal desktop runtime packs aren't there either and will be fetched from nuget the first time they're used. If you install workloads it'll download packages into the packs folder, but that is not a requirement, just an optimization (e.g. we needed to be able to use workloads offline). |
That's exactly what I was hoping to achieve from crossgen2/ilc known packs. Otherwise downloading these nugets separately in CI container builds is same pain as before, so I'll continue to mount ~/.nuget directory there.. :) |
@MichalStrehovsky any concerns from your side? |
I don't think this will work in a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this will work in a
.props
file. This is so early that we don't know the project hasPublishAot
in it. It is so early that we probably don't even have_TargetFrameworkVersionWithoutV
yet.
Tried this locally and it only does something if I do dotnet publish -bl -p:PublishAot=true -p:_TargetFrameworkVersionWithoutV=9.0
. And the thing it does is not good:
D:\test\test.csproj : error NU1101: Unable to find package Microsoft.NETCore.App.Runtime.NativeAOT.win-x64. No packages exist with this id in source(s): dotnet9, Microsoft Visual Studio Offline Packages, NET8, nuget.org [D:\test\test.csproj]
We don't seem to have the Windows packages published yet: https://dnceng.visualstudio.com/public/_artifacts/feed/dotnet9
Bummer. I agree about |
I would be surprised if they work. When I tried this locally, it didn't try to use the runtime pack unless I also specified a value for |
Fix in dotnet/runtime#97023 |
All the existing usages of _TargetFrameworkVersionWithoutV are in Conditions on Item/ItemGroup so maybe the msbuild evaluation order is different for those. You can try moving the checks into the condition on the FrameworkReference. |
I'm sorry I didn't get back to this. I may find some free cycles to try again once .NET 9 Preview 1 ships with the necessary packages. |
Nevermind, that's actually fine. |
I'm playing with alternatives here. Below is an alternative approach. We'd delete all the One significant issue with this general approach is that diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props
index 038026fdf5..05f0b41f13 100644
--- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props
+++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props
@@ -83,10 +83,14 @@ Copyright (c) .NET Foundation. All rights reserved.
RuntimePackLabels="Mono"
Condition="'$(UseMonoRuntime)' == 'true' And ('$(_TargetFrameworkVersionWithoutV)' != '') And ('$(_TargetFrameworkVersionWithoutV)' >= '6.0')" />
- <!-- Allow opt-in to NativeAOT runtime pack for .NET 8.0 or higher -->
+ <!-- Allow opt-in to NativeAOT runtime pack for .NET 8.0 or higher and default to it for .NET 9.0 or higher -->
<FrameworkReference Update="Microsoft.NETCore.App"
RuntimePackLabels="NativeAOT"
- Condition="'$(_IsPublishing)' == 'true' and '$(PublishAotUsingRuntimePack)' == 'true' And ('$(_TargetFrameworkVersionWithoutV)' != '') And ('$(_TargetFrameworkVersionWithoutV)' >= '8.0')" />
+ Condition="'$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true' And '$(_TargetFrameworkVersionWithoutV)' != ''
+ And (
+ ('$(PublishAotUsingRuntimePack)' == 'true' And '$(_TargetFrameworkVersionWithoutV)' >= '8.0')
+ Or
+ ('$(_TargetFrameworkVersionWithoutV)' >= '9.0'))" />
</ItemGroup>
diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets
index 63be500baa..e0fd0be66d 100644
--- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets
+++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets
@@ -77,6 +77,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<PropertyGroup>
<EnableTargetingPackDownload Condition="'$(EnableTargetingPackDownload)' == ''">true</EnableTargetingPackDownload>
<EnableRuntimePackDownload Condition="'$(EnableRuntimePackDownload)' == ''">true</EnableRuntimePackDownload>
+ <_UsingNativeAotRuntimePack Condition="'%(FrameworkReference.Identity)' == 'Microsoft.NETCore.App' And '%(FrameworkReference.RuntimePackLabels)' == 'NativeAOT'">true</_UsingNativeAotRuntimePack>
</PropertyGroup>
<PropertyGroup>
@@ -116,7 +117,7 @@ Copyright (c) .NET Foundation. All rights reserved.
FirstTargetFrameworkVersionToSupportSingleFileAnalyzer="$(_FirstTargetFrameworkVersionToSupportSingleFileAnalyzer)"
SilenceEnableSingleFileAnalyzerUnsupportedWarning="$(_SilenceEnableSingleFileAnalyzerUnsupportedWarning)"
MinNonEolTargetFrameworkForSingleFile="$(_MinNonEolTargetFrameworkForSingleFile)"
- AotUseKnownRuntimePackForTarget="$(PublishAotUsingRuntimePack)"
+ AotUseKnownRuntimePackForTarget="$(_UsingNativeAotRuntimePack)"
RuntimeIdentifier="$(RuntimeIdentifier)"
RuntimeIdentifiers="$(RuntimeIdentifiers)"
RuntimeFrameworkVersion="$(RuntimeFrameworkVersion)" |
Rather than adding yet another path through this code, I'd like to focus on making I suggest we default |
As #46070 got merged in and as far as this PR is concerned we should bump the condition: Apart from that minor change, what are the follow-up actions to move this PR forward? |
Cc @Sergio0694 on WinAppSDK experiences around this. I think this is going to put us into a situation where we need to "support" people setting underscored properties. Granted, the underscored property is already semi-supported (Github is full of hits of people setting this, like https://github.com/baronfel/sdk-container-demo/blob/530356ee6891b317b316d1c98199e6fcc50341ef/src/solution-level-example/Directory.Solution.targets#L17-L25), but this would be a first time when we'd need to direct people to set the underscored property in an error message to make the breaking change self-serviceable. The project I'm linking to is one of the examples where people just want to invoke the Publish target and running |
The way out I've been thinking about for a while would be to:
This would address all of the subtle weird issues like " |
For the |
I definitely wouldn't mention the underscored property in the message. Until it's made public the error message will be suboptimal (not self-service for cases like the one you linked), but it seems better than hitting some downstream ILC error. I think it accurately reflects the current SDK position that 'dotnet msbuild /t:Publish' is not supported. I agree with your plan #37872 (comment). I am hoping that putting in errors in the right spots will help get traction on making this public, and I don't think we should block switching to runtime packs on it.
If I understand correctly, the fix for UWP and WinUI 3 will be to require users to invoke |
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props
Outdated
Show resolved
Hide resolved
…DefaultItems.props Co-authored-by: Sven Boemer <[email protected]>
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props
Outdated
Show resolved
Hide resolved
@MichalStrehovsky @sbomer by the way, we're seeing issues related to the general problem of "how to correctly detect whether you're publishing or not" coming up all the time, and I'm wondering whether this could be a good occasion to work together and see if we can actually find a solution that works well for this across both .NET, Windows, etc. For instance, in the MSX tooling there's a few scenarios where we're trying to detect whether we're actually publishing or not, because if that's the case then we know the ILC targets will also run, which means we need to account for the output binary being native and not having other separate managed .dll-s etc., which is relevant in several cases (eg. specifying the implementation .dll for a WinRT component in your APPX manifest). What we're doing right now is having targets that do something like If there were some property that we could consistently and reliably depend upon to just know "are we going to be published or not", then that solve all of these issues. Perhaps we should set up some time to chat and see if there's a proper solution we could come up with? 🙂 |
…DefaultItems.props Co-authored-by: Sven Boemer <[email protected]>
The moment this merges, _IsPublishing will be needed for WinUI/UWP to work. That puts a bit of a pressure on things. I think we'll just end up with _IsPublishing becoming really public and official, it already de facto is because the SDK gave people no choice.
Here's my thoughts around this:
I kind of wish Publish was a build configuration not a Target. I'm sure it would have other problems but it would solve a lot of problems here (since _IsPublishing affects how we build things too, not just what we do in the publish target). I spent a lot of time yesterday thinking about this and even after sleeping on it I don't see good answers. I wonder if in dotnet/runtime#109988 we solved the worst problem with the current approach and whether we should just keep shipping the framework in the ILCompiler package and swap it out before we start ILCompiler (and drop the idea of runtime packs, even on iOS/Bionic - we can just have a ILCompiler package without the compiler for those...). We can certainly try the approach in the PR too, but I'm starting to be concerned we'll be forced to roll it back because we don't have answers for the people invoking the Publish target today. |
#26324 tracks this. We could wait for a solution there, but my preference is to take the breaking change earlier rather than later, and adjust the error message once there's a better supported solution. (I do think this is a good occasion to find a broader solution, and introducing a clear error should help it get traction where it hasn't so far.)
To my knowledge it's not documented, just broken in ways that are hard to detect or diagnose (that's what #46070, #46171, and dotnet/runtime#95496 are supposed to help with).
Note that
It's certainly an option, but it feels to me like going against the grain of the SDK publishing design. From all the conversations I've had about |
That resolves my biggest concern. I'm still not sure if this will actually work out, but we can try. I assume we wouldn't ship .NET 10 RTM in shape where we have both a framework in a runtime pack and in the ILCompiler package. |
@akoeplinger do we need someone from dotnet/sdk for official sign off? |
@baronfel I saw you added "needs team triage" label so I assume you want to take a look? |
@akoeplinger I marked it so the SDK team would discuss this this week. We've done so and are working on some plans for 10 (chatting with @agocke and stuff) but have no specific feedback on this PR at this time. |
Ref: dotnet/runtime#87060