documentation/Contributions/MSBuild-overview.md
MSBuild implements an actual language (... MSBuildian?). For syntax it uses XML. The XML elements and attributes represent keywords, variable names, and expressions in the language. The language is interpreted.
MSBuild has two data structures:
string foo in C#string[] foo in C#. Except that each array has a name called an item-type, and each element may not only have a value, but also have associated key-value pairs known as metadata.Typewise, everything is a string in MSBuild.
Executing logic is grouped in Targets. They are like functions in C#. Targets can contain a single type of statement, Tasks. Targets form dependencies between themselves and are executed via a stack, similar to stack based function execution in other languages.
Data structures (properties and items) can be declared either inside or outside targets. There is a single scope in MSBuild, you could call it the static scope. There's no automatic "target scopes". So if you declare a property or an item inside a target, it's still static and visible to the rest of the targets.
The parser, which produces the AST: ProjectParser. The AST top node is the ProjectRootElement
Interpretation happens in two big separate phases.
The first interpretation phase is called project evaluation. It's done by the msbuild Evaluator. The result of evaluation is an object tree similar (but different) to the symbol trees done by compilers. The semantic top nodes are ProjectInstance and Project. You can sort of think of the ProjectRootElement as the syntax API and the Project / ProjectInstance as the semantic API. The big difference in MSBuild is that ProjectInstance/Project also contain the actual interpretation results of MSBuild's state (properties and items) that sits outside targets.
Evaluation does not execute the targets in a project. It only interprets and stores the results of logic outside targets.
The second phase of msbuild interpretation is target execution. This happens in the TargetBuilder. The TargetBuilder uses a stack to execute targets. The initial state is the state contained inside a given ProjectInstance. So targets execute in a stack based manner and mutate the global state inside a ProjectInstance.
What's the difference between Project and ProjectInstance? While both represent evaluated projects, they are intended for different use cases. Project objects are specialized in introspecting / analyzing MSBuild code and also in providing high level project editing operations. ProjectInstance objects are read only. So the objects in the Project tree point back to their corresponding ProjectRootElement AST elements. The objects in the ProjectInstance tree do not point back to the ProjectRootElement elements (so they have a much smaller memory footprint). For example, the Project tree is used by Visual Studio to analyze msbuild projects, and to reflect UI changes all the way down to the XML elements. The TargetBuilder only works with the lighter weight ProjectInstance tree, since it only needs to read state.
Project / ProjectInstance: entrypoint APIs for working with MSBuild evaluations.BuildManager: entrypoint API for executing targets in MSBuild.
Build -> Build Solution)