msbuild 中的双循环?

发布于 2024-10-14 00:18:54 字数 1155 浏览 4 评论 0原文

我正在为 msbuild 编写一个脚本,该脚本应该一步生成两批。
示例:2 个 ItemGroups

<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>
  <GroupOneStep>%(GroupOne.Identity)</GroupOneStep>
</PropertyGroup>
<Message Text="$(GroupOneStep) %(GroupTwo.Identity)" />

2 A   
2 B

任何提示吗?我要疯了。 :-(

PS:这是一篇关于该主题的博文 - 不幸的是它并不像那里所建议的那样工作: http:// /blogs.msdn.com/b/giuliov/archive/2010/04/30/gotcha-msbuild-nested-loops-double-batching.aspx

I'm writing a script for msbuild which should make two batches in one step.
Example: 2 ItemGroups

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

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

These two groups should be looped within each other:

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

I hoped that msbuild makes the result up of both batches giving

1 A  
2 A  
1 B  
2 B  

as result.
But that didn't happen. Instead, it returned the following useless crap:

1  
2  
  A  
  B  

Doing it the way the blog from the link below proposes (using a local propertygroup) like

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

makes

2 A   
2 B

Any hints? I'm going mad. :-(

PS: Here's a blogpost about the topic - unfortunately it doesn't work as propsed there:
http://blogs.msdn.com/b/giuliov/archive/2010/04/30/gotcha-msbuild-nested-loops-double-batching.aspx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

っ左 2024-10-21 00:18:54

对于两个嵌套循环,这是有效的:

<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).

For two nested loops this works:

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

Results in:

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).
陪我终i 2024-10-21 00:18:54

人们还可以使用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>

One can also make triple nested loops using the technique of 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>
亚希 2024-10-21 00:18:54

尝试使用组 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)" />

Try this to create a new ItemGroup using the identity from group 1 and assigning metadata to the new item group from the identity (or any other metadata) of group 2. Then use batching to iterate over the new group.

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

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

If you have more than two groups you can add CreateItem entries to merge the third group into _Group_Merged and then iterate over that combined group.

<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)" />
相思碎 2024-10-21 00:18:54

这是一个更简单的解决方案。

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

This is a much simpler solution.

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

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

Using an intermediate Item group Combined to create an intermediate item group that the Message task batches on.

If you reference two Item groups in the same task, Msbuild will batch
on them both separately. which is NOT what you want

If you have more ItemMetaData you'll need to handle that explicitly for the second ItemGroup, The ItemGroup included with the reference symbol @ automatically includes the ItemMetaData, so you'll just need to create the additional MetaData from the second group by referencing explicitly. Here's an example:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文