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”应用于 Item“i”,因为元数据“m”未由项“i”显式定义。 但是,默认元数据“n”不适用于项“i”,因为元数据“n”已由项“i”定义。
注释
XML 元素和参数名称区分大小写。 项元数据和 Item/属性名称不区分大小写。 因此,只应将名称与大小写不同的 ItemDefinitionGroup 项视为同一 ItemGroup。
值源
ItemDefinitionGroup 中定义的元数据的值可能来自许多不同的源,如下所示:
PropertyGroup 属性
ItemDefinitionGroup 中的项
ItemDefinitionGroup Item 上的项转换
环境变量
全局属性(从 MSBuild.exe 命令行)
保留属性
ItemDefinitionGroup 中项的已知元数据
CDATA 节 <![CDATA[此处未分析任何内容]]>
注释
ItemDefinitionGroup 元数据声明中的项元数据在 ItemDefinitionGroup 元数据声明中无效,因为 ItemDefinitionGroup 元素在 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“.
注释
这也可能在同一 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>m0</m>
<m Condition="'%(test.yes)'=='1'">m1</m>
</i>
</ItemDefinitionGroup>
在上面的示例中,项“i”在其条件中引用项“test”。 此条件永远不会为 true,因为 MSBuild 将对 ItemDefinitionGroup 中另一项元数据的引用解释为空字符串。 因此,“m”将设置为“m0”。
<ItemDefinitionGroup>
<i>
<m>m0</m>
<yes>1</yes>
<m Condition="'%(i.yes)'=='1'">m1</m>
</i>
</ItemDefinitionGroup>
在上面的示例中,“m”将设置为值“m1”作为条件引用项“i”项“是”的元数据值。
重写和删除元数据
通过将元数据值设置为另一个值,可以在后面的 ItemDefinitionGroup 元素中重写 ItemDefinitionGroup 元素中定义的元数据。 还可以通过将元数据项设置为空值来有效地删除元数据项。 例如:
<ItemDefinitionGroup>
<i>
<m>m1</m>
</i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<i>
<m></m>
</i>
</ItemDefinitionGroup>
项“i”仍包含元数据“m”,但其值现在为空。
元数据的范围
ItemDefinitionGroups 在定义的位置具有全局范围和全局属性。 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 开始,ItemGroups 也可以自引用。 例如:
<ItemGroup>
<item Include="a">
<m>m1</m>
<m>%(m);m2</m>
</item>
</ItemGroup>