Преобразования MSBuild
Обновлен: Ноябрь 2007
Преобразование — это взаимнооднозначное превращение одного набора элементов в другой. Позволяя проекту трансформировать наборы элементов, преобразования также позволяют целевому объекту определить прямое сопоставление входных данных с выходными данными. В данном разделе описываются преобразования и способы их использования в MSBuild для эффективного построения проектов.
Модификаторы преобразований
Преобразования не выполняются произвольно, они ограничены определенным синтаксисом, в котором все модификаторы преобразований должны указываться в формате %(ItemMetaDataName). В качестве модификатора преобразования можно использовать любые метаданные элементов, включая стандартные метаданные, назначенные каждому элементу при создании. Список стандартных метаданных элементов см. в разделе Общеизвестные метаданные элементов MSBuild.
В приведенном ниже примере показано, как список файлов .resx преобразуется в список файлов .resources. Модификатор преобразования %(filename) указывает, что каждый файл .resources должен иметь то же имя, что и соответствующий файл .resx.
@(RESXFile->'%(filename).resources')
Примечание. |
---|
Для преобразованного набора элементов можно задать пользовательский разделитель, так же как для обычного набора элементов. Например, чтобы отделить элементы преобразованного набора запятой (,), а не точкой с запятой (;), используйте следующий XML-код: @(RESXFile->'Toolset\%(filename)%(extension)', ',') |
Например, если в наборе элементов @(RESXFile) содержатся элементы Form1.resx, Form2.resx и Form3.resx, в преобразованном списке будут содержаться элементы Form1.resources, Form2.resources и Form3.resources.
Использование нескольких модификаторов
Преобразование может содержать несколько модификаторов, которые можно указывать в произвольном порядке, а также повторять в выражении преобразования. В приведенном ниже примере имя каталога, содержащего файлы, изменено, но файлы сохраняют исходное название и расширение.
@(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>
Пример
Описание
В следующем примере показан файл проекта MSBuild, в котором используется преобразование. В этом примере предполагается, что в каталоге c:\sub0\sub1\sub2\sub3 содержится один XSD-файл и используется рабочий каталог c:\sub0.
Код
<Project xmlns="https://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:\xmake\sub1\sub2\sub3\myfile.xsd
rootdir + directory + filename + extension: C:\xmake\sub1\sub2\sub3\myfile.xsd
identity: sub1\sub2\sub3\myfile.xsd
filename: myfile
directory: xmake\sub1\sub2\sub3\
relativedir: sub1\sub2\sub3\
extension: .xsd
См. также
Задачи
Практическое руководство. Инкрементное построение