Partager via


Builds incrémentielles

Les builds MSBuild incrémentielles sont des builds optimisées qui permettent de ne pas exécuter les cibles dont les fichiers de sortie sont à jour par rapport à leurs fichiers d’entrée correspondants.

Un élément cible peut avoir à la fois un attribut Inputs, qui indique les éléments attendus comme entrée et un attribut Outputs, qui indique les éléments qu’il produit en tant que sortie. MSBuild tente de trouver un mappage un-à-un entre les valeurs de ces attributs. Si un tel mappage existe, MSBuild compare l’horodatage de chaque élément d’entrée à l’horodatage de son élément de sortie correspondant. Les fichiers de sortie qui n’ont pas de mappage un-à-un sont comparés à tous les fichiers d’entrée. Un élément est considéré comme up-to-date si son fichier de sortie est le même âge ou plus récent que son fichier d’entrée ou ses fichiers.

Remarque

Lorsque MSBuild évalue les fichiers d’entrée, seul le contenu de la liste dans l’exécution actuelle est pris en compte. Les modifications apportées à la liste à partir de la dernière compilation ne rendent pas automatiquement une cible obsolète.

Si tous les éléments de sortie sont up-to-date, MSBuild ignore la cible. Cette build incrémentielle de la cible peut améliorer considérablement la vitesse de génération. Si seuls certains fichiers sont up-to-date, MSBuild exécute la cible, mais ignore les éléments up-to-date et apporte donc tous les éléments up-to-date. Ce processus est appelé « build incrémentielle partielle ».

Les mappages un-à-un peuvent être générés uniquement en rendant l’attribut Outputs une transformation de l’attribut Inputs. Pour plus d’informations, consultez Transformations MSBuild.

Tenez compte de la cible suivante :

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

L’ensemble de fichiers représentés par le type d’élément Compile est copié dans un répertoire de sauvegarde. Les fichiers de sauvegarde ont l’extension de nom de fichier .bak. Si les fichiers représentés par le type d’élément Compile ou les fichiers de sauvegarde correspondants ne sont pas supprimés ou modifiés après l’exécution de la cible Backup, la cible Backup est ignorée dans les builds suivantes.

Inférence de sortie

MSBuild compare les attributs Inputs et Outputs d’une cible pour déterminer si la cible doit s’exécuter. Dans l’idéal, l’ensemble de fichiers qui existe après la fin d’une build incrémentielle doit rester identique si les cibles associées sont exécutées ou non. Étant donné que les propriétés et les éléments que les tâches créent ou modifient peuvent affecter la compilation, MSBuild doit déduire leurs valeurs même si la cible associée est ignorée. Ce processus est appelé « inférence de sortie ».

Il existe trois cas :

  • La cible a un attribut Condition dont la valeur est false. Dans ce cas, la cible n’est pas exécutée et n’a aucun effet sur la build.

  • La cible comprend des sorties obsolètes, et est donc exécutée pour les mettre à jour.

  • La cible ne comprend aucune sortie obsolète, et est donc ignorée. MSBuild évalue la cible et apporte des modifications aux éléments et aux propriétés comme si la cible a été exécutée.

Pour prendre en charge la compilation incrémentielle, les tâches doivent s’assurer que la valeur d’attribut TaskParameter de n’importe quel élément Output est égale à un paramètre d’entrée de tâche. Par exemple:

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

Ce code crée la propriété Easy, qui a la valeur 123 si la cible est exécutée ou ignorée.

À compter de MSBuild 3.5, l’inférence de sortie est effectuée automatiquement sur les groupes d’éléments et de propriétés d’une cible. Les tâches CreateItem ne sont pas requises pour un objectif et doivent être évitées. En outre, les tâches CreateProperty ne doivent être utilisées dans une cible que pour déterminer si une cible a été exécutée.

Avant MSBuild 3.5, vous pouvez utiliser la tâche CreateItem.

Déterminer si une cible est exécutée

En raison de l’inférence de sortie, vous devez examiner les propriétés et les éléments d’une cible pour déterminer si la cible a été exécutée. Pour ce faire, ajoutez la tâche CreateProperty à la cible et donnez-lui un élément Output dont TaskParameter est ValueSetByTask. Par exemple:

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

Ce code crée la propriété CompileRan et lui donne la valeur true, mais uniquement si la cible est exécutée. Si la cible est ignorée, CompileRan n’est pas créée.