-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
Description
This may be by design (see referenced issues below) but I found this very confusing, so wanted to make sure we have an issue for this specific problem.
Repro
<Project>
<Target Name="Build" DependsOnTargets="Work;Enable;Second" />
<Target Name="Work" Condition=" '$(Enabled)' == 'true' ">
<Message Importance="high" Text="1. Work ran" />
</Target>
<Target Name="Hook" AfterTargets="Work">
<Message Importance="high" Text="2. Hook ran" />
</Target>
<Target Name="Enable">
<PropertyGroup>
<Enabled>true</Enabled>
</PropertyGroup>
</Target>
<Target Name="Second" DependsOnTargets="Work" />
</Project>$ dotnet msbuild repro.proj -v:n
Expected: 1. Work ran before 2. Hook ran
Actual: 2. Hook ran before 1. Work ran
Hook fires on the first (Condition-false) invocation of Work, before Work has ever executed. When Work actually runs on the second invocation (after Enable sets the property), Hook does not fire again.
Analysis
Two documented behaviors interact to produce this:
- AfterTargets fires on skipped targets — "After the target is executed or skipped, any other target that lists it in an
AfterTargetsattribute is run." - Condition-skipped targets can re-run — "If a target is skipped because its
Conditionevaluates tofalse, it can still be executed if invoked later withConditiontrue."
The target gets a second chance, but its hooks don't.
This came up while investigating an incremental build issue in xamarin-android.
Related
- Targets hooked BeforeTargets a conditioned target run after instead #8788 —
BeforeTargetsordering wrong on Condition-false target (fixed) - Confusing and inconsistent behavior around
AfterTargets="Build"in referenced projects #11784 —AfterTargetsnot awaited by second caller in parallel builds (open)
Reactions are currently unavailable