Double-Loop in msbuild?

前端 未结 4 968
闹比i
闹比i 2021-02-07 18:06

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


 
 

        
相关标签:
4条回答
  • 2021-02-07 18:34

    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>
    
    0 讨论(0)
  • 2021-02-07 18:55

    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>
    
    0 讨论(0)
  • 2021-02-07 18:58

    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).
    
    0 讨论(0)
  • 2021-02-07 19:01

    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)" />
    
    0 讨论(0)
提交回复
热议问题