project-system icon indicating copy to clipboard operation
project-system copied to clipboard

Build & Run - only one TFM in multi-target project

Open rainersigwald opened this issue 8 years ago • 3 comments

Copied from original issue https://github.com/Microsoft/msbuild/issues/1818 posted by @onovotny

When making changes to multi-targeted libraries, the project system/MSBuild has to rebuild all TFM's as part of the build graph. This is not necessary if I want to run an app on a particular TFM. The build system should only build the necessary closest TFM.

Concrete example:

  • .NET 4.6 exe references multi-targeted library with net45 and netstandard1.4 outputs (there may be many more).
  • Change is made in the library
  • User hits F5 to debug/run the app.

Actual results The library is built twice, once per TFM

Expected results Library is built once

Note, if I just build the library or the sln, it should build all. This is an optimization for when I build a specific library/app/output that depends on another one and it knows which one it needs.

rainersigwald avatar Mar 08 '17 17:03 rainersigwald

Migrating this here because MSBuild and the Sdk do the right thing--a command line build of the app builds only the net45 version of the lib in this example.

Visual Studio, though, sees that the project is out of date and invokes "Build" on the "outer" instance of the project, which in turn builds all TFMs.

rainersigwald avatar Mar 08 '17 17:03 rainersigwald

I don't think there's a lot we can do here due to the current design of build inside Visual Studio. Unlike the command-line, MSBuild itself is not the scheduler of solution builds; the VS Solution Build Manager is.

MSBuild via command-line can be smart here and only build what's actually required for a reference because as it builds references at the point it resolves them.

Inside VS, references are built by Solution Build Manager. Previously we had told the Solution Build Manager "hey this entire project is our dependency", so when we kick off a build due to an F5 for a given project, it just looks at all the dependencies of that project and builds them (entirely) in dependency order. There's no extra context that we can pass to say "hey we only need .NET 4.5 bits from this dependency".

davkean avatar Mar 08 '17 22:03 davkean

We build a web product that contains around 150 .net 4.6.2 projects, we would like to migrate to .net 6.0 framework but we can't do this in one shot, it is a long background task. To achive this it could be handy to use multi targetting and conditionnal preprocessing (#if tfm). But the problem is that it will impact a lot the compilation time since actually when we compile a solution all multitarget projets are built in all specified targets !

I could modify all csproj and change<TargetFrameworks> tag content on our CI but it seems a bit hackish.

Is there something more conventionnal ?

Thanks

DomZZ avatar Feb 10 '22 08:02 DomZZ