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

.NET 8: Tracking for TFM trimming, and elimination of net4* targeting in Linux source-build #3014

Closed
25 of 29 tasks
mmitche opened this issue Aug 29, 2022 · 9 comments
Closed
25 of 29 tasks
Assignees
Labels
area-product-experience Improvements in the end-user's product experience

Comments

@mmitche
Copy link
Member

mmitche commented Aug 29, 2022

Description

Tracking for #2901. Requires #3013. source-build net4* targeting elimination required #2974

The purpose of this operation is twofold:

  • Reduce the number of TFMs present overall in .NET's build, potentially improving build time.
  • Eliminate framework TFMs, drastically reducing the size of the source build repository size.

When TFMs other than the latest .NET Core TFM are targeted in source-build, the reference assets for that TFM must be provided via a source build reference package. This is a 'text only' package that is assembled from IL at the beginning of the build to satisfy the required reference assets. In Microsoft's build, these would be restored from the internet, but in source build this is not allowed.

These SBRPs are large. All told, the total size contribution for just the netframework 4* TFMs is around 3GB. Not only does this have a significant contribution to the source build repo size, but it also affects build time. For Linux source build, we spend large amounts of time building assets that are simply thrown away at the end.

An 'ideal' would be a single TFM used throughout all of the .NET build, source build or otherwise. This is not possible. There are legitimate reasons to target older TFMs, especially netstandard. However, we should be able to justify each additional TFM.

To complete this work, repositories will use the tooling provided via #2901 to identify the TFMs in use in their repository. For each TFM, they should do the following:

  • If the TFM can be eliminated, or upgraded to latest (e.g. target the latest netcore explicitly, or use net472), do so. netframework TFM removal for tools and internal code is likely low hanging fruit.
  • Requires Design for unified behavior controls #2974 If the TFM is a framework TFM, it should be conditionalized out in source build for Linux.

It is a goal that the form of this conditionalization remain consistent across projects, and used relatively sparingly. How this conditionalization should be done will be designed in #2974

Repositories

@dotnet-issue-labeler dotnet-issue-labeler bot added area-product-experience Improvements in the end-user's product experience untriaged labels Aug 29, 2022
@mmitche
Copy link
Member Author

mmitche commented Aug 29, 2022

@MichaelSimons Here is the bones of the tracking issue I'm going to open in the repos, can you take a look?

@ericstj For non-source-build cases where we need to target netframework, and any netframework TFM will do, is there a preferred TFM? I'm mostly thinking of non-shipping packages or tooling, as this would be a breaking change otherwise.

@ericstj
Copy link
Member

ericstj commented Aug 30, 2022

For non-source-build cases where we need to target netframework, and any netframework TFM will do, is there a preferred TFM

In dotnet/runtime we have a preference for libraries - the minimum last supported framework which we define as NetFrameworkMinimum. There is likely a different preference for things that are part of VS and that's whatever VS's pre-requisite framework is. I'm not certain what that is, but I do see the SDK targeting net472. cc @marcpopMSFT @ViktorHofer

@ViktorHofer
Copy link
Member

In dotnet/runtime, all libraries target NetCoreAppCurrent and that refers to the .NETCoreApp version currently being developed. Packages target additional frameworks like net6.0, net7.0, net462, netstandard2.0 and netstandard2.1.

IMHO if feasible, for source build, we should only build NetCoreAppCurrent. In dotnet/runtime we already support building just a slice of the graph but as NuGet still restores all target frameworks we would need to rewrite the TargetFrameworks property to trim the other frameworks out.

@mmitche
Copy link
Member Author

mmitche commented Aug 31, 2022

IMHO if feasible, for source build, we should only build NetCoreAppCurrent. In dotnet/runtime we already support building just a slice of the graph but as NuGet still restores all target frameworks we would need to rewrite the TargetFrameworks property to trim the other frameworks out.

What about internal tooling or non-shipping packages? Do we have any cases where we are building framework bits in runtime today?

It would be awesome to code up the TargetFrameworks properties in such a way that it's globally overridable on the runtime side. It is less ideal to have a ton of conditionals in every project.

@ViktorHofer
Copy link
Member

What about internal tooling or non-shipping packages? Do we have any cases where we are building framework bits in runtime today?

Yes, we have msbuild tasks that target .NET Framework but those target .NETCoreApp as well. For source build I guess it's OK to not build the .NET Framework msbuild tasks.

It would be awesome to code up the TargetFrameworks properties in such a way that it's globally overridable on the runtime side. It is less ideal to have a ton of conditionals in every project.

Yes that should be possible via a clever regex pattern (because we not just target net7.0 but also net7.0-windows, net7.0-unix, etc.). A regex pattern applied on the $(TargetFrameworks) property in a targets file should be able to remove anything except $(NetCoreAppCurrent).

That said, the feasibility question regarding repositories only relying on $(NetCoreAppCurrent) assets still stands. We in dotnet/runtime are technically able to only produce $(NetCoreAppCurrent) assemblies and packages but if dependent repositories require other target frameworks like net6.0 or .NETStandard then this wouldn't work.

@mmitche
Copy link
Member Author

mmitche commented Aug 31, 2022

Yes, we have msbuild tasks that target .NET Framework but those target .NETCoreApp as well. For source build I guess it's OK to not build the .NET Framework msbuild tasks.

Do you think that the framework tasks are still required at all?

That said, the feasibility question regarding repositories only relying on $(NetCoreAppCurrent) assets still stands. We in dotnet/runtime are technically able to only produce $(NetCoreAppCurrent) assemblies and packages but if dependent repositories require other target frameworks like net6.0 or .NETStandard then this wouldn't work.

I think we should keep netstandard where we actually want to release a package as netstandard. Downstream repos should not be targeting net6 (for various reasons) in source build. Those binaries going to be running on a net7 runtime, regardless of whether they want net6 or not.

@ViktorHofer
Copy link
Member

I think we should keep netstandard where we actually want to release a package as netstandard.

How many of those packages do we have? As .NETStandard's public api surface is limited I noticed that many/most packages that offer a .NETStandard asset, multi-target to benefit from newer .NETCoreApp features. I would be surprised if we have many packages that are .NETStandard only. It might make sense for the stack to always target the very latest. (That's what we do in runtime).

Do you think that the framework tasks are still required at all?

They should not be required. Also FWIW msbuild was considering making it possible to load .NETCoreApp tasks in the .NET Framework version of msbuild and inside VS so that we can remove the .NETFramework task variants.

@mmitche
Copy link
Member Author

mmitche commented Aug 31, 2022

How many of those packages do we have? As .NETStandard's public api surface is limited I noticed that many/most packages that offer a .NETStandard asset, multi-target to benefit from newer .NETCoreApp features. I would be surprised if we have many packages that are .NETStandard only. It might make sense for the stack to always target the very latest. (That's what we do in runtime).

Roger that. At least we need a way to evaluate what we are producing and then we can make decisions.

@mmitche mmitche changed the title .NET 8: Tracking for TFM trimming, and elimination of net4* targeting in source-build .NET 8: Tracking for TFM trimming, and elimination of net4* targeting in Linux source-build Sep 1, 2022
@MichaelSimons
Copy link
Member

@NikolaMilosavljevic - What work remains here? Can this be closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-product-experience Improvements in the end-user's product experience
Projects
Archived in project
Development

No branches or pull requests

5 participants