Noldorin
Noldorin

Reputation: 147471

MSBuild subtlety with item metadata?

Consider an item type FooItem in an MSBuild project.

In a task we can make references to items and their metadata such as:

%(FooItem.BarMetadata)

or

@(FooItem->'Metadata("BarMetadata")')

or

@(FooItem->'%(BarMetadata)')

Is there any difference between these three approaches, which seem identical to me? Obviously the transform syntax (->) is more powerful in general, but I've explicitly given a simple example equivalent to the use of the % operator, from what I can tell.

Furthermore, is there any effect on task batching here (presuming these expressions are within a task item)? In general, I'm wondering if there's any way to prevent task batching by metadata while still referring to some metadata in a task.

Upvotes: 1

Views: 587

Answers (1)

KMoraz
KMoraz

Reputation: 14164

There are not identical. The transform syntax appends the input to a semicolon-delimited Items array. The % notation adds the input to an ItemGroup Element.

Consider the following target:

<Target Name="TestMetadata">

  <ItemGroup>
    <Files Include="File1.doc">
      <Description>Word Document</Description>
    </Files>
    <Files Include="File2.xls">
      <Description>Excel Document</Description>
    </Files>
    <Files Include="File3.pps">
      <Description>PowerPoint Presentation</Description>
    </Files>
  </ItemGroup>

  <Message Text="Transform: @(Files->'%(FullPath) is %(Description)')" />
  <Message Text="Direct: %(Files.FullPath) is %(Files.Description)" />

</Target>

As the output shows, those notations produce different output:

TestMetadata:   
 Transform: C:\MSBuild\File1.doc is Word Document;C:\MSBuild\File2.xls is Excel Document;C:\\MSBuild\File3.pps is PowerPoint Presentation
Direct: C:\MSBuild\File1.doc is Word Document   
Direct: C:\MSBuild\File2.xls is Excel Document   
Direct: C:\MSBuild\File3.pps is PowerPoint Presentation

Upvotes: 3

Related Questions