Every complex script contains a lot of items transformation steps.
Below, I would like describe one techique, that could be useful for MSBuild's script development.
Let's assume, that you need extract subset from items group with some condition.
Stardard solution could be something like this:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<ItemGroup>
<source Include="http://boost.org/download/boost-1.46.1.zip">
<tag>boost</tag>
</source>
<source Include="http://sourceforge.net/projects/loki-lib/files/Loki/Loki%200.1.7/loki-0.1.7.zip/download">
<tag>loki</tag>
</source>
</ItemGroup>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Target Name="Extract">
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<ItemGroup>
<item Condition="%(source.tag)==$(tag)" Include="@(source)"/>
</ItemGroup>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Message Text="Download: %(item.Identity)" />
</Target>
</Project>
You can specify item subset with value of 'tag' property.
As you can see, MSBuild's output shows only item with value equal 'boost' in the 'tag' property.
> msbuild extract.targets /p:tag=boost
Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.225]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 28.05.2011 16:10:16.
Project "D:\deployment\msi.targets" on node 1 (default targets).
Extract:
Download: http://boost.org/download/boost-1.46.1.zip
Done Building Project "D:\deployment\msi.targets" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.05
Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.225]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 28.05.2011 16:10:16.
Project "D:\deployment\msi.targets" on node 1 (default targets).
Extract:
Download: http://boost.org/download/boost-1.46.1.zip
Done Building Project "D:\deployment\msi.targets" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.05
The solution with indirect addressing is:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<ItemGroup>
<boost Include="http://boost.org/download/boost-1.46.1.zip"/>
<loki Include="http://sourceforge.net/projects/loki-lib/files/Loki/Loki%200.1.7/loki-0.1.7.zip/download"/>
</ItemGroup>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Target Name="Extract">
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<ItemGroup>
<item Include="@($(tag))"/>
</ItemGroup>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Message Text="Download: %(item.Identity)" />
</Target>
</Project>
The MSBuild's output is equal the previous.
The key element of the solution is usage "@($(tag))" expression inside 'Include' item's attribute.