2012-10-20 52 views
17

我有一個Visual Studio 2012解決方案和十二個解決方案配置。每個解決方案配置都是獨立的(即每個配置的輸出完全不相關)。如何並行建立多個配置?

問題:我怎樣才能建立在一個步驟所有十二個配置,即通過在命令行上運行的單個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> 

不幸的是,雖然這確實建立所有十二個配置,它建立他們連續。我的猜測是,當MSBuild對要構建的一組項目執行依賴關係分析時,它確定它們都依賴於相同的解決方案文件,因此它決定不能並行構建它們。 (這只是一個猜測;我可能是完全錯誤的,我對MSBuild知之甚少)。

我也在構建時使用/ m開關。

+1

至於_why_這一點很重要:我可以從我的生成時間削減至少37%,如果我能得到這些版本並行運行。 (我通過從命令行自己運行12個msbuild實例來測試它,並在構建性能上看到了37%的增長--4:09與6:40相比,缺點是它打破了構建的統一日誌記錄;每個版本都會發布自己的日誌。) –

回答

20

利用MSBuild任務的BuildInParallel選項,並在一次調用中傳遞所有項目。這些例子here給出的基本方法:

<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> 
+0

是的,這項工作非常出色。謝謝,傑森。 –

+0

如果兩種配置都繼續執行另一項任務,是否可以將它嵌套在每個配置下,以便每個配置的下一個任務也可以並行執行?例如,它不會等待發布和調試完成,然後執行任務A進行發佈,然後執行任務A進行調試,但是隻要調試完成,啓動A即可進行調試,並且只要完成發佈,啓動A即可發佈? – paulm

+1

如果我正確理解你的問題:這種方法將兩個構建作爲完全獨立的操作開始。每一個都會盡快完成,兩者之間不會同步。想象一下你剛剛啓動了兩個控制檯窗口,並在每個窗口中鍵入了msbuild。 –

相關問題