Workload Target Imports Design#224
Conversation
| ### Change import location of `Directory.Build.targets` | ||
|
|
||
| Change`Directory.Build.targets` to be imported after TargetFramework parsing but before workloads and most of the .NET SDK and common targets. This would be a big breaking change but might not affect most people who use `Directory.Build.targets`. It would break people who use `Directory.Build.targets` to override properties or targets in the MSBuild common targets. | ||
|
|
||
| #### Pros: | ||
|
|
||
| - Logic to enable workloads in `Directory.Build.targets` would “just work”, which is likely what developers expect |
There was a problem hiding this comment.
I strongly prefer this option. It took a while to evangelize the use of Directory.Build.props and Directory.Build.targets. I believe we should strive to optimize for letting developers do 99% of their tweaks by just these files. Having to put more stuff in new files whose import order is slightly different is a complexity nightmare. Yes, this is a breaking change but I think that's a perfect example where the net harm of the breaking change is much lower than the additional cognitive load over more files over time.
There was a problem hiding this comment.
It's hard to grok how significant this is or is not though. Can we get some examples of which properties we can no longer override in Directory.Build.targets if we take this approach. At the moment it's pretty nebulous hence it's hard to decide if this is or is not the right approach.
| - Logic would be split betweenthe .NET SDK and MSBuild, as the .NET SDK would now be responsible for importing `Directory.Build.targets` for projects that use the .NET SDK, but other projects would still need MSBuild to import `Directory.Build.targets` | ||
| - The new behavior would need to be behind a change wave and ideally a separate opt-out flag | ||
| - This goes against the original intent behind `Directory.Build.targets`, which was that it would be imported after all built-in targets. However, the .NET SDK (or any MSBuild SDK) already break this. | ||
| - As part of this work we could possibly add another extension point that allows you to specify `.targets` files that are imported after all other projects or imports. This would likely be an MSBuild engine feature. |
There was a problem hiding this comment.
It would be good if you could state a preference from your team as you're the experts.
|
Have we evaluated how this would impact some of our repos? Basically will it cause us to change? I think that would be instructive for understanding the potential scope of the change for customers. |
Co-authored-by: Immo Landwerth <immo@landwerth.net>
|
|
||
| Conceptually, `Directory.Build.targets` is imported after the body of the main project file. The exact location it is imported is not something most developers likely think about, but it is a good place to put common build logic that depends on properties set in the project file, such as the `TargetFramework`. | ||
|
|
||
| There's not a perfect place to import `Directory.Build.targets`. However, given what we've learned, it may be that the best place to import it is after the TargetFramework parsing, and before the workloads are imported. That way the logic in `Directory.Build.targets` would still be able to depend on the parsed TargetFramework information, but would not be able to override all of the targets and properties set by the .NET SDK and MSBuild common targets that it can today. |
There was a problem hiding this comment.
Would it be at all possible to give users a bit more control over shimming each of these stages? E.g. in addition to Directory.Build.targets, maybe also Directory.Build.AfterSdks.targets and Directory.Build.BeforeSdk.targets. Sure, you'll still probably break things when you change things around, but then at least users that relied on the order would have a destination to move their definitions to.
There was a problem hiding this comment.
Also, very related to ordering, is there any chance that msbuild might eventually support lazily-evaluated properties? A large minority of the build ordering issues I help peers with revolves around reading properties too early (e.g. trying to read OutputPath in Directory.Build.props). Being able to set these using lazy evaluation (e.g. like gnu make = vs :=) in these cases would resolve a few issues. Admittedly, would create its own issues too, but worth a thought here.
|
|
||
| ### Change import location of `Directory.Build.targets` | ||
|
|
||
| Change`Directory.Build.targets` to be imported after TargetFramework parsing but before workloads and most of the .NET SDK and common targets. This would be a big breaking change but might not affect most people who use `Directory.Build.targets`. It would break people who use `Directory.Build.targets` to override properties or targets in the MSBuild common targets. |
There was a problem hiding this comment.
Do we have a list of which targets would be affected here? (Alternatively, a link to the files, so we could check if this affected any of our use cases?)
dc944db to
fdacd18
Compare
|
|
||
| ## Background | ||
|
|
||
| To support .NET SDK workloads, we [changed the order of targets imports](https://github.com/dotnet/sdk/pull/14393) to allow SDK workloads to change property defaults. When we did this, we also changed the import order of some Windows and WPF targets, as we want to make it a workload in the future, which caused a breaking change. It appears that it is not possible to allow workloads to change property defaults and make support for Windows a .NET SDK workload without introducing a breaking change. As a result, this document explores possible solutions to minimize the user impact. |
There was a problem hiding this comment.
Did you mean "Windows Forms and WPF"?
| To support .NET SDK workloads, we [changed the order of targets imports](https://github.com/dotnet/sdk/pull/14393) to allow SDK workloads to change property defaults. When we did this, we also changed the import order of some Windows and WPF targets, as we want to make it a workload in the future, which caused a breaking change. It appears that it is not possible to allow workloads to change property defaults and make support for Windows a .NET SDK workload without introducing a breaking change. As a result, this document explores possible solutions to minimize the user impact. | |
| To support .NET SDK workloads, we [changed the order of targets imports](https://github.com/dotnet/sdk/pull/14393) to allow SDK workloads to change property defaults. When we did this, we also changed the import order of some Windows Forms and WPF targets, as we want to make it a workload in the future, which caused a breaking change. It appears that it is not possible to allow workloads to change property defaults and make support for Windows a .NET SDK workload without introducing a breaking change. As a result, this document explores possible solutions to minimize the user impact. |
|
|
||
| ### Extension Point via Property | ||
|
|
||
| Support an `AfterTargetFrameworkInferenceTargets` property. This property could be used by creating a `Directory.AfterTargetFrameworkInference.targets` file and putting the following in the `Directory.Build.props` file located in the same folder: |
There was a problem hiding this comment.
If it is to accommodate workloads, why not introduce something like Workload.Build.props and Workload.Build.targets?
|
|
||
| #### Cons | ||
|
|
||
| - This would be a breaking change, possibly a very big one |
|
|
||
| #### MSBuild Evaluation | ||
|
|
||
| We are primarily concerned with "[Pass 1](https://github.com/dotnet/msbuild/blob/6f9e0d620718578aab8dafc439d4501339fa4810/src/Build/Evaluation/Evaluator.cs#L613)" of [MSBuild Evaluation](https://docs.microsoft.com/en-us/visualstudio/msbuild/build-process-overview#evaluation-phase), where properties are evaluated and project imports are loaded. |
There was a problem hiding this comment.
| We are primarily concerned with "[Pass 1](https://github.com/dotnet/msbuild/blob/6f9e0d620718578aab8dafc439d4501339fa4810/src/Build/Evaluation/Evaluator.cs#L613)" of [MSBuild Evaluation](https://docs.microsoft.com/en-us/visualstudio/msbuild/build-process-overview#evaluation-phase), where properties are evaluated and project imports are loaded. | |
| We are primarily concerned with "[Pass 1](https://github.com/dotnet/msbuild/blob/6f9e0d620718578aab8dafc439d4501339fa4810/src/Build/Evaluation/Evaluator.cs#L613)" of [MSBuild Evaluation](https://docs.microsoft.com/visualstudio/msbuild/build-process-overview#evaluation-phase), where properties are evaluated and project imports are loaded. |
ditto below
No description provided.