MSBuild 項目
MSBuild 項目はビルド システムへの入力であり、通常はファイルを表します (ファイルは Include
属性で指定します)。 項目は要素名に基づいてアイテムの種類にグループ化されます。 項目の種類は項目の名前付きリストであり、タスクのパラメーターとして使用できます。 タスクは項目値を使用して、ビルド処理のステップを実行します。
項目名はそれぞれが属するアイテムの種類によって指定されるため、「項目」と「項目値」という用語は同義です。
プロジェクト ファイルで項目を作成する
プロジェクト ファイル内で、ItemGroup 要素の子要素として項目を宣言します。 有効な項目名は、大文字か小文字またはアンダースコア (_
) で始まり、続く文字は英数字 (文字または数字)、アンダースコア、ハイフン (-
) となります。 子要素の名前は、アイテムの種類です。 要素の Include
属性は、そのアイテムの種類に組み込まれる項目 (ファイル) を指定します。 たとえば、次の XML では、Compile
という名前のアイテムの種類を作成し、2 つのファイルを含めています。
<ItemGroup>
<Compile Include = "file1.cs"/>
<Compile Include = "file2.cs"/>
</ItemGroup>
項目 file2.cs で項目 file1.cs が置き換えられるのではなく、このファイル名がアイテムの種類 Compile
の値のリストに付加されます。
次の XML では、両方のファイルを 1 つの Include
属性で宣言することで、同じアイテムの種類を作成しています。 ファイル名はセミコロンで区切られます。
<ItemGroup>
<Compile Include = "file1.cs;file2.cs"/>
</ItemGroup>
Include
属性は、.targets
ファイルのようなインポートされたファイルに項目が入っている場合でも、プロジェクト ファイルのフォルダー $(MSBuildProjectPath)
の相対パスとして解釈されます。
実行時に項目を作成する
Target 要素の外側にある項目には、ビルドの評価フェーズで値が割り当てられます。 その後の実行フェーズで、次のようにして項目を作成または変更できます。
どのタスクも項目を生成できます。 項目を生成するには、Task 要素の子要素として、
ItemName
属性を持つ Output 要素が必要です。CreateItem タスクは、項目を生成できます。 この使用法は非推奨とされます。
Target
要素には、項目要素を格納できる ItemGroup 要素を含めることができます。
プロジェクト ファイルの項目を参照する
プロジェクト ファイル全体の項目の種類を参照するには、構文 @(ItemType)
を使用します。 たとえば、前の例に挙げたアイテムの種類を参照するには、@(Compile)
を使用します。 この構文を使用してアイテムの種類をタスクのパラメーターとして指定すれば、項目をそのタスクに渡すことができます。 詳細については、ビルドするファイルを選択する」を参照してください。
既定では、アイテムの種類の項目は、それが展開されるときにセミコロン (;) によって区切られます。 構文 @(ItemType, 'separator')
を使用して、既定以外の区切り記号を指定できます。 詳細については、項目リストをコンマ区切りで表示する」を参照してください。
ワイルドカードを使用して項目を指定する
**
、*
、?
をワイルドカード文字として使用して、各ファイルを個別にリストする代わりに、ファイルのグループをビルドの入力として指定できます。
?
ワイルドカード文字は単一の文字と一致します。*
ワイルドカード文字は 0 個以上の文字と一致します。**
ワイルドカード文字のシーケンスはパスの一部と一致します。
たとえば、プロジェクト ファイルで次の要素を使用して、プロジェクト ファイルが格納されているディレクトリ内のすべての .cs
ファイルを指定できます。
<CSFile Include="*.cs"/>
次の要素は D:
ドライブ上のすべての .vb
ファイルを選択します。
<VBFile Include="D:/**/*.vb"/>
ワイルドカードを展開することなく項目内にリテラル文字 *
または ?
を含める必要がある場合は、ワイルドカード文字をエスケープする必要があります。
ワイルドカード文字の詳細については、「方法:ビルドするファイルを選択する」を参照してください。
Exclude 属性を使用する
項目の要素には Exclude
属性を含めることができます。この属性は、アイテムの種類から特定の項目 (ファイル) を除外します。 Exclude
属性は通常、ワイルドカード文字と一緒に使用されます。 たとえば、次の XML では、DoNotBuild.cs ファイルを除き、ディレクトリのすべての .cs ファイルを項目の種類 CSFile
に追加します。
<ItemGroup>
<CSFile Include="*.cs" Exclude="DoNotBuild.cs"/>
</ItemGroup>
Exclude
属性は、同一の項目要素内にある Include
属性によって追加された項目のみに作用します。 次の例では、Form1.cs ファイルは前の項目要素で追加されているため、除外されません。
<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">
詳細については、ビルドからファイルを除外する」をご覧ください。
項目メタデータ
項目には、Include
および Exclude
属性の情報に加えて、メタデータを含めることができます。 このメタデータは、項目に関する詳細情報を必要とするタスクで使用できます。あるいは、タスクとターゲットをバッチ処理するために使用できます。 詳細については、「MSBuild バッチ」をご覧ください。
メタデータは、項目の要素の子要素としてプロジェクト ファイルで宣言されているキーと値のペアのコレクションです。 子要素の名前はメタデータの名前であり、子要素の値はメタデータの値です。
メタデータは、それが含まれる項目要素に関連付けられています。 たとえば、次の XML では、値 Fr
を持つ Culture
メタデータを、項目の種類 CSFile
の one.cs と two.cs の両方の項目に追加します。
<ItemGroup>
<CSFile Include="one.cs;two.cs">
<Culture>Fr</Culture>
</CSFile>
</ItemGroup>
項目には 0 以上のメタデータ値を指定できます。 メタデータの値は、いつでも変更できます。 メタデータを空の値に設定すると、実質的にはビルドからメタデータが削除されます。
プロジェクト ファイルで項目メタデータを参照する
プロジェクト ファイル全体の項目のメタデータは、%(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 -> '%(Filename).obj')
を使用して、 .cpp
ファイルを表す項目を含む項目の種類 CppFiles
を、対応する .obj
ファイルの一覧に変換できます。
次のコードでは CultureResource
というアイテムの種類を作成し、Culture
メタデータを持つすべての EmbeddedResource
項目のコピーをそこに含めます。 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 に、"Monday" という値を持つメタデータ BuildDay
を指定します。 コードは項目 two.cs に、値 "Tuesday" を持つメタデータ BuildDay
を指定します。
<ItemDefinitionGroup>
<Compile>
<BuildDay>Monday</BuildDay>
</Compile>
</ItemDefinitionGroup>
<ItemGroup>
<Compile Include="one.cs;three.cs" />
<Compile Include="two.cs">
<BuildDay>Tuesday</BuildDay>
</Compile>
</ItemGroup>
詳細については、「項目定義」を参照してください。
Target の ItemGroup の項目の属性
Target
要素には、項目要素を格納できる ItemGroup 要素を含めることができます。 このセクションの属性は、Target
にある ItemGroup
の項目に指定されている場合に有効です。
Remove 属性
Remove
属性では、項目の種類から特定の項目 (ファイル) が削除されます。 この属性は、.NET Framework 3.5 で導入されました (ターゲット内部のみ)。 ターゲット内部と外部の両方が、MSBuild 15.0 以降でサポートされます。
次の例では、項目の種類 Compile
からすべての .config
ファイルを削除します。
<Target>
<ItemGroup>
<Compile Remove="*.config"/>
</ItemGroup>
</Target>
MatchOnMetadata 属性
MatchOnMetadata
属性は、他の項目 (Remove="@(Compile);@(Content)"
など) を参照する Remove
属性にのみ適用され、Remove
操作に対して、項目の値に基づいて一致させるのではなく、指定されたメタデータ名の値に基づいて項目に一致させるように指示します。
B Remove="@(A)" MatchOnMetadata="M"
の一致規則: B
から、メタデータ M
を持つすべての項目で、その M
のメタデータの値 V
が、A
の、値が V
であるメタデータ M
を持つ項目と一致するものを削除します。
<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
から削除されます。
B
のb2
とc2
が、A
のb1
とM1=2
およびM2=x
で一致するB
のd2
が、A
のc1
と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'
MSBuild からの MatchOnMetadata
の使用例:
<_TransitiveItemsToCopyToOutputDirectory Remove="@(_ThisProjectItemsToCopyToOutputDirectory)" MatchOnMetadata="TargetPath" MatchOnMetadataOptions="PathLike" />
この行では、_TransitiveItemsToCopyToOutputDirectory
から、_ThisProjectItemsToCopyToOutputDirectory
の項目と同じ TargetPath
メタデータ値を持つ項目を削除します
MatchOnMetadataOptions 属性
項目間でメタデータ値を照合するために MatchOnMetadata
によって使用される文字列照合の方法を指定します (メタデータ名の照合では常に大文字と小文字が区別されます)。 設定可能な値は、CaseSensitive
、CaseInsensitive
、または PathLike
です。 既定値は CaseSensitive
です。
PathLike
では、スラッシュの向きの正規化、.
や ..
の削除、現在のディレクトリに対してすべての相対パスを絶対にするなど、パスに対応した正規化が値に適用されます。
KeepMetadata 属性
ターゲット内に項目が生成される場合、項目要素に 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 属性
ターゲット内に項目が生成される場合、項目要素に 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 属性
ターゲット内に項目が生成される場合、項目要素に 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
属性では項目の値に加えて項目のメタデータが考慮されるため、メタデータで何が起こっているかを把握することが重要です。 たとえば、「Metadata 項目関数を使用する場合の重複の検出」をご覧ください。
ターゲットの外部にある 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
属性は、2 つ以上の項目からメタデータをインポートしやすくするために、修飾されたメタデータの参照をサポートしています。
<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)
) は、キャプチャされた一致する項目の種類のセット内で、更新式からバインドされます。 - 項目が複数の参照項目の間で複数回一致する場合:
- 参照される各項目の種類から最後に出現したものがキャプチャされます (項目の種類ごとに 1 つのキャプチャされた項目)。
- これは、ターゲットでのタスク項目バッチ処理の動作と一致します。
- %() 参照を配置できる場所:
- Metadata
- メタデータ条件
- メタデータ名のマッチングでは大文字と小文字は区別されません。
ターゲットの 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:
-->