Przekształcenia w programie MSBuild

Przekształcenie jest konwersją jeden do jednego elementu na inną. Oprócz umożliwienia projektu konwersji list elementów przekształcenie umożliwia elementowi docelowemu identyfikację bezpośredniego mapowania między danymi wejściowymi i wyjściowymi. W tym temacie opisano przekształcenia i sposób, w jaki program MSBuild używa ich do wydajniejszego kompilowania projektów.

Modyfikatory przekształcania

Przekształcenia nie są dowolne, ale są ograniczone przez specjalną składnię, w której wszystkie modyfikatory przekształcania muszą mieć format %(<ItemMetaDataName>). Wszystkie metadane elementu mogą być używane jako modyfikator transformacji. Obejmuje to dobrze znane metadane elementu, które są przypisywane do każdego elementu podczas jego tworzenia. Aby uzyskać listę dobrze znanych metadanych elementu, zobacz Dobrze znane metadane elementu.

W poniższym przykładzie lista plików resx jest przekształcana w listę plików resources . Modyfikator przekształcenia %(nazwa pliku) określa, że każdy plik resources ma taką samą nazwę pliku jak odpowiedni plik resx.

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

Jeśli na przykład elementy na liście elementów @(RESXFile) to Form1.resx, Form2.resx i Form3.resx, dane wyjściowe na przekształconej liście będą form1.resources, Form2.resources i Form3.resources.

Uwaga

Separator niestandardowy dla przekształconej listy elementów można określić w taki sam sposób, jak separator dla listy elementów standardowych. Aby na przykład oddzielić przekształconą listę elementów przy użyciu przecinka (,) zamiast domyślnego średnika (;), użyj następującego kodu XML: @(RESXFile->'Toolset\%(filename)%(extension)', ',')

Używanie wielu modyfikatorów

Wyrażenie przekształcenia może zawierać wiele modyfikatorów, które można łączyć w dowolnej kolejności i można je powtórzyć. W poniższym przykładzie nazwa katalogu zawierającego pliki jest zmieniana, ale pliki zachowują oryginalną nazwę i rozszerzenie nazwy pliku.

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

Jeśli na przykład elementy, które znajdują się na RESXFile liście elementów, to Project1\Form1.resx, Project1\Form2.resx i Project1\Form3.text, dane wyjściowe na przekształconej liście będą mieć postać Toolset\Form1.resx, Toolset\Form2.resx i Toolset\Form3.text.

Analiza zależności

Przekształcenia gwarantują mapowanie jeden do jednego między przekształconą listą elementów a oryginalną listą elementów. W związku z tym, jeśli element docelowy tworzy dane wyjściowe, które są przekształceniami danych wejściowych, program MSBuild może analizować znaczniki czasu danych wejściowych i wyjściowych oraz zdecydować, czy pominąć, skompilować lub częściowo skompilować element docelowy.

W zadaniu Kopiowania w poniższym przykładzie każdy plik na BuiltAssemblies liście elementów jest mapowany na plik w folderze docelowym zadania określonego za pomocą przekształcenia w atrybucie Outputs . Jeśli plik na BuiltAssemblies liście elementów ulegnie zmianie, Copy zadanie zostanie uruchomione tylko dla zmienionego pliku, a wszystkie inne pliki zostaną pominięte. Aby uzyskać więcej informacji na temat analizy zależności i sposobu używania przekształceń, zobacz Instrukcje: tworzenie przyrostowe.

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

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

</Target>

Przykład

opis

W poniższym przykładzie pokazano plik projektu MSBuild, który używa przekształceń. W tym przykładzie przyjęto założenie, że w katalogu c:\sub0\sub1\sub2\sub3 znajduje się tylko jeden plik xsd, a katalog roboczy to c:\sub0.

Kod

<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>

Komentarze

Ten przykład generuje następujące wyniki:

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