-
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
Proposal for platform-specific apps for .NET 8 #29950
Comments
Thanks for scoping this out. We should definitely spend time thinking about the defaults we've set. In the past, you've shown with
By this, I assume you mean when building/publishing for TFM below 8 on the 8.0 SDK. Correct me if I'm wrong.
The
I assume this would be undefined if the Output is not
IMO I would want to keep apphost. I think space is less of a premium nowadays, as a developer / user of .NET I would prefer ease of use over saving some MB. It depends on how big the apphost is, which I am unsure of?
I think we should only do this for templates if we do it as you suggested. But personally, I still think I would prefer my app to be portable unless defined otherwise. |
I'm making the point that the warning message for pre .NET 8 TFM apps can link to a breaking change notice, for example. We would have more information than we did when we first wrote the warning and could share that.
I'm proposing to replace
I'm raising that I don't think that there is an important scenario for the apphost with portable apps, with the exception of development. Do you have scenarios in mind?
Why is that? I think you are making a value judgement on one set of scenarios over others. Can you elaborate on that? |
100%. I also interpret this as the breaking change being
We have made progress on a new spec for this, so dropping this discussion. Excited with the final outcome of what we came up with!
Nope, I better understand what you mean now. It's unfortunate we didn't get to discuss this today, but it's something we should definitely look at. But this isn't in a state where it's super actionable for us until it's been discussed further. If there are customers who want it / data on how much space it would save, etc, this would be good to add.
That is true. This feedback was mainly targeted toward the concept of making |
The portable apphost change isn't about space saving. It's about defining the scenario for the apphost (for portable apps). I claim that it is very narrow and that having it confuses things. If it wasn't there, it would help people better understand what portable apps are for. Perhaps it isn't obvious, but the apphost is NOT portable. |
To make sure I'm understanding this correctly, these would all be distinct breaking changes for apps targeting .NET 8 here, right?
Can we not let
I think development is a large one. If we do this, it might make sense to default to keeping it for development scenarios rather than requiring users to se a new property. |
We're not planning on changing the underlying default (at least not now) so we're reliant on a new property in .NET 8 templates. Many users don't real with these low-level concepts today. There were two points against
We chose A lot of this is "least bad design". We concluded that the proposed plan is "least bad." The rules we had in mind:
Yes, the development time scenario for an apphost for portable apps is compelling. It's called out and I think enabling that some way is a good idea. |
The platform specialization part of this has been completed in #30038 :) |
Hey, it's not really clear to me what the plan is anymore, could someone clarify? Is RID-specific going to become the default for |
@reflectronic my understanding was that it was not, at least in .NET 8. IIRC last time this was discussed it was suggested that this be revisited very early in .NET 9 (e.g. preview 1) to ensure any associated impact can be better assessed and mitigated. |
Damian's recollection is correct! Though the idea of doing it in .NET 9 is very up in the air. |
I don't want to say, I told you so! yet here I say anyways!! This is exactly what I proposed when we moved to .NET 5 with a new TF! Here's my comment and examples using We need multiple frameworks either platform-specific ( I see that we are going down the same path once again but this time we should learn from past transgressions. |
Proposal for platform-specific apps for .NET 8
We've been on a journey to rationalize
dotnet build
anddotnet publish
in terms of producing platform-specific apps and how the CLI exposes a natural progression of app specialization options. The overall product started out without sufficient design on this topic and we've been trying to remedy that ever since. We believe we can finally correct these design challenges with .NET 8.Notes:
build
is used a short-hand forbuild
andpublish
unless specifically called out otherwise.publish
UX #26446.Context
Framework-dependent apps have been the default
build
output type since .NET Core 1.0. That remains the best default in our view. The primary deployment model for .NET is a globally installed runtime, and framework-dependent apps align with that. We should retain this behavior.In many scenarios, an app will only ever run in one platform environment (like Linux + x64), and developers know that a priori (for example for containers or client apps). There can be performance benefits by taking advantage of that. In addition, apps built for a single environment are simpler (fewer assets and flat directory structure). We should make it easier to produce platform-specific apps, ideally making it the default.
In contrast, in other scenarios, developers benefit from apps being portable across operating system and architectures. That model has been the default to date and is arguably an advanced pseudo-magic behavior. This behavior should be opt-in since it comes with important trade-offs that developers should understand (or that publishing workflows provide as a requirement).
Platform specialization
Developers can specialize an app for a given platform by specifying a Runtime ID (RID) when building an app, with the
-r
argument, like with:dotnet build -r linux-x64
Specializing an app with a RID produces a self-contained app. This design choice has always been unfortunate, since RID specialization equally applies to framework-dependent and self-contained apps.
The SDK provides a warning when a RID is specified without any additional arguments related to output type. This warning was added with .NET 6.
The intent of this warning was enabling an eventual change in the default behavior when specifying a RID. Given that the warning has been in place for two versions, including an LTS version, we can reasonably now make the change.
Starting with apps that target .NET 8:
--self-contained
or--self-contained true
is specified, then a self-contained app will be produced. Same when theSelfContained=true
.NETSDK1179
will no longer be produced.As the current warning suggests, developers should specify
--self-contained
in response for this change, if they haven't already.Platform specializing by default
We can further refine this proposal by specializing apps by default. We also need to consider compatibility, and an opt-out to enable producing portable apps.
In fact, there is already a CLI argument that provides this behavior:
root@efbeccd6a45b:/app# dotnet build --help | grep runtime --use-current-runtime Use current runtime as the target runtime.
We could add a property with that name, but we can probably do better.
Instead, we propose a
TargetRuntime
property that pairs withTargetFramework
. It will be a convenience wrapper overRuntimeIdentifier
, meaning that it will always produce a valid value (including empty string) for that property.TargetRuntime
will allow the following values:portable
-- same as specifying no RID and procurrent
-- same as specifying--use-current-runtime
.NET 8 templates will be updated to include this property, set to
current
, making .NET 8 apps RID-specific by default.The follow project file demonstrates the change for the
console
template.We are aware that there are two variants of "current RID", one short, one long.
The
--use-current-runtime
flag results in an OS-specific RID, likeosx-arm64
, whiledotnet --info
prints a RID with a version, as follows.% dotnet --info | grep RID RID: osx.13-arm64
That seems odd and asymmetric. Ideally, both variants would be accessible from within a project file and the CLI. More generally, we don't have good names for these different styles of RIDs. We don't need to resolve that for this feature, but it is something that we should separately look into.
Portable apps and apphost
Portable apps include the apphost by default. That doesn't really make sense since the apphost is platform-specific, while the rest of the app is intended to work anywhere. However, it's possible that developers appreciate having an apphost for local dev.
There is no harm to shipping an apphost with a portable app. It is very small and very unlikely to be the source of a vulnerability. However, the platform it supports is arbitrary with respect to the platforms it might run on. As a result, it is hard to describe a general use case (beyond development).
We could adopt the following model:
UseAppHost=true
.UseDebugAppHost=true
(which would be a new property). An alternative would beUseAppHost=Debug
.As an aside, we notice many
Dockerfile
examples where apps are launched with thedotnet foo.dll
pattern, even those they don't need to. Lauching an app with thedotnet
launcher is a fine pattern and should certainly be embraced by portable apps, since it's the only correct cross-platform pattern.@nagilson @DamianEdwards @baronfel @dsplaisted @elinor-fung
The text was updated successfully, but these errors were encountered: