Building projects in parallel

Greetings MSBuilders!

Orcas MSBuild introduces a new feature allowing build authors to build projects in parallel. To enable this feature we have introduced a new parameter to the MSBuild task called “BuildInParallel” and a new command line parameter called “maxcpucount” or “m”. Note that if you do not set the “maxcpucount”, even though you set “BuildInParallel” parameter to true, your projects will be built serially.

Each MSBuild process (including the main or parent process started from command line) contains a component called the node. Projects are processed and built by the node component. Thus using “maxcpucount” of 2 will result in 2 MSBuild processes. If your projects have dependencies on other projects that are being built in parallel, then you will need to set appropriate project to project references so that dependent projects get built first. For instance in the below example (Example 1) if project d has a dependency on project c, building them in parallel could result in any of these projects being built first or both building concurrently. If project d got built first then your build would fail. In order to prevent this you will need to set up a project to project reference from project d to project c. Thus, if project d is built first, it will first follow the project to project reference and build project c, then it would build project d. Setting a project to project reference include invoking the MSBuild task to build the dependent project. Example 2 briefly demonstrates this.

The order at which the projects are built is dependent on the scheduling algorithm of MSBuild. You cannot assume any particular order.

Example 1:

a.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion=”3.5”>

<Target Name="default">

<MSBuild Projects="b.proj;c.proj;d.proj" BuildInParallel="true"/>

</Target>

</Project>

b.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion=”3.5”>

<Target Name="default">

<Message Text="Building project b"/>

</Target>

</Project>

c.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion=”3.5”>

<PropertyGroup>

<OutputType>DLL</OutputType>

<AssemblyName>c</AssemblyName>

</PropertyGroup>

<Target Name="default">

<Message Text="Building project c"/>

</Target>

</Project>

d.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion=”3.5”>

<PropertyGroup>

<OutputType>EXE</OutputType>

<AssemblyName>d</AssemblyName>

</PropertyGroup>

<ItemGroup>

<Reference Include=“c”/>

</ItemGroup>

<Target Name="default">

<Message Text="Building project d"/>

</Target>

</Project>

Command line: msbuild a.proj /m:2

In order to prevent the build from failing in case project c and project d build simultaneously we need to set up the following project to project reference

Example 2

c.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion=”3.5”>

<PropertyGroup>

<OutputType>DLL</OutputType>

<AssemblyName>c</AssemblyName>

</PropertyGroup>

<Target Name="default">

<Message Text="Building project c"/>

</Target>

</Project>

d.proj

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion=”3.5”>

<PropertyGroup>

<OutputType>EXE</OutputType>

<AssemblyName>d</AssemblyName>

</PropertyGroup>

<ItemGroup>

<ProjectReference Include=”c.proj”/>

</ItemGroup>

<Target Name="default" DependsOnTargets=”BuildProjectReferences”>

<Message Text="Building project d"/>

</Target>

<Target Name=" BuildProjectReferences ">

<MSBuild Projects=”@(ProjectReference)” />

</Target>

</Project>

[Author: Jay, MSBuild Software Engineer]