Open KirillOsenkov opened 4 years ago
This gets complicated, because the reasonable mental model for how target dependencies work (a directed acyclic graph of targets with edges determined by DependsOnTargets
, BeforeTargets
, and AfterTargets
) is not how the actual dependencies are implemented, in user-observable (and user-manipulable) ways.
The real implementation is that targets are pushed and popped off a stack as their dependencies are considered. This results in the documented ordering rules for MSBuild targets.
The consequence of the stack-based implementation is that the logged data is completely accurate: exactly one target caused the target in question to be built, for exactly one reason.
That's not the full picture; when trying to understand builds it's completely reasonable to want to know "ok, but if that hadn't been there, what would have happened?". For instance, "is there another target that this target would have run after/before", or "what targets depend on this target?"
Unfortunately, the stack manipulations are dynamic, so simply logging the value of DependsOn
and friends at the end of evalution isn't sufficient; another target run a the right time can change a property and affect dependencies.
It might be possible to add a log event at the relevant target-stack transition points, like https://github.com/microsoft/msbuild/blob/9c33693c492a0cb99474dcb703bfd0947056d8a9/src/Build/BackEnd/Components/RequestBuilder/TargetBuilder.cs#L414-L416
and other calls to PushTargets
.
I think it'd have to be an entirely new log event, though, and possibly one per dependency type.
We might also be able to store the true expanded values of those attributes at the place I mentioned, then pass them along to the place that the current target-started event gets fired and add them to new fields there.
It would be nice to just have the expanded actual values for these attributes, just to see what they evaluated to.
I could add hyperlinks from a target to any of its DependsOnTargets, BeforeTargets or AfterTargets targets:
Not sure if this feature would address it, but sometimes I see a grayed out target and I don't understand why it wasn't executed. This doc: https://github.com/KirillOsenkov/MSBuildStructuredLog/wiki/Viewer-UI lists multiple possible reasons for a target to not log any messages. It would be really useful to know which of the reasons is it.
I wonder what's the best way to get the target graph information. Should this get logged during evaluation? We do log the ParentTarget here: https://github.com/microsoft/msbuild/blob/8eda0fac789ac3314a14bf002bd9b6e8ab382aca/src/Framework/TargetStartedEventArgs.cs#L165
But would be nice to get high fidelity information