0

I'm trying to setup a MSBuild .proj file that can have multiple build configurations passed in as arguments and then have the configs built in parallel. This is an example of what I want to do:

msbuild MultiConfigBuild.proj /m:8 /ds /property:Config=Debug+Release;Platform=x64

I have got it building multiple configurations but I'm unable to get them to build in parallel even with BuildInParallel="true" and /m:8

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Rebuild" ToolsVersion="4.0">
    <ItemGroup>
        <ConfigList Condition=" '@(ConfigList)' == '' and $(Config) != '' " Include="$(Config.Split('+'))" /><!-- parse all requested configurations into a list -->
        <ConfigList Condition=" '@(ConfigList)' == '' " Include="Debug" /><!-- if no configurations were specified, default to Debug -->
    </ItemGroup>
    <!--

    Build the project for each requested configuration. -->
    <Target Name="Rebuild">
        <MSBuild Projects="$(MSBuildProjectDirectory)\Application.sln" Targets="Rebuild" Properties="Configuration=%(ConfigList.Identity);Platform=x64" BuildInParallel="true" />
    </Target>
</Project>

Using the above proj file and command line parameters I get this output for the node utilisation:

         ============================== Node Utilization (IDs represent configurations) ====================================================
         Timestamp:            1        Duration   Cumulative
         -----------------------------------------------------------------------------------------------------------------------------------
         636942946549229765:   0        0.201s     0.201s ####
         636942946551243522:   1        0.006s     0.207s
         636942946551303033:   2        0.354s     0.561s #######
         636942946554839510:   |        0.674s     1.235s #############
         636942946561575184:   |        0.048s     1.282s
         636942946562051339:   |        3.362s     4.645s ###################################################################
         636942946595675132:   |        0.508s     5.152s ##########
         636942946600754168:   1        0.001s     5.153s
         636942946600764083:   0        0.007s     5.160s
         636942946600833525:   3        0.002s     5.163s
         636942946600858339:   4        0.136s     5.299s ##
         636942946602217371:   |        0.420s     5.719s ########
         636942946606418477:   |        0.023s     5.742s
         636942946606651600:   |        2.443s     8.185s ################################################
         636942946631079558:   |        1.692s     9.877s #################################
         636942946648003047:   0        0.000s     9.878s
         -----------------------------------------------------------------------------------------------------------------------------------
         Utilization:          100.0    Average Utilization: 100.0

It's building the 2 configurations in serial on the same node.

I have tried the solution given in this question and that does build the configurations in parallel, but I was not able to set it up to parse multiple configs passed in as arguments.

1 Answers1

0

When you use the %(Item.Metadata) syntax you use item batching, which creates batches of similar metadata that are executed sequentially. So the MSBuild task is called 2 times.

Instead, you want to pass multiple projects to one MSBuild task which have different configuration. You can accomplish this by using batching to create an Item containing the project (/solution) file to build with additional metadata that the MSBuild task uses to set properties (AdditionalProperties) and then pass the set of these project items to a single MSBuild task:

<Target Name="Rebuild">
  <ItemGroup>
    <ProjectToBuild Include="$(MSBuildProjectDirectory)\Application.sln">
      <AdditionalProperties>Configuration=%(ConfigList.Identity)</AdditionalProperties>
    </ProjectToBuild>
  </ItemGroup>
  <MSBuild Projects="@(ProjectToBuild)" Targets="Rebuild" Properties="Platform=x64" BuildInParallel="true" />
</Target>
Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217
  • That works great, thanks. When the builds complete it gives a summary of all the warnings and errors for each build, there is no way to tell which config the errors came from since they all say "Application.sln" . Is there a way to add the config/platform to the summary? – Jordan Peck May 28 '19 at 10:11
  • I don't think so. For that i suggest creating binary logs using the `-bl` argument and looking at the resulting log using the [MSBuild Structured Log Viewer](http://msbuildlog.com/) – Martin Ullrich May 28 '19 at 10:28
  • Is there a way to override the intermediate path used for each msbuild configuration, some of the projects share the same configuration across multiple solution configurations. So when building in parallel it causes issues as they are both trying to use the same intermediate directory. – Jordan Peck May 29 '19 at 15:17
  • Setting IntermediateOutputPath in properties doesn't seem to have any effect. – Jordan Peck May 29 '19 at 15:26