项定义

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>