Set Operations in MSBuild

by KodefuGuru 24. September 2008 19:13

There are scenarios where the situation calls for performing set operations on item collections. You may want to join them together, subtract one from another, or perform an inner join. I originally came up with the idea to demonstrate these from this forum question. These examples work in both MSBuild 2.0 and MSBuild 3.5. A 3.5 only version is included with the attachment to this article.

Set Up

Create an empty msbuild file. Add a default target that you will use to perform the set operations and display messages to show your results.

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <
ItemGroup>
        <
SetA Include="alpha;beta;gamma;delta"/>
        <
SetB Include="alpha;gamma;epsilon"/>
    </
ItemGroup>

    <
Target Name="Build">
    </
Target>        
</
Project>
Union All

Perhaps the easiest set operation is the Union All. This operation combines one collection with another, including duplicates. We only have to use the CreateItem including both sets. Add the following code inside your target to see this in action.

<CreateItem Include="@(SetA);@(SetB)" >
    <
Output TaskParameter="Include" ItemName="UnionAllSet"/>
</
CreateItem>

<
Message Text="Union All: @(UnionAllSet)"/>
Minus

The Minus operation works similar to the Union All operation. However, instead of including both sets, you include one set and exclude the other.

        <CreateItem Include="@(SetA)" Exclude="@(SetB)" >
            <
Output TaskParameter="Include" ItemName="MinusSet"/>
        </
CreateItem>

        <
Message Text="Minus: @(MinusSet)"/>
Intersect

Intersect only takes items that are in both collections. It starts to get tricky with this operation and in fact was the catalyst for this article. I attempted to perform this one using conditions, but nothing seemed to work. I finally realized I would have to perform multiple operations to get the desired intersection: take the first set and exclude the minus set.

<CreateItem Include="@(SetA)" Exclude="@(MinusSet)" >
    <
Output TaskParameter="Include" ItemName="IntersectSet"/>
</
CreateItem>

<
Message Text="Intersect: @(IntersectSet)"/>
Union

The Union operation pulls elements from both item collections. This is very similar to Union All except that it does not include duplicates. To accomplish this, take the UnionAllSet and exclude IntersectSet. Since this removes the original and duplicate items, add IntersectSet back to the results.

<CreateItem Include="@(UnionAllSet)" Exclude="@(IntersectSet)" >
    <
Output TaskParameter="Include" ItemName="UnionSet"/>
</
CreateItem>
<
CreateItem Include="@(IntersectSet)" >
    <
Output TaskParameter="Include" ItemName="UnionSet"/>
</
CreateItem>

<
Message Text="Union: @(UnionSet)"/>
Conclusion

These are basic examples of doing set operations in MSBuild. Combined with batching and transforms, there isn't much standing in the way of defining your item collections how you wish.

Be sure to download the samples below. It includes an MSBuild 3.5 version using the new, cleaner ItemGroup syntax.

MSBuildSetOperations.zip (1.12 kb)

Tags:

Build Ninja

Comments

9/24/2008 3:23:23 PM #

FreeToDev

Very nice post. Makes me wonder why I wrote tasks to do that!

FreeToDev United Kingdom

1/8/2009 12:46:16 AM #

Mat Roberts

Nice post.
Show the .net 3.5 examples too, there much cleaner

Mat Roberts

1/8/2009 4:42:05 AM #

Chris Eargle

I chose to put the version that works both in 2.0 and 3.5 in the main article so a wider audience could play with the concept.

Chris Eargle United States

5/27/2009 1:54:35 AM #

thatcom

In addition the MSBuild provides Properties and Items, which are conceptually equivalent to make's macros. Properties specify static values, whereas Items are usually used to define set of files/folder to perform Tasks upon. Specifying files on Items is made easy by the support of wildcards.

thatcom United States

5/27/2009 11:13:38 AM #

chris

It's more accurate to say that properties are like variables, and items are like collections.

chris United States

8/1/2009 1:47:51 AM #

Josh (ex. membership sites)

Thanks for giving examples. Most code is easier to use after seeing an example or two instead of just generic patterns.

Josh (ex. membership sites) United States

9/17/2009 12:39:10 PM #

JohnM

Very nice! Wish I had this list 2 years ago. Smile
You may want to add an operation for Disjoint Set though...

JohnM United States

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen

Whois KodefuGuru

Chris Eargle

Chris Eargle
.NET Community Champion

LinkedIn Twitter Technorati Facebook

MVP - Visual C#

 

INETA Community Champions
Friend of RedGate
Telerik .NET Ninja
Community blogs & blog posts

I am a #52er


World Map

RecentComments

Comment RSS

Tag cloud

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010