2011-01-24 63 views
11

我正在爲msbuild寫一個腳本,它應該一步完成兩個批次。
實施例:2個ItemGroupsmsbuild中的雙循環?

<ItemGroup> 
<GroupOne Include="1" /> 
<GroupOne Include="2" /> 
</ItemGroup> 

<ItemGroup> 
<GroupTwo Include="A" /> 
<GroupTwo Include="B" /> 
</ItemGroup> 

這兩組應該內彼此成環:

<Message Text="%(GroupOne.Identity) %(GroupTwo.Identity)" /> 

我希望的msbuild使得結果最多兩個批次給

1 A 
2 A 
1 B 
2 B 

作爲結果。
但是沒有發生。相反,它返回以下沒用的廢物:

1 
2 
    A 
    B 

做這從下面的鏈接的博客中提出的方式(使用本地的PropertyGroup)像

<PropertyGroup> 
    <GroupOneStep>%(GroupOne.Identity)</GroupOneStep> 
</PropertyGroup> 
<Message Text="$(GroupOneStep) %(GroupTwo.Identity)" /> 

使得

2 A 
2 B 

任何提示?我瘋了。 :-(

PS:這裏有一個關於該主題的博文 - 不幸的是因爲propsed有它不工作: http://blogs.msdn.com/b/giuliov/archive/2010/04/30/gotcha-msbuild-nested-loops-double-batching.aspx

回答

11

試試這個使用從第1組的身份和到指定的元數據來創建一個新的ItemGroup從第2組的身份(或任何其他元數據)新的項目組,然後使用批處理遍歷新組。

<CreateItem Include="@(GroupOne)" AdditionalMetadata="Option1=%(GroupTwo.Identity)"> 
    <Output ItemName="_Group_Merged" TaskParameter="Include"/> 
</CreateItem> 

<Message Text="%(_Group_Merged.Identity)-%(_Group_Merged.Option1)" /> 

如果有兩個以上的組,您可以添加CreateItem條目合併第三組進入_Group_Merged,然後遍歷該組合組。

<CreateItem Include="@(_Group_Merged)" AdditionalMetadata="Option2=%(GroupThree.Identity)"> 
    <Output ItemName="_Group_Merged2" TaskParameter="Include"/> 
</CreateItem> 

<Message Text="%(_Group_Merged2.Identity)-%(_Group_Merged2.Option1)-%(_Group_Merged2.Option2)" /> 
+0

精靈!這樣可行! :-) – Sascha 2011-01-25 06:24:03

11

這是一個更簡單的解決方案。

<Target Name="Default"> 
    <ItemGroup> 
     <Combined Include="@(GroupOne)"> 
      <GroupTwo>%(GroupTwo.Identity)</GroupTwo> 
     </Combined> 
    </ItemGroup> 

    <Message Text="%(Combined.Identity) %(Combined.GroupTwo) " /> 
</Target> 

使用中間物料組Combined創建消息任務批處理的中間物料組。

如果您在同一個任務中引用兩個項目組,Msbuild將分別在它們上分批批量編寫 。這是不是你想要的

如果您有更多的ItemMetaData你需要處理,明確第二的ItemGroup,將包含的ItemGroup與參考符號@自動包括ItemMetaData,所以你只需要通過顯式引用從第二組創建額外的元數據。這裏有一個例子:

<ItemGroup> 
    <GroupOne Include="1"> 
     <Name>One</Name> 
    </GroupOne> 
    <GroupOne Include="2"> 
     <Name>Two</Name> 
    </GroupOne> 
</ItemGroup> 

<ItemGroup> 
    <GroupTwo Include="A"> 
     <Name>Andrew</Name> 
    </GroupTwo> 
    <GroupTwo Include="B"> 
     <Name>Bob</Name> 
    </GroupTwo> 
</ItemGroup> 

<Target Name="Default"> 
    <ItemGroup> 
     <Combined Include="@(GroupOne)"> 
      <GroupTwo>%(GroupTwo.Identity)</GroupTwo> 
      <GroupTwoName>%(GroupTwo.Name)</GroupTwoName> 
     </Combined> 
    </ItemGroup> 

    <Message Text="%(Combined.Identity) %(Combined.Name) %(Combined.GroupTwoName) %(Combined.GroupTwo) " /> 
</Target> 
4

你也可以使用Dog Ears技術使三重嵌套循環。

<Target Name="Test"> 
    <ItemGroup> 
     <Loop1 Include="L11" /> 
     <Loop1 Include="L12" /> 
     <Loop2 Include="L21" /> 
     <Loop2 Include="L22" /> 
     <Loop3 Include="L31" /> 
     <Loop3 Include="L32" /> 
     <Loop12 Include="@(Loop1)"> 
     <!-- Combine Loop1 and Loop2: Inherit each meta data of Loop1 and add some of Loop2. --> 
     <Loop2Identity>%(Loop2.Identity)</Loop2Identity> 
     </Loop12> 
     <Loop123 Include="@(Loop12)"> 
     <!-- Combine Loop12 and Loop3: Inherit each meta data of Loop12 and add some of Loop3. --> 
     <Loop3Identity>%(Loop3.Identity)</Loop3Identity> 
     </Loop123> 
    </ItemGroup> 
    <!-- Show all entries of Loop1 and Loop2 combined --> 
    <Message Text="Loop12.Identity=%(Loop12.Identity), Loop12.Value1=%(Loop12.Value1), Loop12.Loop2Identity=%(Loop12.Loop2Identity)"/> 
    <!-- Show all entries of Loop1, Loop2 and Loop3 combined --> 
    <Message Text="Loop123.Identity=%(Loop123.Identity), Loop123.Loop2Identity=%(Loop123.Loop2Identity) Loop123.Loop2Identity=%(Loop123.Loop3Identity)"/> 
    </Target> 
0

對於兩個嵌套循環工作原理:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <ItemGroup> 
     <GroupOne Include="1" /> 
     <GroupOne Include="2" /> 
    </ItemGroup> 

    <ItemGroup> 
     <GroupTwo Include="A" /> 
     <GroupTwo Include="B" /> 
    </ItemGroup> 

    <Target Name="Exec" 
     Outputs="%(GroupOne.Identity)"> 
     <Message Text="Building @(GroupOne->'%(Identity)') %(GroupTwo.Identity)"/> 
    </Target> 

</Project> 

結果:

Project "D:\tmp\msbuildtest\test.xml" on node 0 (default targets). 
    Building 1 A 
    Building 1 B 
Exec: 
    Building 2 A 
    Building 2 B 
Done Building Project "D:\tmp\msbuildtest\test.xml" (default targets).