Share via


項目定義

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[此處的任何項目都不會剖析]]>

注意

來自 ItemGroup 的項目中繼資料在 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" 在其 Condition 中參考了項目 "test"。 這個 Condition 永遠不會成立,因為 MSBuild 會將對 ItemDefinitionGroup 中另一個項目中繼資料的參考解譯為空字串。 因此,"m" 會設定為 "m0"。

  <ItemDefinitionGroup>
    <i>
      <m>m0</m>
      <yes>1</yes>
      <m Condition="'%(i.yes)'=='1'">m1</m>
    </i>
  </ItemDefinitionGroup>

在上述範例中,"m" 會設定為 "m1" 值,因為 Condition 針對項目 "yes" 參考了項目 "i" 的中繼資料值。

覆寫及刪除中繼資料

ItemDefinitionGroup 元素中所定義的中繼資料可被稍後的 ItemDefinitionGroup 元素覆寫,方法是將中繼資料值設定為其他值。 您也可以藉由將中繼資料項目設定為空值,來有效地刪除中繼資料項目。 例如:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
    </i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
    <i>
        <m></m>
    </i>
</ItemDefinitionGroup>

項目 "i" 仍然包含中繼資料 "m",但其值現在是空的。

中繼資料的範圍

在已定義及全域的屬性上,只要定義了 ItemDefinitionGroups,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>