Преобразования MSBuild
Преобразование — это однозначное преобразование одного списка элементов в другой. Помимо возможности преобразования списков элементов в проекте, преобразование позволяет целевому объекту определить прямое сопоставление входных и выходных данных. Этот раздел описывает преобразования и то, как MSBuild использует их для более эффективной сборки проектов.
Модификаторы преобразования
Преобразования не являются произвольными, они ограничены специальным синтаксисом, в котором все модификаторы преобразования должны иметь формат %(<имя_метаданных_элемента>). Метаданные элементов можно использовать в качестве модификаторов преобразования. Сюда входят стандартные метаданные элементов, назначаемые каждому элементу при создании. Список стандартных метаданных элементов см. в статье Общеизвестные метаданные элементов MSBuild.
В приведенном ниже примере список файлов RESX преобразуется в список файлов RESOURCES. Модификатор преобразования %(filename) указывает, что каждый файл RESOURCES имеет то же имя, что и соответствующий файл RESX.
@(RESXFile->'%(filename).resources')
Например, если в списке элементов @(RESXFile) содержатся элементы Form1.resx, Form2.resx и Form3.resx, выходными элементами в преобразованном списке будут Form1.resources, Form2.resources и Form3.resources.
Примечание.
Вы можете указать настраиваемый разделитель для преобразованного списка элементов точно так же, как и для стандартного списка элементов. Например, чтобы разделить преобразованный список элементов с помощью запятой (,), а не используемой по умолчанию точки с запятой (;), используйте следующий код XML: @(RESXFile->'Toolset\%(filename)%(extension)', ',')
Использование нескольких модификаторов
Выражение преобразования может содержать несколько модификаторов, которые можно объединять в любом порядке, кроме того, они могут повторяться. В следующем примере изменяется имя каталога, содержащего файлы, однако файлы сохраняют исходное имя и расширение.
@(RESXFile->'Toolset\%(filename)%(extension)')
Например, если в списке элементов RESXFile
содержатся элементы Project1\Form1.resx, Project1\Form2.resx и Project1\Form3.text, выходными элементами в преобразованном списке будут Toolset\Form1.resx, Toolset\Form2.resx и Toolset\Form3.text.
Анализ зависимостей
Преобразование обеспечивает однозначное сопоставление между преобразованным и исходным списками элементов. Таким образом, если целевой объект создает выходные данные, полученные путем преобразования входных файлов, MSBuild может проанализировать метки времени входных и выходных данных и решить, следует ли пропустить целевой объект, выполнить его сборку или частично перестроить.
В задаче Copy в следующем примере каждый файл в списке элементов BuiltAssemblies
сопоставляется с файлом в папке назначения задачи, указанной с помощью преобразования в атрибуте Outputs
. Если изменяется файл в списке элементов BuiltAssemblies
, задача Copy
выполняется только для измененного файла, а все остальные файлы пропускаются. Дополнительные сведения об анализе зависимостей и использовании преобразований см. в статье Практическое руководство. Инкрементная сборка.
<Target Name="CopyOutputs"
Inputs="@(BuiltAssemblies)"
Outputs="@(BuiltAssemblies -> '$(OutputPath)%(Filename)%(Extension)')">
<Copy
SourceFiles="@(BuiltAssemblies)"
DestinationFolder="$(OutputPath)"/>
</Target>
Пример
Description
Следующий пример показывает файл проекта MSBuild, использующий преобразования. В этом примере предполагается, что в каталоге c:\sub0\sub1\sub2\sub3 есть только один XSD-файл, а рабочим каталогом является c:\sub0.
Код
<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>
Комментарии
В примере получается следующий вывод.
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