Closed eerhardt closed 9 months ago
@dotnet/linker-contrib a new issue has been filed in the ILLink area, please triage
Surprised that dotnet publish -p:PublishSingleFile=true
is self-contained by default. But I don't dislike the behavior. And agree with the proposal about PublishTrimmed.
The only thing I don't like is that these properties affect dotnet build
as well. In fact, I don't like self-contained dotnet build
at all. I think that should be a publish-only gesture.
I think this is happening because of the default RID selection. PublishReadyToRun/PublishSingleFile/PublishAot use the current RID, and having a RID currently implies self-contained. https://github.com/dotnet/sdk/blob/201d7199a60503fa627fd3c06cab03a53066ac92/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets#L79-L92 But @nagilson is working on a breaking change where RID no longer implies self-contained: https://github.com/dotnet/sdk/pull/30038.
I expect that after this change, PublishAot will have an error similar to the current one for PublishTrimmed, and the PublishSingleFile default will become framework-dependent. The latter might violate user expectations, but at least will be consistent with the new defaults.
@marcpopMSFT IIRC you set up the auto-tagging of @dotnet/linker-contrib based on the area labels. The team name changed to @dotnet/illink-contrib. Would you be able to update the bot config?
@sbomer see https://github.com/dotnet/sdk/pull/30152. Feel free to update this in the future if there are changes needed.
Good topic! We're trying to provide coherent behaviors for some things that are similar and others less so. It's sometimes easier when we group the options such that the answer pops out. Let's see if that happens here.
I'm going to use MSBuild syntax, where all properties are intended as true
or otherwise have coherent value.
Always framework-dependent:
RuntimeIdentifier
Supports both:
PublishReadyToRun
PublishSingleFile
Could support both, but only supports self-contained:
PublishTrimmed
Always self-contained:
PublishAot
PublishSelfContained
SelfContained
There are two ways we could go with this:
There are four groups. The pragmatic choice is make the first two groups fx-dependent by default and the second two are self-contained.
Another observation is that PublishTrimmed
is likely not used that often on its own. Instead, we could do the following:
PublishTrimmed
PublishSelfContained
to infer PublishTrimmed
and require users to disable trimming if they don't want it. We could also infer PublishReadyToRun
in the same way.That approach would have multiple benefits:
This approach seems to balance CLI consistency with convenience while also most often providing users with a set of artifacts that we would say are "good".
Default PublishSelfContained to infer PublishTrimmed and require users to disable trimming if they don't want it. We could also infer PublishReadyToRun in the same way.
It's worth noting that PublishTrimmed
and PublishReadyToRun
can be somewhat at odds, depending on the goals - trimming will remove R2R info and produce the smallest output, while R2R adds back some size in exchange for startup perf.
Single file would remain a separate concern. The thinking to date is that the various forms of single file should be opt-in since there are more compat considerations with single file variants than with self-contained.
It seems like the same reasoning would apply to PublishTrimmed
as well - there are compat concerns if we implicitly set PublishTrimmed
for PublishSelfContained
.
@richlander Based on my comment above, I want to retire SelfContained
as it is today. Specifically, I think if you want a self-contained output you should have to use dotnet publish
.
A couple more things, actually.
Default PublishSelfContained to infer PublishTrimmed and require users to disable trimming if they don't want it. We could also infer PublishReadyToRun in the same way.
I'm not sure I understand what you're suggesting here. You mean that if PublishSelfContained
is true, the default for PublishTrimmed
is also true? Or the other way around?
Single file would remain a separate concern. The thinking to date is that the various forms of single file should be opt-in since there are more compat considerations with single file variants than with self-contained.
The compat between self-contained single file and plain self-contained is getting pretty good at this point. It's pretty much just Assembly.Location now.
That's a good point @sbomer. Let's go with that.
I'm thinking about this more. I was trying to get at something with that categorization in my previous post, but I didn't quite know what. I do now.
Let's try again.
App characteristics (don't auto-switch from FDD -> SCD):
PublishReadyToRun
PublishSingleFile
PublishTrimmed
RuntimeIdentifier
App kind (these auto switch to SCD):
PublishNativeAot
PublishSelfContained
SelfContained
This feels like a more useful categorization, but I still don't find it particularly satisfying. For example, PublishSingleFile
feels like it should be an app kind and PublishTrimmed
only supports self-contained apps currently.
In the ideal case, users set the minimum values in their project file, like setting PublishSelfContained=true
. If they want to try out trimming or single file from the CLI, they will always get the desired result.
I think this conversation comes down to specializing a default project file (like what templates produce) via the CLI. I think a solution like this would help: https://github.com/dotnet/sdk/issues/26249#issuecomment-1406940259. It's basically the same thing as specifying the same values in a project file.
@agocke -- SelfContained
... I'm a little torn on that one. We need to decide once and for all that we're going to stay with publish
forever. If we agree to that, then I'm happy to go along with your suggestion. Related: https://github.com/dotnet/sdk/issues/26247.
@agocke -- I meant that PublishSelfContained
could infer PublishTrimmed
. I had proposed single file as a default in the past. @jkotas considered that too much of a compatibility risk for opt-out.
Upon further thinking, I think we should go with the categorization I have above and then rely on good project file and CLI gestures to make it easy to adopt the configuration you want. We just added PublishSelfContained
and the bad PM for that feature hasn't published a blog post on that yet. I think we don't have enough customer feedback to suggest we need something more dramatic. I'd rather see us make the CLI easier to use to specify defaults for an environment.
@baronfel @dsplaisted
Thanks everyone for engaging here + internally 😄
@richlander Should we still take this change: https://github.com/dotnet/sdk/pull/30038 if it does not have PublishAot
giving SelfContained
by default? Today is the last day for it to get merged (technically Monday at 3 PM...). It sounds like we are OK with this change breaking PublishTrimmed
, PublishSingleFile
, and PublishReadyToRun
such that old usages of these will now have to add SelfContained
.
If we have a finalized decision on this, we should close/edit this issue since we've seem to have decided against it, and make one specifically for having PublishAot
-> SelfContained
, as well as one for PublishSelfContained
.
Right. I'm suggesting that PublishAot
and PublishSelfContained
should infer SelfContained
.
I think all the other cases should not infer a SelfContained
value. That breaks our model, IMO, and is impossible to explain w/o giving folks a decoder ring. Sometimes what feels like a productivity killer (like our PublishTrimmed
example) is overshadowed by an inconsistent model.
Up-leveling a bit. We should be dissatisfied with experiences that are inconvenient. However, addressing those at the lowest levels (like with these properties) is just one option. We should ensure we have all the options on the table for how to address UX. I'm proposing we handle this UX concerns (like PublishTrimmed
being annoying) at a higher level. It's really only annoying for the CLI scenario.
If we intend to handle UX concerns at a higher level (which as I understand means through project templates, or some other way to "bake in" the chosen options), would it make sense to treat PublishAot
the same as PublishTrimmed
? That way it becomes very clear whether the output is SCD or FDD, based on the presence/absence of PublishSelfContained
, and PublishAot
is no longer the odd one out.
From the internal discussion it also sounds like a FDD PublishAot
deployment is possible in theory, even if it's unlikely we would add this option.
Then we can explain everything by saying that SCD is orthogonal to the other publish options. To use your terminology, SCD is an "app kind" and everything else is an "app characteristic" - where not all combinations are supported, but nothing is implicitly set (so no decoder ring is required).
I don't think PublishAot
and PublishTrimmed
are very similar. We could enable PublishTrimmed
for FDD if we wanted to. We just haven't. It also means we're one motivating customer request from doing so.
Another middling option is to expose another set of CLI flags, like --trim-scd
or similar.
We could enable PublishTrimmed for FDD if we wanted to. We just haven't.
The same can be said about PublishAot. (FDD was the default deployment option for .NET Native for UWP.)
You are right! I forgot about that. However (and correct me if I'm wrong), it seems more likely that we'll enable trimming for FDD than Native Aot for FDD. Or, do we just need to wait on a similar "one motiving scenario"?
I agree.
That's a bit ambiguous. There were two things you could agree with. I assume you were agreeing that trimming for FDD was more likely.
I assume you were agreeing that trimming for FDD was more likely.
Yep.
Here's a concrete proposal, since we still have time on our side.
PublishNativeAOT
and *SelfContained
imply SDC).I make no secret that I think this approach would be a good solution for this specific topic area and also have broader utility for even more common scenarios.
As stated above there's a conflict between consistency and "ease of use". The above discussion makes it clear that we're proposing sacrifying "easy of use on CLI" and want consistent CLI options. (Personally I'm split on this, but if most people think that's the right approach, let's do it). This means that for example adding trimming in CLI will be somewhat cumbersome (need to also specify SCD).
With that, I don't see why we would special case PublishNativeAOT
as the only which implies SCD. On the scale of "basic" to "advanced" uses, AOT is probably the most advanced right now, so we could argue that making it easy to use from CLI is low priority.
Another way to look at it - if we think we can solve the UX for trimming outside of CLI, I don't see why we could not solve it the same way for AOT as well. And then keep the CLI 100% consistent.
As already mentioned, we could introduce CLI-only aliases which solve the UX:
We're already introducing dotnet new api -aot
and thus it would make sense to have dotnet publish -aot
which will "do the right thing" (and that could mean different things for different TFMs if we really needed to). Basically, decouple the MSBuild properties (very explicit and orthogonal/independent) from use-of-use CLI options (targeted at the most frequent scenarios).
I don't think making a breaking change for PublishSingleFile to default to framework-dependent is correct. Logically, I want my app in a single file. To me, making the default behavior being "the whole app in a single file" is the expected behavior.
For PublishTrimmed, even if/when we support FDD with PublishTrimmed, the fact that we've only had self-contained for 4, going on 5, versions now should tell us what the logical default is. If the scenario isn't important enough to implement, it isn't important enough to be considered the "default".
I don't think making a breaking change for PublishSingleFile to default to framework-dependent is correct
I agree that this is one of the biggest downsides to the breaking change (RID no longer implying self-contained). Same applies to vanilla "dotnet publish -r \<RID>".
However, I would find it really unexpected if "dotnet publish" produced one kind (SCD/FDD) of deployment, but "dotnet publish -p:PublishSingleFile=true" produced a different kind. So I'll throw another idea into the mix: what if we made PublishSelfContained
true by default? It would keep the command-line options independent, and shifts where the breaking change is.
Pros:
Cons:
I'm not sure how significant the "dotnet publish" break is. Personally I only ever do a RID-specific publish anyway (and almost always want it to be self-contained), but maybe my usage is not representative.
PublishSelfContained
by default is an interesting idea. Another idea per @marcpopMSFT is that we could infer SelfContained
by default when using these properties, BUT have a warning like the old SelfContained warning,
WARNING: NETSDK11??: One of '--self-contained' or '--no-self-contained' options are recommended when `Publish*` is used.
Thoughts @richlander ? I think this is a good compromise with UX but also on the orthogonal properties perspective.
I don't think making a breaking change for PublishSingleFile to default to framework-dependent is correct
I agree that this is one of the biggest downsides to the breaking change (RID no longer implying self-contained). Same applies to vanilla "dotnet publish -r
".
IMO - This isn't part of the RID breaking change. I didn't specify a RID at all: dotnet publish -p:PublishSingleFile=true
. I don't get a warning on .NET 7, like I do for -r <RID>
.
Here's the product behavior to date. It's useful to record that so that we're all on the same page.
.NET 6:
root@d2e8b3f38232:/app# dotnet --version
6.0.405
root@d2e8b3f38232:/app# dotnet new console -o app
root@d2e8b3f38232:/app# dotnet publish
root@d2e8b3f38232:/app# find . | grep coreclr
root@d2e8b3f38232:/app# dotnet publish -p:SelfContained=true
MSBuild version 17.3.2+561848881 for .NET
Determining projects to restore...
All projects are up-to-date for restore.
/usr/share/dotnet/sdk/6.0.405/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(154,5): error NETSDK1031: It is not supported to build or publish a self-contained application without specifying a RuntimeIdentifier. You must either specify a RuntimeIdentifier or set SelfContained to false. [/app/app.csproj]
root@d2e8b3f38232:/app# dotnet publish -p:PublishReadyToRun=true
MSBuild version 17.3.2+561848881 for .NET
Determining projects to restore...
Restored /app/app.csproj (in 5.18 sec).
app -> /app/bin/Debug/net6.0/app.dll
/usr/share/dotnet/sdk/6.0.405/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Publish.targets(293,5): error NETSDK1094: Unable to optimize assemblies for performance: a valid runtime package was not found. Either set the PublishReadyToRun property to false, or use a supported runtime identifier when publishing. [/app/app.csproj]
.NET 7:
root@d94e82f2a8a2:/app# dotnet --version
7.0.102
root@d94e82f2a8a2:/app# dotnet new console
root@d94e82f2a8a2:/app# dotnet publish
root@d94e82f2a8a2:/app# find . | grep coreclr
root@d94e82f2a8a2:/app# dotnet publish -p:SelfContained=true
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored /app/app.csproj (in 4.97 sec).
app -> /app/bin/Debug/net7.0/linux-x64/app.dll
app -> /app/bin/Debug/net7.0/linux-x64/publish/
root@d94e82f2a8a2:/app# find . | grep coreclr
./bin/Debug/net7.0/linux-x64/libcoreclr.so
root@d94e82f2a8a2:/app# dotnet publish -p:PublishReadyToRun=true
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
All projects are up-to-date for restore.
app -> /app/bin/Debug/net7.0/linux-x64/app.dll
app -> /app/bin/Debug/net7.0/linux-x64/publish/
root@d94e82f2a8a2:/app# find . | grep coreclr
./bin/Debug/net7.0/linux-x64/libcoreclr.so
./bin/Debug/net7.0/linux-x64/publish/libcoreclr.so
root@d94e82f2a8a2:/app# dotnet publish -p:PublishTrimmed=true
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored /app/app.csproj (in 64 ms).
app -> /app/bin/Debug/net7.0/app.dll
/usr/share/dotnet/sdk/7.0.102/Sdks/Microsoft.NET.ILLink.Tasks/build/Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [/app/app.csproj]
root@d94e82f2a8a2:/app# dotnet publish -p:PublishSingleFile=true
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored /app/app.csproj (in 104 ms).
app -> /app/bin/Debug/net7.0/linux-x64/app.dll
app -> /app/bin/Debug/net7.0/linux-x64/publish/
root@d94e82f2a8a2:/app# dotnet publish -p:PublishNativeAot=true
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored /app/app.csproj (in 81 ms).
app -> /app/bin/Debug/net7.0/app.dll
app -> /app/bin/Debug/net7.0/publish/
I actually thought we implemented PublishSelfContained
last version, but I guess not. As I recall, this isn't the first time I've been confused by that.
The quick summary is this, all new in .NET 7:
SelfContained=true
implies a RID and previously did not.PublishTrimmed
doesn't imply a deployment typePublishAot
, PublishSingleFile
, and PublishReadyToRun
a imply SCD and a RID.However, I would find it really unexpected if "dotnet publish" produced one kind (SCD/FDD) of deployment, but "dotnet publish -p:PublishSingleFile=true" produced a different kind.
It is even more true for dotnet build
to dotnet publish
, in general. We cannot change dotnet publish
to be SCD. That's a very large breaking change and would fundamentally change the product. For example, there are tons of people that use our container images. They need to produce FDD apps for that to make sense.
I guess after all of this conversation, I conclude that we should leave the behavior as-is in .NET 7. I think we all agree that there is an affinity to SCD with Single File and AOT. That's why they have the current behavior. I'm no longer proposing we change that.
I'm still not convinced on PublishTrimmed
. We are going through a painful multi-release effort of changing what dotnet publish -r some-rid
means, making it FDD by default. I don't want to regret this moment when we later decide to support FDD trimming. I suspect it will happen at some point.
Let's assume that we were enabling FDD trimming this release. What would we do?
I think we'd enable it for both FDD and SCD PublishTrimmed
, and (like now) it wouldn't imply either.
We'd then need to decide if we wanted a simpler way to enable PublishTrimmed
+ SCD in one gesture. I'd be happy with PublishTrimmedScd
. Is that good enough to satisfy the usability concerns?
Tell me if I'm wrong, but I don't think we need to over-prioritize the loose-files scenario. I'm guessing that most folks prefer one of our single file scenarios. Also, has there been many requests to improve this? If not, then that suggests to me that people are using the single file options.
I just did some more research. I forgot about PublishReadyToRun
. It implies a RID and SCD. I updated the comment above to include that.
I'm not sure I agree with my previous thinking (in .NET 7) that led to this point, but I'm now coming to a different conclusion given the experiences all pushing one way and a desire for consistent behaviors and not breaking compat.
Back to what we'd do if we were enabling PublishTrimmed
now. I'd suggest then that we consider adding a PublishTrimmedFdd
variant and same to the other Publish*
properties that currently imply SCD but also can support FDD.
Outside of that idea, people could update their project files like this and that would work.
<PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
<PublishSelfContained>false</PublishSelfContained>
</PropertyGroup>
That leads me to the conclusion that all the Publish*
properties should imply SCD and a RID. That's not too crazy. The Publish*
properties were created for the non-default case. Most people that want the non-default case are opting for some form of SCD.
I agree that this is one of the biggest downsides to the breaking change (RID no longer implying self-contained). Same applies to vanilla "dotnet publish -r ".
IMO - This isn't part of the RID breaking change. I didn't specify a RID at all: dotnet publish -p:PublishSingleFile=true. I don't get a warning on .NET 7, like I do for -r
.
@nagilson please correct me if I'm wrong, but I believe that the behavior is the consequence of "use current rid for single-file" combined with "rid implies self-contained" - so I think https://github.com/dotnet/sdk/pull/30038 will result in single-file being FDD by default.
Unless we change it. We need to decide on the intended behavior and then we have deliver it. I have made a proposal on that.
Let's assume that we were enabling FDD trimming this release. What would we do?
I think we'd enable it for both FDD and SCD PublishTrimmed, and (like now) it wouldn't imply either.
all the Publish* properties should imply SCD and a RID.
I preferred the first conclusion. :) I would keep trimming orthogonal to FDD/SCD - it feels wrong to have one deployment mode for "dotnet publish", and the opposite for "dotnet publish -p:PublishTrimmed=true", especially if we support both.
It seems worth revisiting our reasoning for removing the "RID -> self-contained" behavior. My understanding is that since RID-specific works with both FDD and SCD, we wanted to keep the options orthogonal to each other. It was confusing that no-RID meant FDD, and RID meant SCD.
How are the publish options different? (Why should no-R2R be FDD, but R2R be SCD by default?)
Seems like there are three reasons why we might set defaults to particular values:
(3) is a bit tricky because the support might be temporary, but I don't necessarily think that's a bad reason to set a default if we think that even if that changes (2) still holds.
So it appears that we have three options:
Random thought, might be nice to enable something like this (it would just set the specific properties during the relevant target, with values for the specific properties winning if also specified):
<PropertyGroup>
<PublishKind>Trimmed;SelfContained;SingleFile;Release</PublishKind>
</PropertyGroup>
The valid values are any of the '*' values from the 'Publish*' properties. If an invalid combination is specified it would error.
@DamianEdwards Meh. Sorry, seems like clutter to me, and now I have to remember two ways of configuring the flags. 😄
@agocke well that's just, like, your opinion man 😉
But seriously, eye of the beholder and all that. But looking at this sea of publish properties made me desire something more concise, especially when we start talking about combination properties like PublishTimmedScd
ewww
combination properties like PublishTimmedScd ewww
Yeah, I'm not convinced we should do those either. At the end of the day I think the verbosity of setting each individual flag isn't such a big deal, and much of the verbosity actually comes from XML. I'd rather not create complex parsing just to work around XML verbosity. Whether or not we like it, it's the language we've chosen.
I'd rather not create complex parsing just to work around XML verbosity.
I understood this was an established pattern in our build system already (semi-colon separated values) so I didn't consider it as introducing anything new or complex.
Items are generally preferred, because then you don't have the (ridiculously common, always infuriating) problem of <NoWarn>CA12356</NoWarn>
accidentally overriding all the previous <NoWarn>
clauses.
But the difficulty mostly comes from your suggestion of parsing the separated values and then using them to set the PublishX property. Not easy to implement in MSBuild target language and not possible in a build task.
it would just set the specific properties during the relevant target
Interesting idea, but I don't think that's the key aspect we're struggling with. In fact, that feels a bit like an anti-pattern since we're trying to make the product provide best practice behavior by default. It just turns out that's hard in some cases..
especially when we start talking about combination properties like PublishTimmedScd ewww
Agree.
How are the publish options different? (Why should no-R2R be FDD, but R2R be SCD by default?)
You are right. The current system doesn't make much sense. When I was writing last night, I was getting "compat afraid". So, let's play the "compat be damned" game.
I'd switch all of these to FDD by default, give the teams the opportunity to provide a valuable FDD behavior, and then add a --scd
flag to the CLI. Obviously PublishSelfContained
would remain SCD.
Actually, I'd also leave PublishNativeAot
as-is, implying SCD. I don't think we're ever going to provide an FDD behavior for it. As Jan raised, we've done that in the past, but I am extremely doubtful that we'll ever repeat that.
This release is definitely our last opportunity to make these changes. What do folks think of this proposal? Certainly, it would be the most coherent to the product overall.
and then add a --scd flag to the CLI
We already have --self-contained
though right? Or am I misunderstanding?
Yes. It's a pain to type. What I'm hearing from this conversation is that people on the team (who I totally recognize are not our customers) find the following to be arduous:
root@d94e82f2a8a2:/app# dotnet publish -p:PublishTrimmed=true
MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored /app/app.csproj (in 64 ms).
app -> /app/bin/Debug/net7.0/app.dll
/usr/share/dotnet/sdk/7.0.102/Sdks/Microsoft.NET.ILLink.Tasks/build/Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [/app/app.csproj]
root@d94e82f2a8a2:/app# dotnet publish -p:PublishTrimmed=true --self-contained
The UX ask was to make -p:PublishTrimmed=true
to be SCD. While also recognize my flip-flop-ness on the topic, I've been pushing back on that. I'm trying to make the product consistent and easier to use at the same time. Adding --scd
was intended to help with that and be a middle ground answer. I do want to reiterate that I think this whole converation is a function of the CLI experience. I hold that we have a good model for project files since they are typically "get it right once and forget it".
Also, lots of CLIs offer short forms like that so it doesn't seem strange.
For example:
$ wget --help | grep verbose
-v, --verbose be verbose (this is the default)
-nv, --no-verbose turn off verboseness, without being quiet
Actually, I'd also leave PublishNativeAot as-is, implying SCD
This feels like my argument about commonality-over-consistency. Even if we build PublishAot FDD, it will be much less common than scd. I think at can make the same argument for Publish Trimmed or single file
NativeAot is most that way and we get farther from that level of certainty as we go. They don't sit at the same spot on the spectrum. That's why I don't find this argument convincing.
Also, we're never going to build Native AOT FDD. It's a waste of time since no one wants that modality.
Also, we're never going to build Native AOT FDD
The more I look at it, the more I think the same think about PublishTrimmed.
The more I look at it, the more I think the same think about PublishTrimmed.
I've seen several asks for FDD Trimming over time (TerraFx - if I remember correctly is one example, WinUI is another).
FDD Single-File is also pretty useful and I've seen it used. Definitely not as common as SCD though.
I personally don't buy any argument toward making R2R default to SCD - those two are completely orthogonal even functionally.
So the only two which I think we might consider are:
I'd switch all of these to FDD by default, give the teams the opportunity to provide a valuable FDD behavior, and then add a --scd flag to the CLI. Obviously PublishSelfContained would remain SCD.
This is my favorite proposal so far - and I like the less verbose --scd
flag as a UX improvement.
Regarding AOT and trimming:
To me trimming should align with the rest of the defaults (FDD). Otherwise if we ever add FDD trimming (not unlikely), we will have this undesirable scenario where the defaults flip if you opt into trimming.
Personally I would do the same for PublishAot (not imply SCD), even if it never supports FDD. Then we have a consistent/predictable UX across the board. I think the reasoning from https://github.com/dotnet/sdk/issues/30104#issuecomment-1408630029 still applies - any UX improvements at a higher layer (templates or CLI flags) could help with both trimming and AOT usability.
There's also the argument about one-way doors. If we make either scenario SCD by default, it is harder to go back. If we make them "fail by default" (with an obvious and easily fixed error) we still leave open the option of making them SCD by default in the future.
This suggests to me that we could take the breaking change as-is, and look for feedback in .NET 8 previews to see how painful it is for customers. We still have plenty of time to add SCD-by-default for trimming/aot if we need to.
less verbose --scd flag as a UX improvement
We already have --sc
.
@sbomer Thanks for bringing me in here.
Please correct me if I'm wrong, but I believe that the behavior is the consequence of "use current rid for single-file" combined with "rid implies self-contained"
This is correct.
Net 6: (No Implicit RID):
dotnet publish -p:PublishSingleFile=true
--> SelfContained=false
, except it will fail. Once you add the rid to make it pass, then it is the same as:
Net 7: (Implicit RID):
dotnet publish -p:PublishSingleFile=true
--> RuntimeIdentifier
--> SelfContained=true
For PublishSingleFile
the default FDD behavior is OK, it won't fail. And that was the default behavior in NET 6. (Well, you can do it with --no-selfcontained: but you need to provide a RID. Sorry for my sloppy language, thanks.)
Doing the following steps:
dotnet new console
dotnet publish -p:PublishTrimmed=true
Results in the following error:
However, doing
dotnet publish -p:PublishAot=true
dotnet publish -p:PublishSingleFile=true
Just works without more command line args.
We should make
PublishTrimmed=true
implySelfContained=true
, just likePublishAot=true
andPublishSingleFile=true
does. That way users don't need to pass extra args on the command line, just to make this work.If in the future we want to support a mode where
PublishTrimmed=true
, butSelfContained=false
, those customers can explicitly--self-contained false
. This is consistent with the currentPublishSingleFile=true
behavior. By default it is self-contained. And you can opt into Framework Dependent Deployment withdotnet publish -p:PublishSingleFile=true --self-contained false
.cc @vitek-karas @sbomer @agocke