増分ビルド

MSBuild 増分ビルドは、対応する入力ファイルに対して最新の出力ファイルを持つターゲットが実行されないように最適化されたビルドです。

ターゲット要素には、ターゲットが入力として期待する項目を示す Inputs 属性と、出力として生成される項目を示す Outputs 属性の両方を持つことができます。 MSBuild は、これらの属性の値間の 1 対 1 のマッピングを検索しようとします。 このようなマッピングが存在する場合、MSBuild は、すべての入力項目のタイム スタンプを、対応する出力項目のタイム スタンプと比較します。 1 対 1 のマッピングがない出力ファイルは、すべての入力ファイルと比較されます。 項目は、出力ファイルの有効期間が入力ファイルまたはファイルと同じか新しい場合、-date up-toと見なされます。

MSBuild が入力ファイルを評価すると、現在の実行のリストの内容のみが考慮されます。 最後のビルドからの一覧の変更では、ターゲットが自動的に古くなっていません。

すべての出力項目が -date up-to場合、MSBuild はターゲットをスキップします。 ターゲットのこの 増分ビルド により、ビルド速度が大幅に向上します。 一部のファイルのみが最新状態の場合、MSBuildはターゲットを実行しますが、最新状態の項目をスキップするため、すべての項目が最新状態になります。 このプロセスは、 部分的な増分ビルドと呼ばれます。

1 対 1 のマッピングは、 Outputs 属性を Inputs 属性の変換にすることによってのみ生成できます。 詳細については、「 MSBuild 変換」を参照してください。

次のターゲットを検討してください。

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

Compile項目の種類で表される一連のファイルがバックアップ ディレクトリにコピーされます。 バックアップ ファイルには、 .bak ファイル名拡張子が付いています。 Compile項目の種類または対応するバックアップ ファイルで表されるファイルが、Backup ターゲットの実行後に削除または変更されない場合、Backup ターゲットは後続のビルドでスキップされます。

出力推論

MSBuild は、ターゲットの Inputs 属性と Outputs 属性を比較して、ターゲットを実行する必要があるかどうかを判断します。 理想的には、インクリメンタル ビルドの完了後に存在するファイルのセットは、関連付けられているターゲットが実行されるかどうかにかかわらず、同じままである必要があります。 タスクが作成または変更するプロパティと項目はビルドに影響を与える可能性があるため、MSBuild は、それらに影響を与えるターゲットがスキップされた場合でも、その値を推論する必要があります。 このプロセスは 、出力推論と呼ばれます。

次の 3 つのケースがあります。

  • ターゲットには、Conditionに評価されるfalse属性があります。 この場合、ターゲットは実行されず、ビルドには影響しません。

  • ターゲットには更新が必要な出力があり、これを最新の状態にするために実行されます。

  • ターゲットに古い出力がないため、処理がスキップされます。 MSBuild はターゲットを評価し、ターゲットが実行されたかのように項目とプロパティに変更を加えます。

増分コンパイルをサポートするには、タスクは、TaskParameter要素のOutput属性値がタスク入力パラメーターと等しいことを確認する必要があります。 例えば次が挙げられます。

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

このコードでは、プロパティ Easyが作成されます。このプロパティには、ターゲットが実行されるかスキップされるか 123 値が含まれます。

出力推論は、ターゲット内の項目およびプロパティ グループに対して自動的に実行されます。 CreateItem タスクはターゲットでは必要ないため、避ける必要があります。 また、 CreateProperty タスクは、ターゲットが実行されたかどうかを判断するためにのみ、ターゲットで使用する必要があります。

ターゲットが実行されているかどうかを確認する

出力推論のため、ターゲットのプロパティと項目を調べて、ターゲットが実行されたかどうかを判断する必要があります。 これを行うには、CreateProperty タスクをターゲットに追加し、TaskParameterValueSetByTaskであるOutput要素を指定します。 例えば次が挙げられます。

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

このコードは、プロパティ CompileRan を作成し、ターゲットが実行された場合にのみ、 true値を指定します。 ターゲットがスキップされた場合、 CompileRan は作成されません。