Enable projects to use the SDK `TargetFramework`
See original GitHub issueThe .NET SDK comes with a targeting pack and a runtime (in addition to build tools). If you compile an app for the same version as the SDK, then you can use the targeting pack and runtime that comes with the SDK. Yeahh! If you compile an app for an older version, then you need an older version of the runtime and targeting pack. You can either install those or update the project file. There is no way to that via the commandline. You can change the RID via the commandline but not the TFM.
The .NET SDK offers a variety of controls for controlling compile-time vs runtime framework versions. The model, however, could be better. This is particularly obvious if you are wanting to test existing/old apps on a newer SDK.
FYI: I’m using older .NET versions for my examples, only because they were convenient. This experience hasn’t changed recently.
This is the base experience today, when SDK and TargetFramework
don’t match:
root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# dotnet --version
6.0.113
root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# dotnet run
You must install or update .NET to run this application.
App: /core/samples/dotnet-runtimeinfo/bin/Debug/netcoreapp3.1/dotnet-runtimeinfo
Architecture: x64
Framework: 'Microsoft.NETCore.App', version '3.1.0' (x64)
.NET location: /usr/lib/dotnet
The following frameworks were found:
6.0.13 at [/usr/lib/dotnet/shared/Microsoft.NETCore.App]
You cannot updated TargetFramework
from the commandline, AFAICT.
root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# cat dotnet-runtimeinfo.csproj | grep TargetFramework
<TargetFramework>netcoreapp3.1</TargetFramework>
root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# dotnet run -p:TargetFramework=net6.0
/usr/lib/dotnet/sdk/6.0.113/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(267,5): error NETSDK1005: Assets file '/core/samples/dotnet-runtimeinfo/obj/project.assets.json' doesn't have a target for 'net6.0'. Ensure that restore has run and that you have included 'net6.0' in the TargetFrameworks for your project. [/core/samples/dotnet-runtimeinfo/dotnet-runtimeinfo.csproj]
The build failed. Fix the build errors and run again.
The RollForward
property works pretty well. It can be added to a project file or injected via ENV
or the CLI (via -p:RollFoward
). RollForward
model has the downside that an old target framework needs to be downloaded, at least in the case that you want to use a new SDK for both compiling and running the app.
Instead, it would nice if there was a way to say “roll forward by using the SDK target framework”. That would result in using SDK-provided assets and to naturally using the SDK runtime version.
We could offer a way to specify what the minimum target framework is for a project and infer the actual target framework from the SDK (assuming it is same or higher). That way, you wouldn’t ever get weird compile-time failures due to missing APIs.
Perhaps via the following property:
<MinimumTargetFramework>net6.0</MinimumTargetFramework>
or possibly:
<TargetFramework>net6.0</TargetFramework>
<UseSdkTargetFramework>true</UseSdkTargetFramework>
The second property could also be UseSdkDefaults
if we wanted something more general.
This approach would have a few benefits:
- The SDK version would become the primary version concept to reason about (for folks that adopted this model).
- The (minimum) TargetFramework property would solely describe API surface area, as opposed to also determining minimum runtime version.
- The SDK-provided targeting pack would be used, skipping an extra download.
- The
RollForward
property wouldn’t need to be used as part of development, leaving it only for deployed apps.
Some apps would break with this model, either due to breaking changes, warning waves or something else. It’s less about the apps breaking and more about the care factor of the apps breaking. There are two solutions for that: don’t use the feature, or use global.json
. For people that use global.json
, this feature would still have significant value.
This model would be more complicated for compound TFMs, like the ones we have for Android and iOS. That would require some more thought. I thought we should start out with the base premise before looking at those TFMs.
This model wouldn’t work (at least not naturally) with multi-targeting. That seems fine, both because multi-targeting is uncommon with apps and because multi-targeting is an intentional model that isn’t amenable to policy solutions like this.
Issue Analytics
- State:
- Created 8 months ago
- Comments:11 (10 by maintainers)
Top GitHub Comments
Perhaps we should put a version number at the top:
That completes the pivot. The
8.0
would be a minimum.Or better yet:
Obviously, there might be an
ItemGroup
here.@mhutch @DamianEdwards
Yes. Certainly, whether it is opt-in min or exact is a detail.
There are really two suggestions here: