Itens do MSBuild

Itens do MSBuild são entradas no sistema de build e eles normalmente representam arquivos (os arquivos estão especificados no atributo Include). Os itens são agrupados em tipos de item com base em seus nomes de elemento. Os tipos de item são listas nomeadas de itens que podem ser usados como parâmetros para tarefas. As tarefas usam os valores do item para executar as etapas do processo de build.

Como os itens são nomeados pelo tipo de item ao qual pertencem, os termos “item” e “valor de item” podem ser usados alternadamente.

Criar itens em um arquivo de projeto

Os itens são declarados no arquivo de projeto como elementos filho de um elemento ItemGroup. Os nomes de item válidos começam com uma letra maiúscula ou minúscula ou sublinhado (_); os caracteres subsequentes válidos incluem caracteres alfanuméricos (letras ou dígitos), sublinhado e hífen (-). O nome do elemento filho é o tipo do item. O atributo Include do elemento especifica os itens (arquivos) a serem incluídos com esse tipo de item. Por exemplo, o XML a seguir cria um tipo de item chamado Compile, que inclui dois arquivos.

<ItemGroup>
    <Compile Include = "file1.cs"/>
    <Compile Include = "file2.cs"/>
</ItemGroup>

O item file2.cs não substitui o item file1.cs; em vez disso, o nome de arquivo é acrescentado à lista de valores do tipo de item Compile.

O XML a seguir cria o mesmo tipo de item declarando os dois arquivos em um atributo Include. Observe que os nomes de arquivo são separados por ponto e vírgula.

<ItemGroup>
    <Compile Include = "file1.cs;file2.cs"/>
</ItemGroup>

O atributo Include é um caminho interpretado em relação à pasta do arquivo de projeto, $(MSBuildProjectPath), mesmo que o item esteja em um arquivo importado, como um arquivo .targets.

Criar itens durante a execução

Os itens que estão fora dos elementos de destino são valores designados durante a fase de avaliação de um build. Durante a fase de execução subsequente, os itens podem ser criados ou modificados das seguintes maneiras:

  • Qualquer tarefa pode emitir um item. Para emitir um item, o elemento Task deve ter um elemento filho Output que tem um atributo ItemName.

  • A tarefa CreateItem pode emitir um item. Esse uso é preterido.

  • Os elementos Target podem conter elementos ItemGroup que podem conter elementos de item.

Referenciar itens em um arquivo de projeto

Para referenciar tipos de item em todo o arquivo de projeto, use a sintaxe @(ItemType). Por exemplo, você faria referência no tipo de item no exemplo anterior usando @(Compile). Usando esta sintaxe, você pode passar itens para tarefas, especificando o tipo de item como um parâmetro dessa tarefa. Para obter mais informações, confira Como selecionar os arquivos a serem compilados.

Por padrão, os itens de um tipo de item são separados por ponto e vírgula (;) quando são expandidos. Use a sintaxe @(ItemType, 'separator') para especificar um separador diferente do padrão. Para obter mais informações, confira Como exibir uma lista de itens separada por vírgulas.

Usar curingas para especificar itens

Você pode usar os caracteres curinga **, * e ? para especificar um grupo de arquivos como entradas para um build em vez de listar cada arquivo separadamente.

  • O caractere curinga ? corresponde a um único caractere.
  • O caractere curinga * corresponde a zero ou mais caracteres.
  • A sequência de caracteres curinga ** corresponde a um caminho parcial.

Por exemplo, você pode especificar todos os arquivos .cs no diretório que contém o arquivo de projeto usando o elemento a seguir no arquivo de projeto.

<CSFile Include="*.cs"/>

O seguinte elemento seleciona todos os arquivos .vb na unidade D::

<VBFile Include="D:/**/*.vb"/>

Para incluir caracteres literais * ou ? em um item sem expansão de curinga, você deve usar o escape para os caracteres curinga.

Para obter mais informações sobre caracteres curinga, confira Como selecionar os arquivos a serem compilados.

Usar o atributo Exclude

Os elementos de item podem conter o atributo Exclude, que exclui itens específicos (arquivos) do tipo de item. O atributo Exclude normalmente é usado junto com caracteres curinga. Por exemplo, o XML a seguir adiciona cada arquivo .cs no diretório ao tipo de item CSFile, exceto o arquivo DoNotBuild.cs.

<ItemGroup>
    <CSFile  Include="*.cs"  Exclude="DoNotBuild.cs"/>
</ItemGroup>

O atributo Exclude afeta somente os itens adicionados pelo atributo Include no elemento do item que contém ambos. O exemplo a seguir não exclui o arquivo Form1.cs, que foi adicionado no elemento de item anterior.

<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">

Para obter mais informações, confira Como excluir arquivos do build.

Metadados do item

Os itens que podem conter metadados, além das informações nos atributos Include e Exclude. Esses metadados podem ser usados por tarefas que exigem mais informações sobre os itens ou para os destinos e tarefas de lote. Para obter mais informações, consulte Envio em lote.

Os metadados são uma coleção de pares chave-valor que são declarados no arquivo de projeto como elementos filho de um elemento do item. O nome do elemento filho é o nome dos metadados e o valor do elemento filho é o valor dos metadados.

Os metadados são associados ao elemento do item que os contém. Por exemplo, o XML a seguir adiciona metadados Culture que têm o valor Fr aos itens one.cs e two.cs do tipo de item CSFile.

<ItemGroup>
    <CSFile Include="one.cs;two.cs">
        <Culture>Fr</Culture>
    </CSFile>
</ItemGroup>

Um item pode ter zero ou mais valores de metadados. Você pode alterar os valores de metadados a qualquer momento. Se definir metadados para um valor vazio, você efetivamente vai removê-lo do build.

Referenciar metadados de item em um arquivo de projeto

Você pode fazer referência a metadados de item em todo o arquivo de projeto usando a sintaxe %(ItemMetadataName). Se existir a ambiguidade, você poderá qualificar uma referência usando o nome do tipo de item. Por exemplo, você pode especificar %(ItemType.ItemMetaDataName). O exemplo a seguir usa os metadados Display para colocar em lote a tarefa Message. Para obter mais informações sobre como usar os metadados de item para o envio em lote, confira Metadados de item no envio de tarefas em lote.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Stuff Include="One.cs" >
            <Display>false</Display>
        </Stuff>
        <Stuff Include="Two.cs">
            <Display>true</Display>
        </Stuff>
    </ItemGroup>
    <Target Name="Batching">
        <Message Text="@(Stuff)" Condition=" '%(Display)' == 'true' "/>
    </Target>
</Project>

Metadados de itens conhecidos

Sempre que um item é adicionado a um tipo de item, esse item é atribuído a alguns metadados conhecidos. Por exemplo, todos os itens que têm metadados %(Filename) conhecidos, cujo valor é o nome de arquivo do item (sem a extensão). Para obter mais informações, confira Metadados de item conhecidos.

Transformar os tipos de item usando metadados

Você pode transformar listas de itens em novas listas de item usando metadados. Por exemplo, você pode transformar um tipo de item CppFiles que tem itens que representam arquivos .cpp em uma lista correspondente de arquivos .obj usando a expressão @(CppFiles -> '%(Filename).obj').

O código a seguir cria um tipo de item CultureResource que contém cópias de todos os itens EmbeddedResource com metadados Culture. O valor de metadados Culture se torna o valor dos novos metadados CultureResource.TargetDirectory.

<Target Name="ProcessCultureResources">
    <ItemGroup>
        <CultureResource Include="@(EmbeddedResource)"
            Condition="'%(EmbeddedResource.Culture)' != ''">
            <TargetDirectory>%(EmbeddedResource.Culture) </TargetDirectory>
        </CultureResource>
    </ItemGroup>
</Target>

Para conhecer mais operações em itens, consulte Transformações e funções de item do MSBuild.

Definições de item

Você pode adicionar metadados padrão a qualquer tipo de item usando o elemento ItemDefinitionGroup. Como metadados conhecidos, os metadados padrão estão associados a todos os itens do tipo de item especificado. Você pode substituir explicitamente metadados padrão em uma definição de item. Por exemplo, o XML a seguir fornece aos itens Compileone.cs e three.cs os metadados BuildDay com o valor "Monday". O código fornece ao item two.cs os metadados BuildDay com o valor "Tuesday".

<ItemDefinitionGroup>
    <Compile>
        <BuildDay>Monday</BuildDay>
    </Compile>
</ItemDefinitionGroup>
<ItemGroup>
    <Compile Include="one.cs;three.cs" />
    <Compile Include="two.cs">
        <BuildDay>Tuesday</BuildDay>
    </Compile>
</ItemGroup>

Para obter mais informações, confira Definições de item.

Atributos de itens em um ItemGroup de um Target

Os elementos Target podem conter elementos ItemGroup que podem conter elementos de item. Os atributos nesta seção são válidos quando são especificados para um item em um ItemGroup que é um Target.

Remover atributo

O atributo Remove remove itens específicos (arquivos) do tipo de item. Esse atributo foi introduzido no .NET Framework 3.5 (somente dentro de destinos). Há suporte para destinos internos e externos a partir do MSBuild 15.0.

O exemplo a seguir remove todos os arquivos .config do tipo de item Compile.

<Target>
    <ItemGroup>
        <Compile Remove="*.config"/>
    </ItemGroup>
</Target>

Atributo MatchOnMetadata

O atributo MatchOnMetadata é aplicável somente a atributos Remove que fazem referência a outros itens (por exemplo, Remove="@(Compile);@(Content)") e instrui a operação Remove a corresponder itens com base nos valores dos nomes de metadados especificados, em vez de corresponder com base nos valores do item.

Regra de correspondência para B Remove="@(A)" MatchOnMetadata="M": remova todos os itens de B que tenham metadados M, cujo valor de metadados V para M corresponda a qualquer item de A com metadados M de valor V.

<Project>
  <ItemGroup>
    <A Include='a1' M1='1' M2='a' M3="e"/>
    <A Include='b1' M1='2' M2='x' M3="f"/>
    <A Include='c1' M1='3' M2='y' M3="g"/>
    <A Include='d1' M1='4' M2='b' M3="h"/>

    <B Include='a2' M1='x' m2='c' M3="m"/>
    <B Include='b2' M1='2' m2='x' M3="n"/>
    <B Include='c2' M1='2' m2='x' M3="o"/>
    <B Include='d2' M1='3' m2='y' M3="p"/>
    <B Include='e2' M1='3' m2='Y' M3="p"/>
    <B Include='f2' M1='4'        M3="r"/>
    <B Include='g2'               M3="s"/>

    <B Remove='@(A)' MatchOnMetadata='M1;M2'/>
  </ItemGroup>

  <Target Name="PrintEvaluation">
    <Message Text="%(B.Identity) M1='%(B.M1)' M2='%(B.M2)' M3='%(B.M3)'" />
  </Target>
</Project>

No exemplo, os valores de item b2, c2 e d2 são removidos do item B porque:

  • b2 e c2 de B correspondem a b1 de A em M1=2 e em M2=x
  • d2 de B correspondem a c1 de A em M1=3 e em M2=y

A tarefa Message gera o seguinte:

  a2 M1='x' M2='c' M3='m'
  e2 M1='3' M2='Y' M3='p'
  f2 M1='4' M2='' M3='r'
  g2 M1='' M2='' M3='s'

Exemplo de uso do MatchOnMetadata do MSBuild:

      <_TransitiveItemsToCopyToOutputDirectory Remove="@(_ThisProjectItemsToCopyToOutputDirectory)" MatchOnMetadata="TargetPath" MatchOnMetadataOptions="PathLike" />

Esta linha remove itens de _TransitiveItemsToCopyToOutputDirectory que têm os mesmos valores de metadados TargetPath de itens em _ThisProjectItemsToCopyToOutputDirectory

Atributo MatchOnMetadataOptions

Especifica a estratégia de correspondência de cadeia de caracteres usada por MatchOnMetadata para corresponder os valores de metadados entre itens (a correspondência dos nomes de metadados é sempre feita sem diferenciar maiúsculas de minúsculas). Os valores possíveis são CaseSensitive, CaseInsensitive, ou PathLike. O valor padrão é CaseSensitive.

PathLike aplica a normalização com reconhecimento de caminho aos valores como normalizar orientações de barra, ignorar barras à direita, eliminar . e .. e tornar todos os caminhos relativos absolutos em relação ao diretório atual.

Atributo KeepMetadata

Se um item for gerado em um destino, o elemento de item poderá conter o atributo KeepMetadata. Se esse atributo for especificado, apenas os metadados que serão especificados na lista de nomes separados por ponto-e-vírgula serão transferidos do item de origem para o item de destino. Um valor vazio para esse atributo é equivalente a não especificação dele. O atributo KeepMetadata foi introduzido no .NET Framework 4.5.

O exemplo a seguir mostra como usar o atributo KeepMetadata.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0">

    <ItemGroup>
        <FirstItem Include="rhinoceros">
            <Class>mammal</Class>
            <Size>large</Size>
        </FirstItem>

    </ItemGroup>
    <Target Name="MyTarget">
        <ItemGroup>
            <SecondItem Include="@(FirstItem)" KeepMetadata="Class" />
        </ItemGroup>

        <Message Text="FirstItem: %(FirstItem.Identity)" />
        <Message Text="  Class: %(FirstItem.Class)" />
        <Message Text="  Size:  %(FirstItem.Size)"  />

        <Message Text="SecondItem: %(SecondItem.Identity)" />
        <Message Text="  Class: %(SecondItem.Class)" />
        <Message Text="  Size:  %(SecondItem.Size)"  />
    </Target>
</Project>

<!--
Output:
  FirstItem: rhinoceros
    Class: mammal
    Size:  large
  SecondItem: rhinoceros
    Class: mammal
    Size:
-->

Atributo RemoveMetadata

Se um item for gerado em um destino, o elemento de item poderá conter o atributo RemoveMetadata. Se esse atributo for especificado, todos os metadados serão transferidos do item de origem para o item de destino, exceto os metadados cujos nomes estão contidos na lista de nomes separados por ponto-e-vírgula. Um valor vazio para esse atributo é equivalente a não especificação dele. O atributo RemoveMetadata foi introduzido no .NET Framework 4.5.

O exemplo a seguir mostra como usar o atributo RemoveMetadata.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <MetadataToRemove>Size;Material</MetadataToRemove>
    </PropertyGroup>

    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
    </ItemGroup>

    <Target Name="MyTarget">
        <ItemGroup>
            <Item2 Include="@(Item1)" RemoveMetadata="$(MetadataToRemove)" />
        </ItemGroup>

        <Message Text="Item1: %(Item1.Identity)" />
        <Message Text="  Size:     %(Item1.Size)" />
        <Message Text="  Color:    %(Item1.Color)" />
        <Message Text="  Material: %(Item1.Material)" />
        <Message Text="Item2: %(Item2.Identity)" />
        <Message Text="  Size:     %(Item2.Size)" />
        <Message Text="  Color:    %(Item2.Color)" />
        <Message Text="  Material: %(Item2.Material)" />
    </Target>
</Project>

<!--
Output:
  Item1: stapler
    Size:     medium
    Color:    black
    Material: plastic
  Item2: stapler
    Size:
    Color:    black
    Material:
-->

Para obter mais operações sobre itens, consulte Funções de item do MSBuild.

Atributo KeepDuplicates

Se um item for gerado em um destino, o elemento de item poderá conter o atributo KeepDuplicates. KeepDuplicates é um atributo Boolean que especifica se um item deverá ser adicionado ao grupo de destino se for uma duplicata exata de um item existente.

Se o item de origem e de destino tiverem o mesmo valor Include, mas metadados diferentes, o item será adicionado mesmo se KeepDuplicates estiver definido como false. Um valor vazio para esse atributo é equivalente a não especificação dele. O atributo KeepDuplicates foi introduzido no .NET Framework 4.5.

O exemplo a seguir mostra como usar o atributo KeepDuplicates.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <ItemGroup>
        <Item1 Include="hourglass;boomerang" />
        <Item2 Include="hourglass;boomerang" />
    </ItemGroup>

    <Target Name="MyTarget">
        <ItemGroup>
            <Item1 Include="hourglass" KeepDuplicates="false" />
            <Item2 Include="hourglass" />
        </ItemGroup>

        <Message Text="Item1: @(Item1)" />
        <Message Text="  %(Item1.Identity)  Count: @(Item1->Count())" />
        <Message Text="Item2: @(Item2)" />
        <Message Text="  %(Item2.Identity)  Count: @(Item2->Count())" />
    </Target>
</Project>

<!--
Output:
  Item1: hourglass;boomerang
    hourglass  Count: 1
    boomerang  Count: 1
  Item2: hourglass;boomerang;hourglass
    hourglass  Count: 2
    boomerang  Count: 1
-->

Como o atributo KeepDuplicates considera os metadados de itens além dos valores de item, é importante saber o que está acontecendo com os metadados. Por exemplo, consulte Detectar duplicatas ao usar a função de item de metadados.

Atualizar metadados em itens em um ItemGroup fora de um Destino

Itens fora dos destinos podem ter seus metadados existentes atualizados por meio do atributo Update. Esse atributo não está disponível para itens em destinos.

<Project>
    <PropertyGroup>
        <MetadataToUpdate>pencil</MetadataToUpdate>
    </PropertyGroup>

    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
        <Item1 Include="pencil">
            <Size>small</Size>
            <Color>yellow</Color>
            <Material>wood</Material>
        </Item1>
        <Item1 Include="eraser">
            <Color>red</Color>
        </Item1>
        <Item1 Include="notebook">
            <Size>large</Size>
            <Color>white</Color>
            <Material>paper</Material>
        </Item1>

        <Item2 Include="notebook">
            <Size>SMALL</Size>
            <Color>YELLOW</Color>
        </Item2>

        <!-- Metadata can be expressed either as attributes or as elements -->
        <Item1 Update="$(MetadataToUpdate);stapler;er*r;@(Item2)" Price="10" Material="">
            <Color>RED</Color>
        </Item1>
    </ItemGroup>

    <Target Name="MyTarget">
        <Message Text="Item1: %(Item1.Identity)
    Size: %(Item1.Size)
    Color: %(Item1.Color)
    Material: %(Item1.Material)
    Price: %(Item1.Price)" />
    </Target>
</Project>

<!--  
Item1: stapler
    Size: medium
    Color: RED
    Material:
    Price: 10
Item1: pencil
    Size: small
    Color: RED
    Material:
    Price: 10
Item1: eraser
    Size:
    Color: RED
    Material:
    Price: 10
Item1: notebook
    Size: large
    Color: RED
    Material:
    Price: 10
-->

No MSBuild versão 16.6 e posterior, o atributo Update dá suporte a referências de metadados qualificados para facilitar a importação de metadados de dois ou mais itens.

<Project>
    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
        <Item1 Include="pencil">
            <Size>small</Size>
            <Color>yellow</Color>
            <Material>wood</Material>
        </Item1>
        <Item1 Include="eraser">
            <Size>small</Size>
            <Color>red</Color>
            <Material>gum</Material>
        </Item1>
        <Item1 Include="notebook">
            <Size>large</Size>
            <Color>white</Color>
            <Material>paper</Material>
        </Item1>

        <Item2 Include="pencil">
            <Size>MEDIUM</Size>
            <Color>RED</Color>
            <Material>PLASTIC</Material>
            <Price>10</Price>
        </Item2>

        <Item3 Include="notebook">
            <Size>SMALL</Size>
            <Color>BLUE</Color>
            <Price>20</Price>
        </Item3>

        <!-- Metadata can be expressed either as attributes or as elements -->
        <Item1 Update="@(Item2);er*r;@(Item3)" Size="%(Size)" Color="%(Item2.Color)" Price="%(Item3.Price)" Model="2020">
            <Material Condition="'%(Item2.Material)' != ''">Premium %(Item2.Material)</Material>
        </Item1>
    </ItemGroup>

    <Target Name="MyTarget">
        <Message Text="Item1: %(Item1.Identity)
    Size: %(Item1.Size)
    Color: %(Item1.Color)
    Material: %(Item1.Material)
    Price: %(Item1.Price)
    Model: %(Item1.Model)" />
    </Target>
</Project>

<!--  
Item1: stapler
    Size: medium
    Color: black
    Material: plastic
    Price:
    Model:
Item1: pencil
    Size: small
    Color: RED
    Material: Premium PLASTIC
    Price:
    Model: 2020
Item1: eraser
    Size: small
    Color:
    Material: gum
    Price:
    Model: 2020
Item1: notebook
    Size: large
    Color:
    Material: paper
    Price: 20
    Model: 2020
-->

Comentários:

  • Os metadados não qualificados (%(MetadataName)) são associados ao tipo de item que está sendo atualizado (Item1 no exemplo acima). Os metadados qualificados (%(Item2.Color)) são associados dentro do conjunto de tipos de item correspondentes capturados na expressão Update.
  • Se um item corresponder várias vezes dentro e entre vários itens referenciados:
    • A última ocorrência de cada tipo de item referenciado será capturada (portanto, um item capturado por tipo de item).
    • Isso corresponde ao comportamento do envio em lote de itens de tarefa em destinos.
  • Em que é possível colocar referências %():
    • Metadados
    • Condições de metadados
  • A correspondência de nomes de metadados não diferencia maiúsculas de minúsculas.

Atualizar metadados em itens em um ItemGroup de um Destino

Os metadados também podem ser modificados dentro de destinos por uma sintaxe menos expressiva do que Update:

<Project>
    <ItemGroup>
        <Item1 Include="stapler">
            <Size>medium</Size>
            <Color>black</Color>
            <Material>plastic</Material>
        </Item1>
        <Item1 Include="pencil">
            <Size>small</Size>
            <Color>yellow</Color>
            <Material>wood</Material>
        </Item1>
        <Item1 Include="eraser">
            <Size>small</Size>
            <Color>red</Color>
            <Material>gum</Material>
        </Item1>
        <Item1 Include="notebook">
            <Size>large</Size>
            <Color>white</Color>
            <Material>paper</Material>
        </Item1>

        <Item2 Include="pencil">
            <Size>MEDIUM</Size>
            <Color>RED</Color>
            <Material>PLASTIC</Material>
            <Price>10</Price>
        </Item2>

        <Item2 Include="ruler">
            <Color>GREEN</Color>
        </Item2>

    </ItemGroup>

    <Target Name="MyTarget">
        <ItemGroup>
            <!-- Metadata can be expressed either as attributes or as elements -->
            <Item1 Size="GIGANTIC" Color="%(Item2.Color)">
                <Material Condition="'%(Item2.Material)' != ''">Premium %(Item2.Material)</Material>
            </Item1>
        </ItemGroup>

        <Message Text="Item1: %(Item1.Identity)
    Size: %(Item1.Size)
    Color: %(Item1.Color)
    Material: %(Item1.Material)
    Price: %(Item1.Price)
    Model: %(Item1.Model)" />
    </Target>
</Project>

<!--  
Item1: stapler
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
Item1: pencil
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
Item1: eraser
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
Item1: notebook
    Size: GIGANTIC
    Color: GREEN
    Material: Premium PLASTIC
    Price:
    Model:
-->