Skip to content

Instantly share code, notes, and snippets.

@SingleAccretion
Last active September 18, 2025 19:02
Show Gist options
  • Select an option

  • Save SingleAccretion/672e8ddd7f1988d0d7a56688d03b9041 to your computer and use it in GitHub Desktop.

Select an option

Save SingleAccretion/672e8ddd7f1988d0d7a56688d03b9041 to your computer and use it in GitHub Desktop.
MSBuild target execution algorithm in pseudocode
void ExecuteTarget(Target tgt)
{
    // Each target only runs once during an MSBuild invocation.
    if (tgt.State == Executed)
        return;

    // Note how the condition is evaluated prior to running the depended-on targets.
    if (Evaluate(tgt.Condition))
    {
        // TODO: BeforeTargets of other targets are also in DependsOnTargets, but how are they ordered?
        foreach (Target dep in Evaluate(tgt.DependsOnTargets))
        {
            ExecuteTarget(dep);
        }

        if (InputsNewerThanOutputs(tgt, out inputs))
        {
            ExecuteTasks(tgt.Body, inputs);
        }
        else
        {
            // When a target is incrementally skipped, its changes to properties
            // and items are still effected. This is known as "output inference".
            ExecutePropertyAndItemGroups(tgt.Body);
        }
    }

    // TODO: when are AfterTargets evaluated and in what order?
    foreach (Target dep in tgt.TargetsReferencingThisTargetViaAfterTargets)
    {
        ExecuteTarget(dep);
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment