Archive for the ‘MsBuild’ Category

MSBuild – More ways to generate a cross-product

Tuesday, March 16th, 20100 comments

I’ve been using MsBuild a lot over the last 6 months as the company I’ve been working with migrates from TFS to TeamCity/Subversion. One problem that arises is the need to join item collections. I found two ways to do this and decided to look around to see how other people have been handling this. Aaron Hallberg wrote about this a few years back and another example can be found here.

One example I’ve found to work is similar to the second example:

<Project DefaultTargets="PrintFooAndBar"
     xmlns="schemas.microsoft.com/developer/msbuild/2003" >

  <ItemGroup>
    <Foo Include="foo1">
      <FooMetadata>1</FooMetadata>
    </Foo>
    <Foo Include="foo2">
      <FooMetadata>2</FooMetadata>
    </Foo>
  </ItemGroup>

  <ItemGroup>
    <Bar Include="bar1">
      <BarMetadata>a</BarMetadata>
    </Bar>
    <Bar Include="bar2">
      <BarMetadata>b</BarMetadata>
    </Bar>
  </ItemGroup>

  <Target Name="Merge" Outputs=" %(Bar.Identity) ">
    <ItemGroup>
      <_Foo Include="@(Foo)">
        <BarMetadata>%(Bar.BarMetadata)</BarMetadata>
      </_Foo>
    </ItemGroup>
  </Target>

  <Target Name="PrintFooAndBar" DependsOnTargets="Merge">
    <Message Importance="high"
             Text="FooMetadata=%(_Foo.FooMetadata), BarMetadata=%(_Foo.BarMetadata)" />
  </Target>

</Project>

This produces the following output:

Project "E:\Projects\MsBuild\cross_product_1.build" on node 0 (default target(s)).
  FooMetadata=1, BarMetadata=a
  FooMetadata=2, BarMetadata=a
  FooMetadata=1, BarMetadata=b
  FooMetadata=2, BarMetadata=b
Done Building Project "E:\Projects\MsBuild\cross_product_1.build" (default target(s)).

The other example I’ve used is similar although it doesnโ€™t require an intermediate task to build a temporary list:

<Project DefaultTargets="PrintFooAndBar"
         xmlns="schemas.microsoft.com/developer/msbuild/2003" >

  <ItemGroup>
    <Foo Include="foo1">
      <FooMetadata>1</FooMetadata>
    </Foo>
    <Foo Include="foo2">
      <FooMetadata>2</FooMetadata>
    </Foo>
  </ItemGroup>

  <ItemGroup>
    <Bar Include="@(Foo)">
      <BarMetadata>a</BarMetadata>
    </Bar>
    <Bar Include="@(Foo)">
      <BarMetadata>b</BarMetadata>
    </Bar>
  </ItemGroup>

  <Target Name="PrintFooAndBar">
    <Message Importance="high"
             Text="FooMetadata=%(Bar.FooMetadata), BarMetadata=%(Bar.BarMetadata)" />
  </Target>

</Project>

Which produces the following output:

Project "E:\Projects\MsBuild\cross_product_2.build" on node 0 (default targets).
  FooMetadata=1, BarMetadata=a
  FooMetadata=2, BarMetadata=a
  FooMetadata=1, BarMetadata=b
  FooMetadata=2, BarMetadata=b
Done Building Project "E:\Projects\MsBuild\cross_product_2.build" (default targets).

Posted in MsBuild

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.