项定义

MSBuild 2.0 允许使用 ItemGroup 元素在项目文件中对项进行静态声明。 但是,只能在项级别添加元数据,即使所有项的元数据都相同也是如此。 MSBuild 3.5 引入了一个名为 ItemDefinitionGroup 的项目元素,从而克服了这一限制。 使用 ItemDefinitionGroup 可以定义一组项定义,这些项定义将默认元数据值添加到命名项类型中的所有项中。

ItemDefinitionGroup 元素紧跟在项目文件的 Project 元素之后。 项定义提供了下列功能:

  • 可为目标外的项定义全局默认元数据。 也就是说,同一元数据适用于指定类型的所有项。

  • 项类型可以有多个定义。 在向类型中添加其他元数据规范时,最后一个规范优先。 (元数据与属性遵循相同的导入顺序。)

  • 可以附加元数据。 例如,CDefines 值是根据所设置的属性进行条件累积的结果。 例如 MT;STD_CALL;DEBUG;UNICODE。

  • 可以移除元数据。

  • 条件可用于控制是否包含元数据。

项元数据默认值

ItemDefinitionGroup 中定义的项元数据只是默认元数据的声明。 除非定义一个使用 ItemGroup 来包含元数据值的项,否则不应用元数据。

提示

本主题中的许多示例都演示了 ItemDefinitionGroup 元素,但为清楚起见,省略了其对应的 ItemGroup 定义。

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

在此示例中,默认元数据“m”应用于项“i”,原因是项“i”未显式定义元数据“m”。 但默认元数据“n”不应用于项“i”,原因是项“i”已定义元数据“n”。

提示

XML 元素和参数名区分大小写。 项元数据和项/属性名不区分大小写。 因此,应将名称只有大小写不同的 ItemDefinitionGroup 项视为同一 ItemGroup。

值源

在 ItemDefinitionGroup 中定义的元数据的值可能有多个不同来源,如下所示:

  • PropertyGroup 属性

  • ItemDefinitionGroup 中的项

  • ItemDefinitionGroup 项中的项转换

  • 环境变量

  • 全局属性(来自 MSBuild.exe 命令行)

  • 保留属性

  • ItemDefinitionGroup 中的项的已知元数据

  • CDATA 节 <![CDATA[此处的所有内容均未分析]]>

提示

由于 ItemDefinitionGroup 元素先于 ItemGroup 元素进行处理,因此来自 ItemGroup 的项元数据在 ItemDefinitionGroup 元数据声明中没有用。

累加性定义和多个定义

在添加定义或使用多个 ItemDefinitionGroup 时,请记住下列注意事项:

  • 将其他元数据规范添加至类型。

  • 最后一个规范优先。

当具有多个 ItemDefinitionGroup 时,每个后续规范都会将其元数据添加至前一定义中。 例如:

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

提示

在同一 ItemDefinitionGroup 中也会出现这种情况。

在重写以前定义的元数据时,最后一个规范优先。 在下面的示例中,元数据“m”的最终值从“m1”变为“m1a”。

<ItemDefinitionGroup>

<i>

<m>m1</m>

</i>

</ItemDefinitionGroup>

<ItemDefinitionGroup>

<i>

<m>m1a</m>

</i>

</ItemDefinitionGroup>

使用 ItemDefinitionGroup 中的条件

可以使用 ItemDefinitionGroup 中的条件来控制是否包含元数据。 例如:

<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">

<i>

<m>m1</m>

</i>

</ItemDefinitionGroup>

在此情况下,仅当“Configuration”属性的值为“Debug”时,才包含项“i”中的默认元数据“m1”。

提示

条件中只支持本地元数据引用。

早期 ItemDefinitionGroup 中定义的元数据引用对项(而不是定义组)而言在本地。 也就是说,引用的范围特定于项。 例如:

<ItemDefinitionGroup>

<test>

<yes>1</yes>

</test>

<i>

<m Condition="'%(test.yes)'=='1'">m1</m>

</i>

</ItemDefinitionGroup>

在此示例中,项“i”在条件中引用项“test”。

重写和删除元数据

在 ItemDefinitionGroup 元素中定义的元数据可在以后的 ItemDefinitionGroup 中重写,方法是将该元数据值设置为空白。 通过将该元数据值设置为空值还可以有效删除元数据项。 例如:

<ItemDefinitionGroup>

<i>

<m>m1</m>

</i>

</ItemDefinitionGroup>

<ItemDefinitionGroup>

<i>

<m></m>

</i>

</ItemDefinitionGroup>

项“i”仍然包含元数据“m”,但其值现在为空。

元数据的范围

ItemDefinitionGroup 对于已定义的全局属性在其定义位置具有全局范围。 ItemDefinitionGroup 中的默认元数据定义可以自引用。 例如,下面的示例使用了一个简单的元数据引用:

<ItemDefinitionGroup>

<i>

<m>m1</m>

<m>%(m);m2</m>

</i>

</ItemDefinitionGroup>

也可以使用限定的元数据引用:

<ItemDefinitionGroup>

<i>

<m>m1</m>

<m>%(i.m);m2</m>

</i>

</ItemDefinitionGroup>

但是,下面的代码无效:

<ItemDefinitionGroup>

<i>

<m>m1</m>

<m>@(x)</m>

</i>

</ItemDefinitionGroup>

从 MSBuild 3.5 开始,ItemGroup 也可以自引用。 例如:

<ItemGroup>

<item Include="a">

<m>m1</m>

<m>%(m);m2</m>

</item>

</ItemGroup>

请参见

概念

MSBuild 批处理