累加組建

累加組建是已最佳化的組置,因此不會執行輸出檔案與其相關對應輸入檔案為最新的目標。 目標項目可能有 Inputs 屬性可指出目標預期作為輸入的項目,以及 Outputs 屬性可指出它產生作為輸出的項目。 MSBuild 嘗試尋找這些屬性值之間的 1 對 1 對應。 如果具有 1 對 1 對應,MSBuild 會比較每個輸入項目的時間戳記與其對應輸出項目的時間戳記。 沒有 1 對 1 對應的輸出檔案會與所有輸入檔案進行比較。 如果項目的輸出檔與輸入檔同齡或是前者較新,該項目則可視為最新狀態。

注意

當 MSBuild 評估輸入檔時,只會考慮目前執行中清單的內容。 上一個組建清單中的變更不會自動使目標過期。

如果所有輸出項目都是最新的,則 MSBuild 會跳過目標。 目標的這個「累加組建」可以大幅改善建置速度。 如果只有某些檔案是最新的,則 MSBuild 會執行目標,但跳過最新項目,進而讓所有項目都具有最新狀態。 此程序稱為「部分累加組建」

只有讓 Outputs 屬性成為 Inputs 屬性的轉換,才能產生 1 對 1 對應。 如需詳細資訊,請參閱轉換

請考慮下列目標。

<Target Name="Backup" Inputs="@(Compile)"
    Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">
    <Copy SourceFiles="@(Compile)" DestinationFiles=
        "@(Compile->'$(BackupFolder)%(Identity).bak')" />
</Target>

Compile 項目類型所代表的檔案集會複製至備份目錄。 備份檔案的副檔名為 .bak。 如果在執行備份目標之後未刪除或修改 Compile 項目類型所代表的檔案或對應的備份檔案,則會在後續組建中跳過備份目標。

輸出推斷

MSBuild 會比較目標的 InputsOutputs 屬性,以判斷是否必須執行目標。 在理想情況下,不論是否執行相關聯的目標,累加組建完成之後存在的檔案集應該都會維持不變。 因為工作所建立或改變的屬性和項目可能會影響組建,所以 MSBuild 必須推斷其值,即使跳過影響它們的目標也是一樣。 此程序稱為「輸出推斷」

有三種情況:

  • 目標的 Condition 屬性評估為 false。 在此情況下,不會執行目標,而且對組建沒有任何作用。

  • 目標的輸出過期,將會執行以使其具有最新狀態。

  • 目標沒有過期輸出,將會予以跳過。 MSBuild 會評估目標並變更項目和屬性,就像已執行目標一樣。

若要支援累加編譯,工作必須確保任何 Output 項目的 TaskParameter 屬性值相當於工作輸入參數。 以下列出一些範例:

<CreateProperty Value="123">
    <Output PropertyName="Easy" TaskParameter="Value" />
</CreateProperty>

不論執行還是跳過目標,此程式碼都會建立值為 "123" 的屬性 Easy。

從 MSBuild 3.5 開始,系統會自動對目標中的項目和屬性群組執行輸出推斷。 目標中不需要 CreateItem 工作,應該予以避免。 此外,只應該在目標中使用 CreateProperty 工作,以判斷是否已執行目標。

在 MSBuild 3.5 以前,您可以使用 CreateItem 工作。

判斷是否已執行目標

基於輸出推斷,您必須新增目標的 CreateProperty 工作來檢查屬性和項目,以判斷是否已執行目標。 將 CreateProperty 工作新增至目標,並為它提供其 TaskParameter 為 "ValueSetByTask" 的 Output 項目。

<CreateProperty Value="true">
    <Output TaskParameter="ValueSetByTask" PropertyName="CompileRan" />
</CreateProperty>

此程式碼會建立 CompileRan 屬性,並為其提供 true 值,唯一前提是已執行目標。 如果跳過目標,則不會建立 CompileRan。