Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Msbuild 如何并行构建多个配置?_Msbuild - Fatal编程技术网

Msbuild 如何并行构建多个配置?

Msbuild 如何并行构建多个配置?,msbuild,Msbuild,我有一个Visual Studio 2012解决方案,包含12种解决方案配置。每个解决方案配置都是独立的(即,每个配置的输出完全不相关) 问题:如何在一个步骤中构建所有12个配置,即通过在命令行上运行单个MSBuild命令,以及如何并行构建配置 例如,如果只有两种配置,Release/AnyCPU和Debug/AnyCPU,我希望这两种配置同时并行构建 为了完整性,以下是我尝试过的内容:;我还没有解决这个问题的办法 为了一次生成所有项目,我创建了一个新的项目文件,其中包含一个生成目标,该目标针

我有一个Visual Studio 2012解决方案,包含12种解决方案配置。每个解决方案配置都是独立的(即,每个配置的输出完全不相关)

问题:如何在一个步骤中构建所有12个配置,即通过在命令行上运行单个MSBuild命令,以及如何并行构建配置

例如,如果只有两种配置,Release/AnyCPU和Debug/AnyCPU,我希望这两种配置同时并行构建

为了完整性,以下是我尝试过的内容:;我还没有解决这个问题的办法


为了一次生成所有项目,我创建了一个新的项目文件,其中包含一个生成目标,该目标针对每个配置在解决方案文件上运行MSBuild任务:

<Target Name="Build">
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=Win32"     Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=x64"       Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=ARM"       Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=Win32" Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=x64"   Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=ARM"   Targets="$(BuildCommand)" />

  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=Win32"       Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=x64"         Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=ARM"         Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=Win32"   Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=x64"     Targets="$(BuildCommand)" />
  <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=ARM"     Targets="$(BuildCommand)" />
</Target>

这非常有效,只是每个MSBuild任务都是按顺序调用的,因此没有并行性(是的,每个配置生成中都有并行性,但我确实希望跨配置生成获得并行性)

为了使配置并行生成,我尝试使用MSBuild任务的BuildInParallel属性。我编写了一个预构建任务,为每个配置生成项目文件,然后尝试并行构建所有生成的项目:

<Target Name="PreBuild" Outputs="%(ProjectConfiguration.Identity)" Returns="%(BuildProject.Identity)">
  <Message Text="Cloning Solution for Configuration:  %(ProjectConfiguration.Identity)" />
  <PropertyGroup>
    <BuildProjectPath>$(IntPath)\%(ProjectConfiguration.Platform)\%(ProjectConfiguration.Configuration)\build.proj</BuildProjectPath>
  </PropertyGroup>
  <ItemGroup>
    <BuildProject Include="$(BuildProjectPath)" />
  </ItemGroup>
  <MakeDir Directories="$(IntPath)\%(ProjectConfiguration.Platform)\%(ProjectConfiguration.Configuration)" />
  <WriteLinesToFile
    File="$(BuildProjectPath)"
    Lines="&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;Project DefaultTargets='Build' ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
  &lt;Target Name='Build'&gt;
    &lt;MSBuild
      Projects='$(SlnPath)'
      Properties='
        SolutionDir=$(MSBuildProjectDirectory)\%3b
        Configuration=%(ProjectConfiguration.Configuration)%3b
        Platform=%(ProjectConfiguration.Platform)
      '
      Targets='$(BuildCommand)'
    /&gt;
  &lt;/Target&gt;
&lt;/Project&gt;"
    Overwrite="true" />

</Target>
<Target Name="Build" DependsOnTargets="PreBuild">
  <Message Text="%(BuildProject.Identity)" />
  <MSBuild Projects="%(BuildProject.Identity)" Properties="BuildCommand=$(BuildCommand)" BuildInParallel="true" />
</Target>

$(IntPath)\%(ProjectConfiguration.Platform)\%(ProjectConfiguration.Configuration)\build.proj
不幸的是,虽然这确实构建了所有12种配置,但它是串行构建的。我的猜测是,当MSBuild对要生成的一组项目执行依赖性分析时,它会确定它们都依赖于同一个解决方案文件,因此它决定它们不能并行生成。(这只是一个猜测;我可能完全错了。我对MSBuild知之甚少。)


我在构建时也使用/m开关。

利用MSBuild任务的BuildInParallel选项,在一次调用中传递所有项目。示例给出了基本方法:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <ProjectToBuild Include="a1.sln">
            <Properties>Configuration=Debug</Properties>
        </ProjectToBuild>
        <ProjectToBuild Include="a1.sln">
            <Properties>Configuration=Release</Properties>
        </ProjectToBuild>
    </ItemGroup>
    <Target Name="Build">
        <MSBuild Projects="@(ProjectToBuild)" BuildInParallel="true" />
    </Target>
</Project>

配置=调试
配置=发布

至于为什么这一点很重要:如果我能让构建并行运行,我至少可以减少37%的构建时间。(我通过自己从命令行运行12个msbuild实例进行了测试,发现构建性能提高了37%——4:09比6:40。其缺点是它破坏了构建的统一日志记录;每个构建都会发出自己的日志。)如果这两个配置都继续执行另一个任务,是否可以将其嵌套在每个配置下,以便每个配置的下一个任务也并行执行?例如,它不会等待发布和调试完成,然后执行任务A以进行发布,任务A以进行调试,而是在调试完成后立即启动任务A以进行调试,在发布完成后立即启动任务A以进行发布?如果我正确理解了您的问题:这种方法将两个构建作为完全独立的操作启动。每一个都将尽可能快地完成,两者之间没有同步。假设您刚刚启动了两个控制台窗口,并在每个窗口中键入了msbuild。因此,如果您希望仅在这些窗口已生成时执行另一个命令,则这是不可能的?当然,这是可能的…只需在生成目标中添加更多内容。但最好将此类查询作为新问题而不是无关问题中的注释来询问。