Skip to content
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

[Breaking change]: RuntimeSpecific Apps in .NET Will No Longer Be SelfContained by default, and instead Framework Dependent By Default #33726

Closed
2 of 3 tasks
nagilson opened this issue Jan 26, 2023 · 4 comments · Fixed by #34497 or #35656
Assignees
Labels
binary incompatible Existing binaries may encounter a breaking change in behavior. breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 8 Work items for the .NET 8 release 📌 seQUESTered Identifies that an issue has been imported into Quest. source incompatible Source code may encounter a breaking change in behavior when targeting the new version. 🗺️ reQUEST Triggers an issue to be imported into Quest.

Comments

@nagilson
Copy link
Member

nagilson commented Jan 26, 2023

Description

RuntimeSpecific Apps (.NET Apps with a RuntimeIdentifier) Will No Longer Be SelfContained by default, and instead Framework Dependent By Default.
dotnet/sdk#30038

cc @richlander.

Version

.NET 8 Preview 5

Previous behavior

Previously, if RuntimeIdentifier (RID) was specified, the app would be SelfContained (SC) if SelfContained was not explicitly specified.

New behavior

Now, for apps with TargetFramework 8.0 or higher, RuntimeIdentifier no longer implies SelfContained by default. Instead, apps that give a runtime identifier will be dependent on the .NET Framework by default (FDD). Apps for .NET 7 or below will not see this change in behavior.

This is a break for any customer that deployed, distributed, published, etc, their app, and desired their app to not require the .NET Framework to be installed on the machine for it to work, but did not explicitly add SelfContained to get this behavior. They may have relied on the old behavior to produce a .NET Framework INDEPENDENT app by default.

This is a break for anyone relying on the IL Link tool. Users will have to take the steps described below to use IL Link again.
Note: Some Publish properties like PublishTrimmed, and PublishSingleFile, PublishAot, currently require SelfContained to work and using these properties will require SelfContained to be added now.

This is a break for Blazor WASM apps as they relied on this behavior. We expect the Blazor WASM team to side-step this breaking change in their SDK by adding SelfContained automatically for all customers, so Blazor customers should be unaffected.

Type of breaking change

  • Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code may require source changes to compile successfully.
  • Behavioral change: Existing binaries may behave differently at run time.

Reason for change

Previously we warned of this breaking change with the following warning in .NET 6:

warning NETSDK1179: One of '--self-contained' or '--no-self-contained' options are required when '--runtime' is used. [/app/app.csproj]

We have given customers time to add SelfContained explicitly.

As for why the change is being made:

  1. This is currently what Visual Studio does by default.  So it aligns the dotnet SDK with VS.
  2. It will save space to have apps be framework dependent by default as there won't be copies of .NET stored in each app.
  3. Command line options should be ideally orthogonal. In this case the tooling supports both RuntimeIdentifier specific SelfContained Deployment and RID specific Framework Dependent Deployments. So it's really weird that no-RID -> defaults to FDD and RID -> defaults to SCD. It has made even internal people at MSFT think that you cant have a Non SelfContained app (FDD) if a RID is given, which is NOT true.

Recommended action

Customers using .NET 7 and below who relied on the old behavior where SelfContained was inferred will see this warning:

For projects with TargetFrameworks >= 8.0, RuntimeIdentifier no longer automatically gives a SelfContained app. To continue creating a .NET framework independent app after upgrading to 8.0, consider setting SelfContained explicitly.

They should follow the guidance of the warning if they want to continue to produce SelfContained apps. If they would like to move to the new default, they can set SelfContained as false, in the project file, like

<SelfContained>false</SelfContained

or in the call to dotnet, like dotnet publish --no-self-contained.

For .NET 8, nothing needs to be specified unless the old default is desired, in which case the customer must add SelfContained as true.

Feature area

SDK

Affected APIs

No response


Associated WorkItem - 67115

@nagilson nagilson added doc-idea breaking-change Indicates a .NET Core breaking change labels Jan 26, 2023
@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Jan 26, 2023
@gewarren gewarren added 🏁 Release: .NET 8 Work items for the .NET 8 release and removed ⌚ Not Triaged Not triaged labels Jan 26, 2023
@dotnet-bot dotnet-bot added binary incompatible Existing binaries may encounter a breaking change in behavior. source incompatible Source code may encounter a breaking change in behavior when targeting the new version. labels Jan 26, 2023
@nagilson
Copy link
Member Author

Update: This has been delayed from Preview 1 to Preview 2. I will provide an update when possible; we may redecide this part of the decision:

Note: Some Publish properties like PublishTrimmed, and PublishSingleFile, PublishAot, currently require SelfContained to work and using these properties will require SelfContained to be added now.

@gewarren gewarren added the 🗺️ reQUEST Triggers an issue to be imported into Quest. label Mar 2, 2023
@github-actions github-actions bot added 📌 seQUESTered Identifies that an issue has been imported into Quest. and removed 🗺️ reQUEST Triggers an issue to be imported into Quest. labels Mar 2, 2023
@ghost ghost added the in-pr This issue will be closed (fixed) by an active pull request. label Mar 10, 2023
@github-project-automation github-project-automation bot moved this from 🔖 Ready to ✅ Done in dotnet/docs March 2023 sprint Mar 13, 2023
@ghost ghost removed the in-pr This issue will be closed (fixed) by an active pull request. label Mar 13, 2023
@nagilson nagilson reopened this Apr 26, 2023
@nagilson
Copy link
Member Author

nagilson commented Apr 26, 2023

We did reach a final decision. Here are the new details about this break. It will go into preview 5.

Here are the new things that arent listed above:

Changes to Publish Property Behaviors

Some Publish Properties currenlty only work if SelfContained is true which are the ones described above such as PublishSingleFile. The following properties will experience different behavior. They will imply PublishSelfContained and therefore SelfContained whenever added during publish only. In .NET 7 all of these properties except PublishTrimmed already did this but also for build.. restore.. etc. Now they only do it during publish and PublishTrimmed infers SelfContained for the first time under this change.

IF the targetframework is 8 or higher: PublishAot, PublishTrimmed, PublishSingleFile will add SelfContained as true to the project only when publishing via dotnet publish and only if SelfContained is unspecified.

The difference here is that its only during publish. And for PublishTrimmed this is new behavior.

The exception to this is PublishReadyToRun. In .NET 7 this property made the app SelfContained if SelfContained was not specified. With the new change.. this property will NOT infer or imply SelfContained if the TFM is 8 or higher.

Why this change

We made this decision based on which properties do not currently support apps that are SelfContained.. which properties we plan on adding that support to in the future.. and which defaults were agreed upon to have the easiest UX for each property.

Action to take

If someone is affected by this break they should specify SelfContained as either true or false depending on the behavior they want. They can add it in their project file or in the command line as earlier described.

@nagilson
Copy link
Member Author

@gewarren Please let me know if there are any questions here. Thank you!

@nagilson
Copy link
Member Author

Preview 5 it is!

@gewarren gewarren added the 🗺️ reQUEST Triggers an issue to be imported into Quest. label Jun 2, 2023
@ghost ghost added the in-pr This issue will be closed (fixed) by an active pull request. label Jun 5, 2023
@gewarren gewarren moved this from 🔖 Ready to 🏗 In progress in dotnet/docs June 2023 sprint Jun 5, 2023
@gewarren gewarren moved this from 🏗 In progress to 👀 In review in dotnet/docs June 2023 sprint Jun 6, 2023
@github-project-automation github-project-automation bot moved this from 🆕 New to ✅ Done in .NET 8.0 work items Jun 7, 2023
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in dotnet/docs June 2023 sprint Jun 7, 2023
@ghost ghost removed the in-pr This issue will be closed (fixed) by an active pull request. label Jun 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
binary incompatible Existing binaries may encounter a breaking change in behavior. breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 8 Work items for the .NET 8 release 📌 seQUESTered Identifies that an issue has been imported into Quest. source incompatible Source code may encounter a breaking change in behavior when targeting the new version. 🗺️ reQUEST Triggers an issue to be imported into Quest.
Projects
No open projects
Status: Done
Status: Done
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants