Inkrementelle Builds
Inkrementelle Builds in MSBuild sind Buildvorgänge, die so optimiert werden, dass Ziele mit Ausgabedateien, die hinsichtlich der zugehörigen Eingabedateien aktuell sind, nicht ausgeführt werden.
Ein Zielelement kann sowohl über ein Inputs
-Attribut verfügen, das angibt, welche Elemente das Ziel als Eingabe erwartet, und ein Outputs
-Attribut, das angibt, welche Elemente als Ausgabe erzeugt werden. MSBuild versucht, eine 1:1-Zuordnung zwischen den Werten dieser Attribute zu finden. Wenn eine solche Zuordnung vorhanden ist, vergleicht MSBuild den Zeitstempel jedes Eingabeelements mit dem Zeitstempel des entsprechenden Ausgabeelements. Ausgabedateien ohne 1:1-Zuordnung werden mit allen Eingabedateien verglichen. Ein Element wird als up-to-datum betrachtet, wenn die Ausgabedatei dasselbe Alter oder neuer ist als die Eingabedatei oder Dateien.
Anmerkung
Wenn MSBuild die Eingabedateien auswertet, werden nur die Inhalte der Liste in der aktuellen Ausführung berücksichtigt. Änderungen in der Liste aus dem letzten Build machen kein Ziel automatisch veraltet.
Wenn alle Ausgabeelemente aktuell sind, überspringt MSBuild das Ziel. Mit diesem inkrementellen Build kann die Buildgeschwindigkeit für das Ziel entscheidend erhöht werden. Wenn nur einige Dateien up-to-date sind, führt MSBuild das Ziel aus, überspringt aber die up-to-date-Elemente und bringt daher alle Elemente up-to-date. Dieser Prozess wird als partieller inkrementeller Build bezeichnet.
1:1-Zuordnungen können nur erstellt werden, indem das Outputs
Attribut eine Transformation des attributs Inputs
wird. Weitere Informationen finden Sie unter MSBuild-Transformationen.
Betrachten Sie das folgende Ziel:
<Target Name="Backup" Inputs="@(Compile)"
Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder)%(Identity).bak')" />
</Target>
Der Satz von Dateien, die durch den Compile
Elementtyp dargestellt werden, wird in ein Sicherungsverzeichnis kopiert. Die Sicherungsdateien haben die Dateinamenerweiterung .bak
. Wenn die durch den Compile
Elementtyp oder die entsprechenden Sicherungsdateien dargestellten Dateien nach ausführung des Backup
Ziels nicht gelöscht oder geändert werden, wird das Backup
Ziel in nachfolgenden Builds übersprungen.
Ausgaberückschluss
MSBuild vergleicht die attribute Inputs
und Outputs
eines Ziels, um festzustellen, ob das Ziel ausgeführt werden muss. Im Idealfall sollte der Satz von Dateien, die vorhanden sind, nachdem ein inkrementeller Build abgeschlossen wurde, unverändert bleiben, unabhängig davon, ob die zugeordneten Ziele ausgeführt werden. Da Eigenschaften und Elemente, die Aufgaben erstellen oder ändern, auswirkungen auf den Build haben können, muss MSBuild ihre Werte ableiten, auch wenn das Ziel, das sie betrifft, übersprungen wird. Dieser Prozess wird als Ausgaberückschluss bezeichnet.
Es gibt drei Fälle:
Das Ziel weist ein
Condition
-Attribut auf, das zufalse
ausgewertet wird. In diesem Fall wird das Target nicht ausgeführt und hat keinen Einfluss auf den Build.Das Ziel weist veraltete Ausgaben auf und wird ausgeführt, um diese auf den aktuellen Stand zu bringen.
Das Ziel weist keine veralteten Ausgaben auf und wird übersprungen. MSBuild wertet das Ziel aus und nimmt Änderungen an Elementen und Eigenschaften vor, als ob das Ziel ausgeführt wurde.
Um die inkrementelle Kompilierung zu unterstützen, müssen Aufgaben sicherstellen, dass der TaskParameter
Attributwert eines beliebigen Output
Elements einem Vorgangseingabeparameter entspricht. Zum Beispiel:
<CreateProperty Value="123">
<Output PropertyName="Easy" TaskParameter="Value" />
</CreateProperty>
Mit diesem Code wird die Eigenschaft Easy
erstellt, die den Wert 123
hat, unabhängig davon, ob das Ziel ausgeführt oder übersprungen wird.
Mit MSBuild 3.5 wird die Ausgabeableitung automatisch für Element- und Eigenschaftengruppen in einem Target ausgeführt. Aufgaben vom Typ CreateItem
sind in einem Ziel nicht erforderlich und sollten vermieden werden. Darüber hinaus sollten CreateProperty
Aufgaben nur in einem Ziel verwendet werden, um zu bestimmen, ob ein Ziel ausgeführt wurde.
Vor MSBuild 3.5 können Sie die aufgabe CreateItem verwenden.
Bestimmen, ob ein Ziel ausgeführt wird
Aufgrund der Ausgabeausleitung müssen Sie die Eigenschaften und Elemente eines Ziels untersuchen, um festzustellen, ob das Ziel ausgeführt wurde. Fügen Sie dazu die CreateProperty
-Aufgabe zum Ziel hinzu und geben Sie ihm ein Output
-Element, dessen TaskParameter
ValueSetByTask
ist. Zum Beispiel:
<CreateProperty Value="true">
<Output TaskParameter="ValueSetByTask" PropertyName="CompileRan" />
</CreateProperty>
Dieser Code erstellt die Eigenschaft CompileRan
und gibt den Wert true
, aber nur, wenn das Ziel ausgeführt wird. Wenn das Ziel übersprungen wird, wird CompileRan
nicht erstellt.