Элементы SBuild
Элементы MSBuild — это входные данные для системы сборки. Они, как правило, представляют файлы (файлы указаны в атрибуте Include
). Элементы группируются в типы, определяемые их именами. Типы элементов — это именованные списки элементов, которые можно использовать в качестве параметров для задач. Задачи используют значения элементов для выполнения этапов процесса сборки.
Так как имена элементов образуются от имен типов, которым они принадлежат, термины "элемент" и "значение элемента" могут использоваться один вместо другого.
Создание элементов в файле проекта
Элементы в файле проекта объявляются как дочерние элементы элемента ItemGroup. Допустимые имена элементов начинаются с прописной или строчной буквы или подчеркивания (_
); допустимые последующие символы включают буквенно-цифровые символы (буквы или цифры), подчеркивание и дефис (-
). Имя дочернего элемента совпадает с именем типа элемента. Атрибут Include
элемента определяет элементы (файлы), которые следует включить в данный тип элементов. В приведенном ниже примере XML-кода создается тип элементов с именем Compile
, в который входят два файла.
<ItemGroup>
<Compile Include = "file1.cs"/>
<Compile Include = "file2.cs"/>
</ItemGroup>
Элемент file2.cs не заменяет собой элемент file1.cs. Имя файла добавляется в список значений для типа элемента Compile
.
Следующий XML-код создает такой же тип элементов путем объявления обоих файлов в одном атрибуте Include
. Обратите внимание, что имена файлов разделяются точкой с запятой.
<ItemGroup>
<Compile Include = "file1.cs;file2.cs"/>
</ItemGroup>
Атрибут Include
— это путь, интерпретируемый относительно папки файла проекта, $(MSBuildProjectPath)
даже если элемент находится в импортированном файле, .targets
например в файле.
Создание элементов во время выполнения
Значения элементам, находящимся за пределами элементов Target, присваиваются на этапе оценки сборки. На следующем этапе выполнения элементы могут быть созданы и их значения могут быть изменены следующим образом.
Любая задача может создать элемент. Для создания элемента элемент Задача должен иметь дочерний элемент Выходные данные с атрибутом
ItemName
.Задача CreateItem также может создать элемент. Этот способ не рекомендуется использовать.
Target
элементы могут содержать элементы ItemGroup, которые могут содержать элементы элемента.
Ссылки на элементы в файле проекта
Чтобы ссылаться на типы элементов в файле проекта, используйте синтаксис @(ItemType)
. Например, для обращения к типу элементов из предыдущего примера следует использовать конструкцию @(Compile)
. Используя этот синтаксис, можно передавать элементы в задачи, указывая тип элементов в качестве параметра этой задачи. Дополнительные сведения см. в разделе Практическое руководство. Выбор файлов для сборки.
По умолчанию при развертывании элементы типа разделяются знаком "точка с запятой" (;). Синтаксис @(ItemType, 'separator')
можно использовать для указания разделителя, отличного от значения по умолчанию. Дополнительные сведения см. в разделе Практическое руководство. Отображение списка элементов, разделенных запятыми.
Использование подстановочных знаков для указания элементов
С помощью подстановочных знаков **
, *
и ?
в качестве входных данных для сборки можно указать сразу группу файлов, не перечисляя эти файлы по отдельности.
- Подстановочный знак
?
заменяет один символ. - Знак
*
заменяет несколько символов (или ни одного). - Последовательность подстановочных знаков
**
заменяет частичный путь.
Например, можно указать все файлы с расширением .cs
в каталоге с файлом проекта, используя следующий элемент в файле проекта.
<CSFile Include="*.cs"/>
Следующий элемент выбирает все файлы с расширением .vb
на диске D:
.
<VBFile Include="D:/**/*.vb"/>
Чтобы включить в элемент сами символы *
или?
без выполнения подстановки, необходимо экранировать подстановочные знаки.
Дополнительные сведения о подстановочных знаках см. в разделе Практическое руководство. Выбор файлов для сборки.
Использование атрибута Exclude
Элементы Item могут содержать атрибут Exclude
, исключающий определенные элементы (файлы) из типа элементов. Атрибут Exclude
обычно используется вместе с подстановочными знаками. Например, следующий XML-файл добавляет каждый .cs файл в каталоге к типу CSFile
элемента, кроме файла DoNotBuild.cs.
<ItemGroup>
<CSFile Include="*.cs" Exclude="DoNotBuild.cs"/>
</ItemGroup>
Атрибут Exclude
применяется только к элементам, добавляемым с помощью атрибута Include
в элемент Item, содержащий их оба. В следующем примере файл Form1.cs, добавленный в предыдущий элемент Item, не исключается.
<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">
Дополнительные сведения см. в разделе Практическое руководство. Исключение файлов из сборки.
Метаданные элементов
Помимо сведений в атрибутах Include
и Exclude
элементы могут содержать метаданные. Эти метаданные могут использоваться задачами, требующими дополнительных сведений об элементах, или для пакетной обработки задач и целевых объектов. Дополнительные сведения см. в статье Пакетная обработка.
Метаданные — это коллекция пар "ключ-значение", которые объявляются в файле проекта как дочерние элементы элемента Item. Имя дочернего элемента совпадает с именем метаданных, а значение дочернего элемента совпадает со значением метаданных.
Метаданные связаны с элементом Item, который их содержит. Например, следующий XML-код добавляет Culture
метаданные, имеющие значение Fr
как для one.cs, так и для элементов two.cs типа элементаCSFile
.
<ItemGroup>
<CSFile Include="one.cs;two.cs">
<Culture>Fr</Culture>
</CSFile>
</ItemGroup>
Элемент может содержать нуль или более значений метаданных. Значения метаданных можно изменить в любое время. Если задать для метаданных пустое значение, это фактически будет означать их удаление из сборки.
Метаданные ссылочного элемента в файле проекта
Вы можете ссылаться на метаданные элемента в файле проекта с помощью синтаксиса %(ItemMetadataName)
. Если возникает неоднозначность, можно ограничить применение ссылки с помощью имени типа элемента. Например, так: %(ItemType.ItemMetaDataName)
. В следующем примере метаданные Display
используются для пакетной обработки Message
задачи. Дополнительные сведения об использовании метаданных элементов для пакетной обработки см. в разделе Метаданные элементов в пакетной обработке задач.
<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>
Стандартные метаданные элементов
Когда элемент добавляется в тип элементов, ему назначаются некоторые стандартные метаданные. Например, все элементы имеют известные метаданные %(Filename)
, значение которого — имя файла элемента (без расширения). Дополнительные сведения см. в разделе Стандартные метаданные элементов.
Преобразование типов элементов с помощью метаданных
С помощью метаданных можно преобразовать списки элементов в новые списки элементов. Например, можно преобразовать тип CppFiles
элемента с элементами.obj
, представляющими .cpp
файлы в соответствующий список файлов с помощью выражения@(CppFiles -> '%(Filename).obj')
.
Следующий код создает тип CultureResource
, содержащий копии всех элементов EmbeddedResource
с метаданными Culture
. Значения метаданных Culture
присваиваются новым метаданным CultureResource.TargetDirectory
.
<Target Name="ProcessCultureResources">
<ItemGroup>
<CultureResource Include="@(EmbeddedResource)"
Condition="'%(EmbeddedResource.Culture)' != ''">
<TargetDirectory>%(EmbeddedResource.Culture) </TargetDirectory>
</CultureResource>
</ItemGroup>
</Target>
Дополнительные операции с элементами описаны в руководствах по функциям элементов MSBuild и преобразованиям.
Определения элементов
Метаданные по умолчанию можно добавить в любой тип элемента с помощью элемента ItemDefinitionGroup. Подобно стандартным метаданным, метаданные по умолчанию связаны со всеми элементами указанного типа. Метаданные по умолчанию можно в явном виде переопределить в определении элемента. В следующем примере XML-кода элементам Compile
one.cs и three.cs назначаются метаданные BuildDay
со значением "Понедельник". В этом коде элементу two.cs назначаются метаданные BuildDay
со значением "Вторник".
<ItemDefinitionGroup>
<Compile>
<BuildDay>Monday</BuildDay>
</Compile>
</ItemDefinitionGroup>
<ItemGroup>
<Compile Include="one.cs;three.cs" />
<Compile Include="two.cs">
<BuildDay>Tuesday</BuildDay>
</Compile>
</ItemGroup>
Дополнительные сведения см. в разделе Определения элементов.
Атрибуты элементов в элементе ItemGroup целевого объекта
Target
элементы могут содержать элементы ItemGroup, которые могут содержать элементы элемента. Атрибуты в этом разделе допустимы, если они указаны для элемента в ItemGroup
объекте, который находится в объекте Target
.
Удалить атрибут
Атрибут Remove
удаляет определенные элементы (файлы) из типа элементов. Этот атрибут появился в .NET Framework 3.5 (только для внутренних целевых объектов). Начиная с MSBuild 15.0, поддерживаются как внутренние, так и внешние целевые объекты.
В следующем примере каждый .config
файл удаляется из Compile
типа элемента.
<Target>
<ItemGroup>
<Compile Remove="*.config"/>
</ItemGroup>
</Target>
Атрибут MatchOnMetadata
Атрибут MatchOnMetadata
применим только к Remove
атрибутам, ссылающимся на другие элементы (например, Remove="@(Compile);@(Content)"
) и предписывает Remove
операции сопоставлять элементы на основе значений указанных имен метаданных вместо сопоставления на основе значений элементов.
Правило сопоставления для B Remove="@(A)" MatchOnMetadata="M"
: удаляет все элементы из B
с метаданными M
, значение которых V
для M
соответствует любым элементам из A
с метаданными M
значения 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>
В примере значения b2
c2
элементов и d2
удаляются из элементаB
, так как:
b2
иc2
изB
соответствуютb1
изA
вM1=2
иM2=x
;d2
изB
соответствуютc1
изA
вM1=3
иM2=y
.
Задача Message
выводит следующие данные:
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'
Пример использования MatchOnMetadata
из MSBuild:
<_TransitiveItemsToCopyToOutputDirectory Remove="@(_ThisProjectItemsToCopyToOutputDirectory)" MatchOnMetadata="TargetPath" MatchOnMetadataOptions="PathLike" />
Эта строка удаляет элементы из _TransitiveItemsToCopyToOutputDirectory
элементов с одинаковыми TargetPath
значениями метаданных из элементов _ThisProjectItemsToCopyToOutputDirectory
Атрибут MatchOnMetadataOptions
Указывает стратегию сопоставления строк, используемую MatchOnMetadata
для сопоставления значений метаданных разных элементов (при сопоставлении имен метаданных регистр не учитывается). Возможные значения: CaseSensitive
, CaseInsensitive
или PathLike
. Значение по умолчанию — CaseSensitive
.
PathLike
Применяет нормализацию с учетом путей к таким значениям, как нормализация ориентаций косой черты, игнорировать конечные косые черты, устранять .
и ..
, а также делать все относительные пути абсолютными для текущего каталога.
Атрибут KeepMetadata
Если элемент создается в целевом объекте, элемент Item может содержать атрибут KeepMetadata
. Если этот атрибут задан, из исходного элемента в целевой передаются только те метаданные, имена которых содержатся в списке имен, разделенных точкой с запятой. Пустое значение этого атрибута эквивалентно тому, что атрибут не задан. Атрибут KeepMetadata
появился в .NET Framework версии 4.5.
В следующем примере показано использование атрибута 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:
-->
Атрибут RemoveMetadata
Если элемент создается в целевом объекте, элемент Item может содержать атрибут RemoveMetadata
. Если этот атрибут задан, из исходного элемента в целевой передаются все метаданные за исключением метаданных, имена которых содержатся в списке имен, разделенных точкой с запятой. Пустое значение этого атрибута эквивалентно тому, что атрибут не задан. Атрибут RemoveMetadata
появился в .NET Framework версии 4.5.
В следующем примере показано использование атрибута 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:
-->
Дополнительные операции с элементами см. в руководстве по функциям элементов MSBuild.
Атрибут KeepDuplicates
Если элемент создается в целевом объекте, элемент Item может содержать атрибут KeepDuplicates
. KeepDuplicates
— это атрибут Boolean
, который указывает, следует ли добавлять элемент в целевую группу, если он является точной копией существующего элемента.
Если исходный и целевой элементы имеют одинаковое значение Include
, но различные метаданные, элемент добавляется в целевую группу, даже если KeepDuplicates
имеет значение false
. Пустое значение этого атрибута эквивалентно тому, что атрибут не задан. Атрибут KeepDuplicates
появился в .NET Framework версии 4.5.
В следующем примере показано использование атрибута 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
-->
KeepDuplicates
Так как атрибут рассматривает метаданные элементов в дополнение к значениям элементов, важно знать, что происходит с метаданными. Например, см. сведения об обнаружении дубликатов при использовании функции элемента метаданных.
Обновление метаданных элементов в ItemGroup за пределами целевого объекта
Для обновления метаданных элементов, находящихся за пределами целевых объектов, можно использовать атрибут Update
. Этот атрибут недоступен для элементов, находящихся внутри целевых объектов.
<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
-->
В MSBuild 16.6 и более поздних версий атрибут 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>
<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
-->
Примечания:
- Неквалифицированные метаданные (
%(MetadataName)
) привязываются к обновляемой типу элемента (Item1
в приведенном выше примере). Полные метаданные (%(Item2.Color)
) привязываются внутри набора соответствующих типов элемента, полученных из выражения Update. - Если элемент совпадает несколько раз в пределах и между несколькими ссылочными элементами:
- Получается последнее вхождение для каждого типа элемента, на который задана ссылка (то есть для каждого типа элемента получается один элемент).
- Это соответствует поведению пакетной обработки элементов задачи в целевых объектах.
- Где можно поместить ссылки %():
- Метаданные
- Условия метаданных
- Сопоставление имен метаданных не учитывает регистр.
Обновление метаданных элементов в ItemGroup целевого объекта
Метаданные также можно изменять внутри целевых объектов, используя менее выразительный по сравнению с 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:
-->
Связанный контент
- Элемент Item (MSBuild)
- Общие элементы проектов MSBuild
- Основные понятия MSBuild
- MSBuild
- Практическое руководство. Выбор файлов для сборки
- Практическое руководство. Исключение файлов из сборки
- Практическое руководство. Отображение списка элементов, разделенных запятыми
- Определения элементов
- Пакетная обработка