MSBuild basic concepts(MSBuild基本概念):MSBuild items

MSBuild项目代表构建系统的输入,通常指代文件。项目按元素名称分组为项目类型,用于任务参数。本文介绍了如何在项目文件中创建和管理项目,包括使用通配符、排除属性、元数据以及在构建过程中动态创建和修改项目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.MSBuild items

MSBuild项目是构建系统的输入,通常代表文件(文件在Include属性中指定)。根据项目的元素名称将项目分组为项目类型。项目类型是可以用作任务参数的项目的命名列表。任务使用项目值执行构建过程的步骤。

在porject file中创建item

将项目文件中的项目声明为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)进行解释的路径,即使该项目位于导入的文件

在执行期间创建项目

在构建的评估阶段,将为目标元素以外的项目分配值。在后续执行阶段中,可以通过以下方式创建或修改项目:

  • 任何任务都可以发射物品。要发出项目,Task元素必须具有带有属性的子Output元素ItemName

  • CreateItem任务可以发出一个项目。不建议使用此用法。

  • 从.NET Framework 3.5开始,Target元素可能包含可能包含项目元素的ItemGroup元素。

项目文件中的参考项目 

要在整个项目文件中引用项目类型,请使用语法@(<ItemType>)。例如,您可以使用来引用上一个示例中的项目类型@(Compile)。通过使用此语法,可以通过将项目类型指定为该任务的参数来将项目传递给任务。

1,声明某个项目

<CSFile Include="form1.cs"/>

<VBFile Include="form1.vb"/>

2,声明多个项目

<CSFile Include="form1.cs;form2.cs"/>

<VBFile Include="form1.vb;form2.vb"/>

3.通过通配符指定输入:

将所有.jpg文件包含在Images目录和子目录中:Include="Images\**\*.jpg"

包括所有以img开头的.jpg文件  :Include="Images\**\img*.jpg"

将名称以jpgs结尾的所有文件包括在目录中:Include="Images\**\*jpgs\*.*"  or  Include="Images\**\*jpgs\*"

4,将项目传递给任务

将所有Visual C#或Visual Basic文件用作输入

使用Include类似于以下内容的属性:

<CSC Sources="@(CSFile)">...</CSC>

要么

<VBC Sources="@(VBFile)">...</VBC>

 
<Project DefaultTargets="Compile"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
    <PropertyGroup>
        <Builtdir>built</Builtdir>
    </PropertyGroup>

    <ItemGroup>
        <CSFile Include="Form1.cs"/>
        <CSFile Include="AssemblyInfo.cs"/>

        <Reference Include="System.dll"/>
        <Reference Include="System.Data.dll"/>
        <Reference Include="System.Drawing.dll"/>
        <Reference Include="System.Windows.Forms.dll"/>
        <Reference Include="System.XML.dll"/>
    </ItemGroup>

    <Target Name="PreBuild">
        <Exec Command="if not exist $(builtdir) md $(builtdir)"/>
    </Target>

    <Target Name="Compile" DependsOnTargets="PreBuild">
        <Csc Sources="@(CSFile)"
            References="@(Reference)"
            OutputAssembly="$(builtdir)\$(MSBuildProjectName).exe"
            TargetType="exe" />
    </Target>
</Project>

使用通配符指定项目

例如,您可以.cs通过使用项目文件中的以下元素来指定包含项目文件的目录中的所有文件。

 
<CSFile Include="*.cs"/>

以下元素选择驱动器.vb上的所有文件D:

<VBFile Include="D:/**/*.vb"/>

使用排除属性

项目元素可以包含Exclude属性,该属性从项目类型中排除特定项目(文件)。

<ItemGroup>
    <CSFile  Include="*.cs"  Exclude="DoNotBuild.cs"/>
</ItemGroup>

Exclude属性仅影响该Include属性在包含它们的item元素中添加的项目。以下示例不会排除文件Form1.cs,该文件已添加到前面的item元素中。

<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">

项目元数据

除了IncludeExclude属性中的信息外,项目还可能包含元数据

元数据是键值对的集合,这些键值对在项目文件中声明为item元素的子元素。子元素的名称是元数据的名称,子元素的值是元数据的值。

元数据与包含它的item元素相关联。例如,以下将Culture元数据添加值Fr到CSFile项类型的one.cstwo.cs项中。

<ItemGroup>
    <CSFile Include="one.cs;two.cs">
        <Culture>Fr</Culture>
    </CSFile>
</ItemGroup>

一个项目可以具有零个或多个元数据值。您可以随时更改元数据值。如果将元数据设置为空值,则可以有效地将其从构建中删除。

项目文件中的参考项目元数据

您可以使用语法%(<ItemMetadataName>)引用整个项目文件中的项目元数据。如果存在歧义,则可以使用项目类型的名称来限定引用。例如,您可以指定%(<ItemType.ItemMetaDataName>)。

下面的示例使用“显示”元数据批处理“消息”任务。
 
<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>

通过使用元数据来转换项目类型

您可以使用元数据将项目列表转换为新的项目列表。例如,您可以使用表达式CppFiles将具有表示.cpp文件的项目的项目类型转换为.obj文件的相应列表@(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>

项目定义

默认元数据添加到任何项目类型。像众所周知的元数据一样,默认元数据与您指定的项目类型的所有项目相关联。您可以在项目定义中显式覆盖默认元数据

在ItemGroup中明确定义的元数据优先于ItemDefinitionGroup中的元数据。ItemDefinitionGroup中的元数据仅适用于ItemGroup中未定义的元数据。例如:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
        <n>n1</n>
    </i>
</ItemDefinitionGroup>
<ItemGroup>
    <i Include="a">
        <o>o1</o>
        <n>n2</n>
    </i>
</ItemGroup>

加性和多重定义

添加定义或使用多个ItemDefinitionGroups时,请记住以下几点:

  • 其他元数据规范已添加到该类型。

  • 最后的规范优先。

当您有多个ItemDefinitionGroups时,每个后续规范都将其元数据添加到先前的定义中。例如:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
        <n>n1</n>
    </i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
    <i>
        <o>o1</o>
    </i>
</ItemDefinitionGroup>

在该示例中,元数据“ o”被添加到“ m”和“ n”。

另外,还可以添加先前定义的元数据值。例如:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
    </i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
    <i>
        <m>%(m);m2</m>
    </i>
</ItemDefinitionGroup>

在此示例中,先前为元数据“ m”(m1)定义的值被添加到新值(m2),因此最终值为“ m1; m2”。

目标的项目组中项目的属性

1,remove 属性

Remove属性从项目类型中删除特定的项目(文件)

下面的示例从“编译”项类型中删除每个.config文件。

<Target>
    <ItemGroup>
        <Compile Remove="*.config"/>
    </ItemGroup>
</Target>

2,KeepMetadata属性

如果在目标内生成项目,则item元素可以包含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:
-->

因为KeepMetadata="Class",所以将FirstItem里面的class元素赋值给了SecondItem 的class元素,而size则没有赋值,所以为空

3.RemoveMetadata属性

如果在目标内生成项目,则item元素可以包含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:
-->

因为最开始定义去除的元素有<MetadataToRemove>Size;Material</MetadataToRemove>,所以item1中的这两个元素没有传递,只传递了color

4,KeepDuplicates属性

如果在目标内生成项目,则item元素可以包含KeepDuplicates属性。KeepDuplicates是一个Boolean属性,用于指定如果该项目与现有项目完全相同,则是否应将其添加到目标组。

如果源项目和目标项目具有相同的包含值,但元数据不同,则即使将项目设置为KeepDuplicates,也会添加该项目false。此属性的空值等效于不指定它。

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值