分享方式:


目標組建順序

如果某一個目標的輸入相依於另一個目標的輸出,則必須排序目標。 您可以使用這些屬性來指定執行目標的順序:

  • InitialTargets. 這個 Project 屬性會指定優先執行的目標,即使已在命令列上或 DefaultTargets 屬性中指定目標也一樣。

  • DefaultTargets. 如果未在命令列上明確指定目標,則這個 Project 屬性會指定要執行哪些目標。

  • DependsOnTargets. 這個 Target 屬性會指定必須在此目標執行之前執行的目標。

  • BeforeTargetsAfterTargets。 這些 Target 屬性會指定此目標應該在指定的目標之前或之後執行。

一般而言,您不應該依賴宣告順序來指定在其他工作之前執行的工作。

目標絕對不會在建置期間執行兩次,即使組建中的後續目標相依於它也一樣。 一旦執行目標之後,它對組建而言就已功成身退了。

目標可以有 Condition 屬性。 如果指定的條件評估為 false,則不會執行目標,且不會對組建產生任何作用。 如需條件的詳細資訊,請參閱條件

初始目標

Project 項目的 InitialTargets 屬性會指定優先執行的目標,即使已在命令列上或 DefaultTargets 屬性中指定目標也一樣。 初始目標通常用於錯誤檢查。

InitialTargets 屬性的值可以是以分號分隔且已排序的目標清單。 下列範例會指定 Warm 目標執行,然後 Eject 目標執行。

<Project InitialTargets="Warm;Eject" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

匯入的專案可能會有自己的 InitialTargets 屬性。 所有的初始目標都會彙總在一起,並依序執行。

如需詳細資訊,請參閱如何:指定要優先建置的目標

預設目標

如果未在命令列上明確指定目標,則 Project 項目的 DefaultTargets 屬性會指定要建置哪些目標。

DefaultTargets 屬性的值可以是以分號分隔且已排序的預設目標清單。 下列範例會指定 Clean 目標執行,然後 Build 目標執行。

<Project DefaultTargets="Clean;Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

您可以在命令列上使用 -target 參數覆寫預設目標。 下列範例會指定 Build 目標執行,然後 Report 目標執行。 當您以這種方式指定目標時,就會忽略任何預設目標。

msbuild -target:Build;Report

如果未指定初始目標和預設目標,以及如果未指定任何命令列目標,MSBuild 就會先執行初始目標,接著執行預設目標。

匯入的專案可能會有自己的 DefaultTargets 屬性。 第一個遇到的 DefaultTargets 屬性會判斷將執行哪些預設目標。

如需詳細資訊,請參閱如何:指定要優先建置的目標

第一個目標

如果沒有初始目標、預設目標或命令列目標,則 MSBuild 會執行它在專案檔或任何匯入的專案檔中遇到的第一個目標。

目標相依性

目標可以說明彼此間的相依性關係。 DependsOnTargets 屬性會指出某一個目標相依於其他目標。 例如,

<Target Name="Serve" DependsOnTargets="Chop;Cook" />

告知 MSBuild,Serve 目標相依於 Chop 目標和 Cook 目標。 MSBuild 會執行 Chop 目標,然後在執行 Serve 目標之前先執行 Cook 目標。

注意

SDK 中的標準目標會定義一些 DependsOn 屬性,其中包含該目標相依性的目標清單(例如 $(BuildDependsOn)$(CleanDependsOn) 等等)。 例如,

<Target Name="Build" DependsOnTargets="$(BuildDependsOn)">

若要自訂專案,您可以使用擴充組建流程圖的其他自定義目標來覆寫DependsOn屬性,如 [擴充Visual Studio組建流程圖中所述]

BeforeTargets 和 AfterTargets

您可以使用 BeforeTargetsAfterTargets 屬性來指定目標順序。

請考慮下列指令碼。

<Project DefaultTargets="Compile;Link" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Compile">
        <Message Text="Compiling" />
    </Target>
    <Target Name="Link">
        <Message Text="Linking" />
    </Target>
</Project>

若要建立中繼目標 Optimize,在 Compile 目標之後,但在 Link 目標之前執行,請 在 Project 項目中的任一處加入下列目標。

<Target Name="Optimize" AfterTargets="Compile">
    <Message Text="Optimizing" />
</Target>

或者,將順序指定為

<Target Name="Optimize" BeforeTargets="Link">
    <Message Text="Optimizing" />
</Target>

在相同的目標上同時指定BeforeTargetsAfterTargets 是沒有用的。 如下一節所述,只有遇到的第一個目標會導致新目標執行。

判斷目標建置順序

MSBuild 會以如下方式判斷目標建置順序:

  1. 執行 InitialTargets 目標。

  2. 執行命令列上使用 -target 參數指定的目標。 如果您未在命令列上指定目標,則會執行 DefaultTargets 目標。 如果兩者都不存在,則會執行第一個遇到的目標。

  3. 評估目標的 Condition 屬性。 如果 Condition 屬性存在且評估為 false,則不會執行目標,且不會對組建產生任何進一步的作用。

    其他列出 BeforeTargetsAfterTargets 中條件式目標的目標,仍會根據指定的順序執行。

  4. 在執行或跳過目標前,其 DependsOnTargets 目標仍會執行,除非 Condition 屬性已套用到目標,並評估為 false

    注意

    若沒有執行,則會將目標視為跳過,因為其輸出項目已是最新狀態 (請參閱累加建置)。 這項檢查會在於目標內部執行工作前完成,且不會影響目標的執行順序。

  5. 在執行或跳過目標前,任何在 BeforeTargets 屬性中列出目標的其他目標都會執行。

  6. 在執行目標前,會先比較它的 Inputs 屬性和 Outputs 屬性。 如果 MSBuild 判斷有任何與一或多個對應輸入檔相關的輸出檔過時,則 MSBuild 會執行目標。 否則,MSBuild 會略過目標。

  7. 在執行或跳過目標後,任何在 AfterTargets 屬性中列出它的其他目標都會執行。