Transformações do MSBuild

Uma transformação é uma conversão individual de uma lista de itens para outra. Além de habilitar um projeto para converter as lista de itens, uma transformação permite que um destino identifique um mapeamento direto entre suas entradas e saídas. Este tópico explica as transformações e como o MSBuild as utiliza para compilar projetos com mais eficiência.

Modificadores de transformação

As transformações não são arbitrárias, mas são limitadas pela sintaxe especial na qual todos os modificadores de transformação devem estar no formato %(<ItemMetaDataName>). Quaisquer metadados de item podem ser usados como um modificador de transformação. Isso inclui os metadados de item bem conhecidos atribuídos a cada item criado. Para obter uma lista de metadados de item conhecidos, confira Metadados de itens conhecidos.

No exemplo a seguir, uma lista de arquivos .resx é transformada em uma lista de arquivos .resources. O modificador de transformação %(filename) especifica que cada arquivo .resources tem o mesmo nome de arquivo do que o arquivo .resx correspondente.

@(RESXFile->'%(filename).resources')

Por exemplo, se os itens na lista @(RESXFile) Form1.resx, Form2.resx e Form3.resx, as saídas na lista transformada serão Form1.resources, Form2.resources e Form3.resources.

Observação

Você pode especificar um separador personalizado para uma lista de itens transformados da mesma maneira que especifica um separador para uma lista de itens padrão. Por exemplo, para separar uma lista de itens transformados usando uma vírgula (,) em vez do ponto-e-vírgula (;) padrão, use o seguinte XML: @(RESXFile->'Toolset\%(filename)%(extension)', ',')

Uso de vários modificadores

Uma expressão de transformação pode conter vários modificadores, que podem ser combinados em qualquer ordem e podem ser repetidos. No exemplo a seguir, o nome do diretório que contém os arquivos é alterado, mas os arquivos de reter a extensão de nome de arquivo e de nome original.

@(RESXFile->'Toolset\%(filename)%(extension)')

Por exemplo, se os itens contidos na lista de itens RESXFile forem Project1\Form1.resx, Project1\Form2.resx e Project1\Form3.text, as saídas na lista transformada serão Toolset\Form1.resx, Toolset\Form2.resx e Toolset\Form3.text.

dependency analysis

Transformações garantem um mapeamento individual entre a lista de itens transformados e a lista do item original. Portanto, se um destino cria saídas que são transformações das entradas, o MSBuild pode analisar os carimbos de data/hora das entradas e saídas e decidir se deseja ignorar, compilar ou recompilar parcialmente um destino.

Na tarefa Copy no exemplo a seguir, todos os arquivos na lista de itens BuiltAssemblies são mapeados para um arquivo na pasta de destino da tarefa especificada usando uma transformação no atributo Outputs. Se um arquivo na lista de itens BuiltAssemblies for alterado, a tarefa Copy será executada somente para o arquivo alterado e todos os outros arquivos serão ignorados. Para saber mais sobre a análise de dependência e como usar transformações, confira Como compilar incrementalmente.

<Target Name="CopyOutputs"
    Inputs="@(BuiltAssemblies)"
    Outputs="@(BuiltAssemblies -> '$(OutputPath)%(Filename)%(Extension)')">

    <Copy
        SourceFiles="@(BuiltAssemblies)"
        DestinationFolder="$(OutputPath)"/>

</Target>

Exemplo

Descrição

O exemplo a seguir mostra um arquivo de projeto do MSBuild que usa transformações. Este exemplo supõe que haja apenas um arquivo .xsd no diretório c:\sub0\sub1\sub2\sub3 e o diretório de trabalho é c:\sub0.

Código

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Schema Include="sub1\**\*.xsd"/>
    </ItemGroup>

    <Target Name="Messages">
        <Message Text="rootdir: @(Schema->'%(rootdir)')"/>
        <Message Text="fullpath: @(Schema->'%(fullpath)')"/>
        <Message Text="rootdir + directory + filename + extension: @(Schema->'%(rootdir)%(directory)%(filename)%(extension)')"/>
        <Message Text="identity: @(Schema->'%(identity)')"/>
        <Message Text="filename: @(Schema->'%(filename)')"/>
        <Message Text="directory: @(Schema->'%(directory)')"/>
        <Message Text="relativedir: @(Schema->'%(relativedir)')"/>
        <Message Text="extension: @(Schema->'%(extension)')"/>
    </Target>
</Project>

Comentários

Esse exemplo gera a saída a seguir:

rootdir: C:\
fullpath: C:\sub0\sub1\sub2\sub3\myfile.xsd
rootdir + directory + filename + extension: C:\sub0\sub1\sub2\sub3\myfile.xsd
identity: sub1\sub2\sub3\myfile.xsd
filename: myfile
directory: sub0\sub1\sub2\sub3\
relativedir: sub1\sub2\sub3\
extension: .xsd