dotnet / core

.NET news, announcements, release notes, and more!
https://dot.net
MIT License
20.98k stars 4.91k forks source link

Proposed .NET 7 Breaking Changes #7131

Open richlander opened 2 years ago

richlander commented 2 years ago

The following list defines breaking changes that are proposed for .NET 7.

Implemented:

Planned for .NET 7:

Unclear plan:

Moved to .NET 8:

No longer honor multi-level-lookup (MLL) for .NET 7+ apps, runtimes and SDKs

Proposal: https://github.com/dotnet/designs/blob/main/accepted/2022/disable-multi-level-lookup-by-default.md Change: https://github.com/dotnet/runtime/pull/67022 Notice: https://github.com/dotnet/docs/issues/28836

Multi-level-lookup (MLL) -- specified with DOTNET_MULTILEVEL_LOOKUP -- is relevant when an alternate location is specified to look for SDKs and/or runtimes, via DOTNET_ROOT. When enabled, MLL expands the search space for runtimes and SDKs to include the global .NET installation location in addition to the DOTNET_ROOT location. This can result in a runtime or SDK being selected from the global installation location rather than the intended private DOTNET_ROOT location, whether that is desired or not.

Motivation for break:

Stop adding 32-bit .NET to the PATH for .NET 7+ runtimes and SDKs (on x64 machine)

Proposal: https://github.com/dotnet/sdk/issues/22030 Change: https://github.com/dotnet/runtime/pull/69902 Notice: https://github.com/dotnet/runtime/issues/70039

Note: This change was made to .NET Core 3.1, .NET 6, and .NET 7.

When you install .NET, the installer adds the install location to the PATH environment variable. This behavior is sound and enables the OS to find dotnet when you use it. We build multiple .NET for multiple architectures (x86, x64, ...). In some cases, an OS supports multiple architectures and then we need a plan for how multiple .NET locations in the PATH works. In short, it doesn't work well. Going forward, we should only ever add the OS native-architecture .NET install location to the PATH. We already started doing that on Apple M1 (Arm64) machines (we only add the Arm64 .NET to the PATH, not the x64 version). We need to repeat this pattern with Windows now, with the 32-bit .NET build.

Motivation for break:

dotnet build/publish uses the implicit SDK RID for RID-specific apps by default

Proposal: https://github.com/dotnet/sdk/issues/23539 Change: https://github.com/dotnet/sdk/pull/22314 Notice: not actually breaking

Today, you must specify a RID when you specify "--self-contained". That's not a useful requirement, particularly if you want to app to be able to run in a given environment (like CI) and don't know what that is ahead of time. Instead, the implicit SDK RID should be used in any scenario where a RID is needed but one isn't provided. The most obvious example of that is to produce a self-contained app.

FYI: This is arguably not a breaking change.

Motivation for break:

dotnet publish/pack produce release assets by default

Proposal: https://github.com/dotnet/sdk/issues/23551

Our basic guidance to developers since .NET Core 1.0 has been "use build for development and publish for prod". Given that, it would make a lot more sense if publish defaulted to a release build. Debug builds run observably slow (sometimes you can see this with just your eyes; no stopwatch required). It is near certain that plenty of .NET apps are deployed as debug due to the current defaults. The CLI would be much better if it offered more differentiated options. There should probably be a more broad re-assessment of build and publish but I'm not digging into that here. I'm proposing a much more simpler change (that doesn't preclude broader changes later; in fact, this change would encourage them).

Motivation for break:

dotnet build/publish produces RID-specific apps by default

Proposal: https://github.com/dotnet/sdk/issues/23540

The .NET SDK has produced portable apps since .NET Core 1.0. That may or may not have made sense, but it no longer does now. Portable apps are bigger, slower to startup, and less reliable in some scenarios. In addition, portable apps are not fully coherent since they have a RID-specific executable but portable assets. That means that you can use the executable for one RID environment and cannot for any other. It's an odd design choice. A perfect example is containers. RID-specific apps are always better for containers. Another example is client apps. Client apps require an executable, such that they should always be RID-specific.

Motivation for break:

dotnet build/publish does not produce an exe/apphost for portable apps by default

Proposal: https://github.com/dotnet/sdk/issues/23545

Portable apps are intended to run in multiple environments. By definition, an executable is RID-specific and therefore only compatible with one of the environments in which a portable app can run. It's possible that developers are happy with this asymmetry, but should opt into that experience.

Motivation for break:

Precompile with AVX2 (x64) or NEON (Arm64) instructions for better startup performance

Proposal: https://github.com/dotnet/designs/pull/173

Vector (SIMD) instructions are now one of the key performance pillars of the .NET platform. Today, pre-compiled Ready-to-Run (R2R) code targets the SSE2 instruction set on x64. We require the JIT to tier the platform to tier 1 in order to take advantage of larger/newer vector instructions (like AVX2). That model penalizes startup on modern hardware and also places a hard dependency on tiered compilation for good performance. Ideally, R2R code was already very good, and tiered compilation was reserved for only the highest value methods. We can achieve that by compiling R2R code with AVX2 (x64) and NEON (Arm64) by default. We would not change the Windows 32-bit or Arm 32-bit builds.

Note: After this change, machines with AVX2 will have better performance, while machines w/o it will end up with worse performance since some R2R methods will be rejected and require jitting where they previously did not.

Motivation for break:

For additional context, SSE2-compatible hardware was first released in 2000, and the same for AVX2 in 2013.

baronfel commented 1 year ago

@stunney are you meaning the breaking change described here? If so this was in 7.0.200 so I'm confused why you're seeing it in 6.0.300+. This was a regression and should be fixed in 7.0.201, which I was able to use in GitHub Actions. If you have a pointer to an erroring project or CI pipeline we could investigate further?