项定义
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>