累加組建Incremental builds

累加組建是已最佳化的組置,因此不會執行輸出檔案與其相關對應輸入檔案為最新的目標。Incremental builds are builds that are optimized so that targets that have output files that are up-to-date with respect to their corresponding input files are not executed. 目標項目可能有 Inputs 屬性可指出目標預期作為輸入的項目,以及 Outputs 屬性可指出它產生作為輸出的項目。A target element can have both an Inputs attribute, which indicates what items the target expects as input, and an Outputs attribute, which indicates what items it produces as output. MSBuild 嘗試尋找這些屬性值之間的 1 對 1 對應。MSBuild attempts to find a 1-to-1 mapping between the values of these attributes. 如果具有 1 對 1 對應,MSBuild 會比較每個輸入項目的時間戳記與其對應輸出項目的時間戳記。If a 1-to-1 mapping exists, MSBuild compares the time stamp of every input item to the time stamp of its corresponding output item. 沒有 1 對 1 對應的輸出檔案會與所有輸入檔案進行比較。Output files that have no 1-to-1 mapping are compared to all input files. 如果項目的輸出檔與輸入檔同齡或是前者較新,該項目則可視為最新狀態。An item is considered up-to-date if its output file is the same age or newer than its input file or files.

如果所有輸出項目都是最新的,則 MSBuild 會跳過目標。If all output items are up-to-date, MSBuild skips the target. 目標的這個「累加組建」可以大幅改善建置速度。This incremental build of the target can significantly improve the build speed. 如果只有某些檔案是最新的,則 MSBuild 會執行目標,但跳過最新項目,進而讓所有項目都具有最新狀態。If only some files are up-to-date, MSBuild executes the target but skips the up-to-date items, and thereby brings all items up-to-date. 此程序稱為「部分累加組建」。This process is known as a partial incremental build.

1 對 1 對應通常是透過項目轉換所產生。1-to-1 mappings are typically produced by item transformations. 如需詳細資訊,請參閱轉換For more information, see Transforms.

請考慮下列目標。Consider the following target.

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

Compile 項目類型所代表的檔案集會複製至備份目錄。The set of files represented by the Compile item type is copied to a backup directory. 備份檔案的副檔名為 .bakThe backup files have the .bak file name extension. 如果在執行備份目標之後未刪除或修改 Compile 項目類型所代表的檔案或對應的備份檔案,則會在後續組建中跳過備份目標。If the files represented by the Compile item type, or the corresponding backup files, are not deleted or modified after the Backup target is run, then the Backup target is skipped in subsequent builds.

輸出推斷Output inference

MSBuild 會比較目標的 InputsOutputs 屬性,以判斷是否必須執行目標。MSBuild compares the Inputs and Outputs attributes of a target to determine whether the target has to execute. 在理想情況下,不論是否執行相關聯的目標,累加組建完成之後存在的檔案集應該都會維持不變。Ideally, the set of files that exists after an incremental build is completed should remain the same whether or not the associated targets are executed. 因為工作所建立或改變的屬性和項目可能會影響組建,所以 MSBuild 必須推斷其值,即使跳過影響它們的目標也是一樣。Because properties and items that are created or altered by tasks can affect the build, MSBuild must infer their values even if the target that affects them is skipped. 此程序稱為「輸出推斷」。This process is known as output inference.

有三種情況:There are three cases:

  • 目標的 Condition 屬性評估為 falseThe target has a Condition attribute that evaluates to false. 在此情況下,不會執行目標,而且對組建沒有任何作用。In this case, the target is not run, and has no effect on the build.

  • 目標的輸出過期,將會執行以使其具有最新狀態。The target has out-of-date outputs and is run to bring them up-to-date.

  • 目標沒有過期輸出,將會予以跳過。The target has no out-of-date outputs and is skipped. MSBuild 會評估目標並變更項目和屬性,就像已執行目標一樣。MSBuild evaluates the target and makes changes to items and properties as if the target had been run.

若要支援累加編譯,工作必須確保任何 Output 項目的 TaskParameter 屬性值相當於工作輸入參數。To support incremental compilation, tasks must ensure that the TaskParameter attribute value of any Output element is equal to a task input parameter. 以下是一些範例:Here are some examples:

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

不論執行還是跳過目標,此程式碼都會建立值為 "123" 的屬性 Easy。This code creates the property Easy, which has the value "123" whether or not the target is executed or skipped.

從 MSBuild 3.5 開始,系統會自動對目標中的項目和屬性群組執行輸出推斷。Starting in MSBuild 3.5, output inference is performed automatically on item and property groups in a target. 目標中不需要 CreateItem 工作,應該予以避免。CreateItem tasks are not required in a target and should be avoided. 此外,只應該在目標中使用 CreateProperty 工作,以判斷是否已執行目標。Also, CreateProperty tasks should be used in a target only to determine whether a target has been executed.

在 MSBuild 3.5 以前,您可以使用 CreateItem 工作。Prior to MSBuild 3.5, you can use the CreateItem task.

判斷是否已執行目標Determine whether a target has been run

基於輸出推斷,您必須新增目標的 CreateProperty 工作來檢查屬性和項目,以判斷是否已執行目標。Because of output inference, you have to add a CreateProperty task to a target to examine properties and items so that you can determine whether the target has been executed. CreateProperty 工作新增至目標,並為它提供其 TaskParameter 為 "ValueSetByTask" 的 Output 項目。Add the CreateProperty task to the target and give it an Output element whose TaskParameter is "ValueSetByTask".

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

此程式碼會建立 CompileRan 屬性,並為其提供 true 值,唯一前提是已執行目標。This code creates the property CompileRan and gives it the value true, but only if the target is executed. 如果跳過目標,則不會建立 CompileRan。If the target is skipped, CompileRan is not created.

另請參閱See also