John Gietzen
John Gietzen

Reputation: 49565

How can I merge two ItemGroups in MSBuild

I have two ItemGroups:

<ItemGroup>
    <Compile Include="A.cs" />
    <Compile Include="B.cs" />
    <Compile Include="C.cs" />
</ItemGroup>
<ItemGroup>
    <PEG Include="A.cs" />
    <PEG Include="Y.cs" />
    <PEG Include="Z.cs" />
</ItemGroup>

I need to do add each of the items in PEG to Compile IF AND ONLY IF that item is not AREADY in Compile.

Is there an easy way to do that?

My first attempt is something like:

<ItemGroup>
  <Compile Include="%(PEG.Identity)" Condition=" '$(Compile)' != '%(PEG.Identity)' " />
</ItemGroup>

But that doesn't work for obvious reasons. I don't really want to do a manual anti-join in MSBuild.

Perhaps using Exclude would work?

Upvotes: 0

Views: 2352

Answers (1)

John Gietzen
John Gietzen

Reputation: 49565

Alright, I figured it out.

The first thing I was doing wrong, was using $(Compile) rather than @(Compile).

Next, I was on the right track with the Exclude property.

Here is what I have come up with:

<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Compile">
  <ItemGroup>
    <Compile Include="A.cs" />
    <Compile Include="B.cs" />
    <Compile Include="C.cs" />
  </ItemGroup>
  <Target Name="Compile">
    <ItemGroup>
        <PEG Include="A" />
        <PEG Include="D" />
    </ItemGroup>
    <Message Text="Compile = @(Compile)" />
    <Message Text="PEG     = @(PEG)" />
    <ItemGroup>
        <Compile Include="%(PEG.Identity).cs" Exclude="@(Compile)" />
    </ItemGroup>
    <Message Text="Compile = @(Compile)" />
  </Target>
</Project>

After this is done, Compile contains A.cs;B.cs;C.cs;D.cs as desired.

Upvotes: 2

Related Questions