项定义

更新:2007 年 11 月

MSBuild 2.0 允许使用 ItemGroup 元素 (MSBuild)PropertyGroup 元素 (MSBuild) 在项目文件中对项进行静态声明。但是,只能在项级别添加元数据,即使所有项的元数据都相同也是如此。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 批处理